@remotex-labs/xbuild 2.1.6 → 2.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/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * DO NOT EDIT MANUALLY.
4
4
  */
5
5
 
6
- import ts, { CompilerOptions, DiagnosticCategory, IScriptSnapshot, LanguageService, ParsedCommandLine, ResolvedModuleWithFailedLookupLocations } from 'typescript';
6
+ import ts, { CompilerOptions, DiagnosticCategory, IScriptSnapshot, LanguageService, ParsedCommandLine, ResolvedModuleWithFailedLookupLocations, SourceFile } from 'typescript';
7
7
  import { BuildOptions, BuildResult, Loader, Message, OnEndResult, OnLoadArgs, OnLoadResult, OnResolveArgs, OnResolveResult, OnStartResult, PartialMessage, Platform, PluginBuild } from 'esbuild';
8
8
  import { IncomingMessage, ServerResponse } from 'http';
9
9
  import { PositionInterface, SourceService } from '@remotex-labs/xmap';
@@ -2197,6 +2197,17 @@ interface LifecycleContextInterface {
2197
2197
  * @since 2.0.0
2198
2198
  */
2199
2199
  variantName: string;
2200
+ /**
2201
+ * esbuild configuration options used for this lifecycle execution.
2202
+ *
2203
+ * @remarks
2204
+ * These options represent the active build configuration for the provider and
2205
+ * are intended to be read by lifecycle handlers when build behavior depends on
2206
+ * entry points, output settings, plugins, or other esbuild flags.
2207
+ *
2208
+ * @since 2.2.0
2209
+ */
2210
+ options: BuildOptions;
2200
2211
  }
2201
2212
  /**
2202
2213
  * Context interface for `onStart` hooks, providing access to the esbuild plugin build object.
@@ -2733,6 +2744,7 @@ type OnLoadType = (context: LoadContextInterface) => MaybeUndefinedPromiseType<O
2733
2744
  *
2734
2745
  * The normalized errors may include:
2735
2746
  * - {@link TypesError} for TypeScript type checking failures
2747
+ * - {@link xBuildError} for text errors during build hooks
2736
2748
  * - {@link esBuildError} for esbuild compilation errors with location information
2737
2749
  * - {@link VMRuntimeError} for runtime errors during build hooks
2738
2750
  * - {@link xBuildBaseError} for custom build system errors
@@ -2745,7 +2757,7 @@ type OnLoadType = (context: LoadContextInterface) => MaybeUndefinedPromiseType<O
2745
2757
  * new TypesError('Type checking failed', diagnostics)
2746
2758
  * ],
2747
2759
  * warnings: [
2748
- * new VMRuntimeError(new Error('Deprecation warning'))
2760
+ * new xBuildError('Deprecation warning')
2749
2761
  * ],
2750
2762
  * metafile: { ... },
2751
2763
  * outputFiles: [ ... ],
@@ -4473,10 +4485,14 @@ declare function parseGlobs(globs: Array<string>): ParseGlobInterface;
4473
4485
  *
4474
4486
  * @remarks
4475
4487
  * Uses early exit optimization - stops checking as soon as a match is found.
4488
+ * A pattern is treated as a match when either:
4489
+ * - The pattern string ends with the provided path
4490
+ * - `matchesGlob(p, pattern)` returns true
4476
4491
  *
4477
4492
  * @example
4478
4493
  * ```ts
4479
4494
  * matchesAny('src/app.ts', ['**\/*.ts', '**\/*.js']); // true
4495
+ * matchesAny('src/app.ts', ['prefix/src/app.ts']); // true (suffix check)
4480
4496
  * matchesAny('README.md', ['**\/*.ts', '**\/*.js']); // false
4481
4497
  * ```
4482
4498
  *
@@ -4596,6 +4612,696 @@ interface ParseGlobInterface {
4596
4612
  */
4597
4613
  exclude: Array<string>;
4598
4614
  }
4615
+ /**
4616
+ * Type alias for build-time definition values used in conditional compilation.
4617
+ *
4618
+ * @remarks
4619
+ * This type represents the structure of the `define` configuration object that controls
4620
+ * conditional macro behavior. Each key is a definition name referenced by `$$ifdef` or
4621
+ * `$$ifndef` macros, and the value determines whether the macro is included or excluded.
4622
+ *
4623
+ * **Value interpretation**:
4624
+ * - Truthy values (`true`, non-zero numbers, non-empty strings): Definition is considered "defined"
4625
+ * - Falsy values (`false`, `0`, `''`, `null`, `undefined`): Definition is considered "not defined"
4626
+ *
4627
+ * The values can be any type, but are typically booleans for clarity. JavaScript's truthiness
4628
+ * rules are applied when evaluating macro conditions.
4629
+ *
4630
+ * @example Basic boolean definitions
4631
+ * ```ts
4632
+ * const defines: DefinesType = {
4633
+ * DEBUG: true,
4634
+ * PRODUCTION: false,
4635
+ * TEST: false
4636
+ * };
4637
+ * ```
4638
+ *
4639
+ * @example Mixed value types
4640
+ * ```ts
4641
+ * const defines: DefinesType = {
4642
+ * DEBUG: true,
4643
+ * LOG_LEVEL: 'info', // Truthy (non-empty string)
4644
+ * MAX_RETRIES: 3, // Truthy (non-zero number)
4645
+ * EXPERIMENTAL: 0, // Falsy
4646
+ * FEATURE_FLAG: undefined // Falsy
4647
+ * };
4648
+ * ```
4649
+ *
4650
+ * @example Usage in configuration
4651
+ * ```ts
4652
+ * const config = {
4653
+ * define: {
4654
+ * DEBUG: process.env.NODE_ENV !== 'production',
4655
+ * API_URL: process.env.API_URL || 'http://localhost:3000'
4656
+ * }
4657
+ * };
4658
+ * ```
4659
+ *
4660
+ * @see {@link StateInterface.defines} for usage context
4661
+ * @see {@link isDefinitionMet} for condition evaluation logic
4662
+ *
4663
+ * @since 2.0.0
4664
+ */
4665
+ type DefinesType = Record<string, unknown>;
4666
+ /**
4667
+ * Build execution context available to macro transformation logic.
4668
+ *
4669
+ * @remarks
4670
+ * Groups runtime build metadata and configuration needed by macros during AST processing:
4671
+ * - `variantName`: active build variant identifier
4672
+ * - `argv`: provider command-line/config arguments
4673
+ * - `options`: effective esbuild `BuildOptions` for the current build
4674
+ *
4675
+ * This object is read by macro handlers to make variant-aware and build-aware decisions.
4676
+ *
4677
+ * @since 2.2.0
4678
+ */
4679
+ interface MacroContextInterface {
4680
+ /**
4681
+ * The current build variant name.
4682
+ *
4683
+ * @remarks
4684
+ * Identifies which variant is being transformed (for example, `development`
4685
+ * or `production`). This value is propagated through macro processing so
4686
+ * diagnostics and generated output can be associated with the correct variant.
4687
+ *
4688
+ * @example
4689
+ * ```ts
4690
+ * $$inline(() => {
4691
+ * console.log(variantName);
4692
+ * });
4693
+ * ```
4694
+ *
4695
+ * @since 2.2.0
4696
+ */
4697
+ variantName: string;
4698
+ /**
4699
+ * Command-line arguments and configuration options passed to the provider.
4700
+ *
4701
+ * @remarks
4702
+ * Contains all CLI options and flags passed when the provider was created.
4703
+ * Available to all handlers for accessing build-specific configuration like
4704
+ * debug flags, output paths, or custom settings.
4705
+ *
4706
+ * @example
4707
+ * ```ts
4708
+ * context.argv; // { debug: true, verbose: false, outdir: 'dist' }
4709
+ * ```
4710
+ *
4711
+ * @since 2.2.0
4712
+ */
4713
+ argv: Record<string, unknown>;
4714
+ /**
4715
+ * esbuild configuration options used for this lifecycle execution.
4716
+ *
4717
+ * @remarks
4718
+ * These options represent the active build configuration for the provider and
4719
+ * are intended to be read by lifecycle handlers when build behavior depends on
4720
+ * entry points, output settings, plugins, or other esbuild flags.
4721
+ *
4722
+ * @since 2.2.0
4723
+ */
4724
+ options: BuildOptions;
4725
+ }
4726
+ /**
4727
+ * Represents the complete state during macro transformation of a source file.
4728
+ *
4729
+ * @remarks
4730
+ * This interface encapsulates all data needed during AST traversal and macro transformation.
4731
+ * It provides:
4732
+ * - **Metadata access**: Build stage information including disabled macro names
4733
+ * - **Configuration**: Build-time definitions controlling conditional compilation
4734
+ * - **Source information**: TypeScript AST and original file content
4735
+ * - **Diagnostic collection**: Arrays for warnings and errors during transformation
4736
+ *
4737
+ * The state is passed through the entire transformation pipeline, allowing functions
4738
+ * to access configuration, collect diagnostics, and track the transformation process.
4739
+ *
4740
+ * **State lifecycle**:
4741
+ * 1. Created in {@link transformerDirective} with initial configuration
4742
+ * 2. Passed to {@link astProcess} for transformation
4743
+ * 3. Passed to individual node processors ({@link isVariableStatement}, {@link isCallExpression})
4744
+ * 4. Passed to macro transformers ({@link astInlineVariable}, {@link astDefineVariable})
4745
+ * 5. Diagnostics extracted and returned in the final result
4746
+ *
4747
+ * @example State initialization
4748
+ * ```ts
4749
+ * const state: StateInterface = {
4750
+ * stage: stage as MacrosStaeInterface,
4751
+ * defines: { DEBUG: true, PRODUCTION: false },
4752
+ * sourceFile: languageService.getProgram()?.getSourceFile(path)!,
4753
+ * contents: fileContents,
4754
+ * errors: [],
4755
+ * warnings: []
4756
+ * };
4757
+ * ```
4758
+ *
4759
+ * @example Collecting diagnostics during transformation
4760
+ * ```ts
4761
+ * function processNode(node: Node, state: StateInterface): void {
4762
+ * if (isInvalidMacro(node)) {
4763
+ * state.warnings.push({
4764
+ * text: 'Invalid macro usage',
4765
+ * location: getLocation(node, state.sourceFile)
4766
+ * });
4767
+ * }
4768
+ * }
4769
+ * ```
4770
+ *
4771
+ * @example Accessing definitions
4772
+ * ```ts
4773
+ * function shouldIncludeMacro(name: string, state: StateInterface): boolean {
4774
+ * const value = state.defines[name];
4775
+ * return name in state.defines && !!value;
4776
+ * }
4777
+ * ```
4778
+ *
4779
+ * @see {@link transformerDirective} for state creation
4780
+ * @see {@link astProcess} for state usage during transformation
4781
+ * @see {@link MacrosStateInterface} for stage metadata structure
4782
+ *
4783
+ * @since 2.0.0
4784
+ */
4785
+ interface StateInterface {
4786
+ /**
4787
+ * The build stage containing macro analysis metadata.
4788
+ *
4789
+ * @remarks
4790
+ * Provides access to metadata collected during the analysis phase, including:
4791
+ * - Set of files containing macros
4792
+ * - Set of disabled macro names (based on definitions)
4793
+ *
4794
+ * This metadata is used to optimize transformation by skipping files without
4795
+ * macros and replacing disabled macro references with `undefined`.
4796
+ *
4797
+ * @see {@link MacrosStateInterface} for metadata structure
4798
+ * @see {@link analyzeMacroMetadata} for metadata generation
4799
+ *
4800
+ * @since 2.0.0
4801
+ */
4802
+ stage: MacrosStateInterface;
4803
+ /**
4804
+ * Array of error messages collected during transformation.
4805
+ *
4806
+ * @remarks
4807
+ * Contains partial esbuild messages representing errors that occurred during
4808
+ * macro processing. Common error sources include:
4809
+ * - Invalid macro syntax
4810
+ * - Runtime errors during inline code evaluation
4811
+ * - TypeScript compilation errors
4812
+ *
4813
+ * Errors are non-fatal during transformation but are reported in the final result
4814
+ * and may cause the build to fail.
4815
+ *
4816
+ * @example Adding an error
4817
+ * ```ts
4818
+ * state.errors.push({
4819
+ * text: 'Cannot evaluate inline macro',
4820
+ * location: { file: filePath, line: 42, column: 10 }
4821
+ * });
4822
+ * ```
4823
+ *
4824
+ * @since 2.0.0
4825
+ */
4826
+ errors: Array<PartialMessage>;
4827
+ /**
4828
+ * Build-time definitions controlling conditional macro inclusion.
4829
+ *
4830
+ * @remarks
4831
+ * A record mapping definition names to their values. Used by `$$ifdef` and `$$ifndef`
4832
+ * macros to determine whether code should be included in the build output.
4833
+ *
4834
+ * Typically sourced from `variant.config.define` in the build configuration.
4835
+ *
4836
+ * @example
4837
+ * ```ts
4838
+ * const state: StateInterface = {
4839
+ * defines: {
4840
+ * DEBUG: true,
4841
+ * PRODUCTION: false,
4842
+ * API_URL: 'https://api.example.com'
4843
+ * },
4844
+ * // ... other properties
4845
+ * };
4846
+ * ```
4847
+ *
4848
+ * @see {@link DefinesType} for type structure
4849
+ * @see {@link isDefinitionMet} for evaluation logic
4850
+ *
4851
+ * @since 2.0.0
4852
+ */
4853
+ defines: DefinesType;
4854
+ /**
4855
+ * Array of warning messages collected during transformation.
4856
+ *
4857
+ * @remarks
4858
+ * Contains partial esbuild messages representing non-fatal issues discovered
4859
+ * during macro processing. Common warning sources include:
4860
+ * - Macro names missing the `$$` prefix convention
4861
+ * - References to undefined functions in inline macros
4862
+ * - Deprecated macro patterns
4863
+ *
4864
+ * Warnings do not prevent successful transformation but indicate potential issues.
4865
+ *
4866
+ * @example Adding a warning
4867
+ * ```ts
4868
+ * state.warnings.push({
4869
+ * text: `Function ${functionName} not found`,
4870
+ * location: { file: filePath, line: 10, column: 5 }
4871
+ * });
4872
+ * ```
4873
+ *
4874
+ * @since 2.0.0
4875
+ */
4876
+ warnings: Array<PartialMessage>;
4877
+ /**
4878
+ * The current file content being transformed.
4879
+ *
4880
+ * @remarks
4881
+ * Contains the complete source file text. During transformation, this content
4882
+ * is modified by applying replacement operations. The final transformed content
4883
+ * is returned in the build result.
4884
+ *
4885
+ * Updated during the transformation process as macros are replaced with their
4886
+ * expanded or evaluated forms.
4887
+ *
4888
+ * @since 2.0.0
4889
+ */
4890
+ contents: string;
4891
+ /**
4892
+ * The TypeScript source file AST.
4893
+ *
4894
+ * @remarks
4895
+ * Provides the parsed Abstract Syntax Tree of the source file, used for:
4896
+ * - AST traversal to locate macro calls
4897
+ * - Text extraction from AST nodes
4898
+ * - Position calculation for diagnostics
4899
+ * - Source location mapping
4900
+ *
4901
+ * Obtained from TypeScript's language service and represents the current
4902
+ * state of the file in the compilation.
4903
+ *
4904
+ * @since 2.0.0
4905
+ */
4906
+ sourceFile: SourceFile;
4907
+ /**
4908
+ * Build execution context available to macro transformation logic.
4909
+ *
4910
+ * @remarks
4911
+ * Groups runtime build metadata and configuration needed by macros during AST processing:
4912
+ * - `variantName`: active build variant identifier
4913
+ * - `argv`: provider command-line/config arguments
4914
+ * - `options`: effective esbuild `BuildOptions` for the current build
4915
+ *
4916
+ * This object is read by macro handlers to make variant-aware and build-aware decisions.
4917
+ *
4918
+ * @since 2.2.0
4919
+ */
4920
+ context: MacroContextInterface;
4921
+ }
4922
+ /**
4923
+ * Represents a text substitution operation for macro replacement.
4924
+ *
4925
+ * @remarks
4926
+ * This interface defines a single replacement operation to be performed on source code
4927
+ * during macro transformation. Each substitution specifies:
4928
+ * - The region of text to replace (via start and end positions)
4929
+ * - The replacement text to insert
4930
+ *
4931
+ * Substitutions are collected during AST traversal and applied in reverse order
4932
+ * (from end to start) to avoid position invalidation as earlier replacements
4933
+ * are applied.
4934
+ *
4935
+ * **Position handling**:
4936
+ * - Positions are character offsets from the start of the file (0-based)
4937
+ * - `start` is inclusive (first character to replace)
4938
+ * - `end` is exclusive (one past the last character to replace)
4939
+ * - Region length: `end - start`
4940
+ *
4941
+ * **Application strategy**:
4942
+ * Replacements are sorted by `start` position in descending order before application,
4943
+ * ensuring that later positions are replaced first, preventing earlier replacements
4944
+ * from shifting positions of subsequent replacements.
4945
+ *
4946
+ * @example Basic substitution
4947
+ * ```ts
4948
+ * const subst: SubstInterface = {
4949
+ * start: 50, // Start of the macro call
4950
+ * end: 85, // End of macro call
4951
+ * replacement: 'function $$debug() { return console.log; }'
4952
+ * };
4953
+ * ```
4954
+ *
4955
+ * @example Replacing a macro with undefined
4956
+ * ```ts
4957
+ * // Replace disabled macro reference
4958
+ * const subst: SubstInterface = {
4959
+ * start: 120,
4960
+ * end: 127, // Length of '$$debug'
4961
+ * replacement: 'undefined'
4962
+ * };
4963
+ * ```
4964
+ *
4965
+ * @example Multiple substitutions
4966
+ * ```ts
4967
+ * const replacements: SubstInterface[] = [
4968
+ * { start: 100, end: 150, replacement: 'transformed1' },
4969
+ * { start: 50, end: 80, replacement: 'transformed2' }
4970
+ * ];
4971
+ *
4972
+ * // Sort by start position (descending)
4973
+ * replacements.sort((a, b) => b.start - a.start);
4974
+ *
4975
+ * // Apply in reverse order
4976
+ * for (const subst of replacements) {
4977
+ * content = content.slice(0, subst.start) +
4978
+ * subst.replacement +
4979
+ * content.slice(subst.end);
4980
+ * }
4981
+ * ```
4982
+ *
4983
+ * @see {@link isVariableStatement} for substitution creation
4984
+ * @see {@link astProcess} for substitution collection and application
4985
+ *
4986
+ * @since 2.0.0
4987
+ */
4988
+ interface SubstInterface {
4989
+ /**
4990
+ * The exclusive end position of the text region to replace.
4991
+ *
4992
+ * @remarks
4993
+ * Character offset representing one position past the last character to replace.
4994
+ * The character at this position is not included in the replacement.
4995
+ *
4996
+ * Obtained from `node.getEnd()` on the AST node being replaced.
4997
+ *
4998
+ * @since 2.0.0
4999
+ */
5000
+ end: number;
5001
+ /**
5002
+ * The inclusive start position of the text region to replace.
5003
+ *
5004
+ * @remarks
5005
+ * Character offset representing the first character to replace in the source text.
5006
+ * The character at this position is included in the replacement.
5007
+ *
5008
+ * Obtained from `node.getStart(sourceFile)` on the AST node being replaced.
5009
+ *
5010
+ * @since 2.0.0
5011
+ */
5012
+ start: number;
5013
+ /**
5014
+ * The replacement text to insert at the specified position.
5015
+ *
5016
+ * @remarks
5017
+ * The complete text that will replace the region defined by `start` and `end`.
5018
+ * Can be:
5019
+ * - Transformed macro code (function declarations, constants)
5020
+ * - Evaluated inline results
5021
+ * - The string `'undefined'` for disabled macros
5022
+ * - Empty string for removed macros
5023
+ *
5024
+ * @example
5025
+ * ```ts
5026
+ * replacement: 'function $$debug() { return console.log; }'
5027
+ * replacement: 'undefined'
5028
+ * replacement: 'export const API_URL = "https://api.example.com";'
5029
+ * replacement: ''
5030
+ * ```
5031
+ *
5032
+ * @since 2.0.0
5033
+ */
5034
+ replacement: string;
5035
+ }
5036
+ /**
5037
+ * Metadata collected during macro analysis for a build variant.
5038
+ *
5039
+ * @remarks
5040
+ * This interface stores essential information about macro usage across the project,
5041
+ * used during the transformation phase to:
5042
+ * - Determine which files need macro processing
5043
+ * - Identify which macro functions should be removed
5044
+ * - Optimize build performance by skipping files without macros
5045
+ *
5046
+ * Both sets use absolute file paths for accurate file identification.
5047
+ *
5048
+ * @example Metadata after analyzing a project
5049
+ * ```ts
5050
+ * const metadata: MacrosMetadataInterface = {
5051
+ * filesWithMacros: new Set([
5052
+ * '/project/src/index.ts',
5053
+ * '/project/src/config.ts',
5054
+ * '/project/src/features/analytics.ts'
5055
+ * ]),
5056
+ * disabledMacroNames: new Set([
5057
+ * '$$noProd', // from $$ifndef('PRODUCTION') when PRODUCTION=true
5058
+ * '$$devOnly', // from $$ifdef('DEVELOPMENT') when DEVELOPMENT=false
5059
+ * '$$testMode' // from $$ifdef('TEST') when TEST=false
5060
+ * ])
5061
+ * };
5062
+ * ```
5063
+ *
5064
+ * @example Using metadata for optimization
5065
+ * ```ts
5066
+ * function shouldProcessFile(filePath: string, metadata: MacrosMetadataInterface): boolean {
5067
+ * // Skip files that don't contain any macros
5068
+ * return metadata.filesWithMacros.has(filePath);
5069
+ * }
5070
+ *
5071
+ * function shouldRemoveMacro(macroName: string, metadata: MacrosMetadataInterface): boolean {
5072
+ * // Check if macro should be stripped from output
5073
+ * return metadata.disabledMacroNames.has(macroName);
5074
+ * }
5075
+ * ```
5076
+ *
5077
+ * @example Building metadata incrementally
5078
+ * ```ts
5079
+ * const metadata: MacrosMetadataInterface = {
5080
+ * filesWithMacros: new Set(),
5081
+ * disabledMacroNames: new Set()
5082
+ * };
5083
+ *
5084
+ * // During analysis
5085
+ * if (fileContainsMacros(file)) {
5086
+ * metadata.filesWithMacros.add(file);
5087
+ * }
5088
+ *
5089
+ * // When a macro is disabled by definitions
5090
+ * if (shouldDisableMacro(macro, defines)) {
5091
+ * metadata.disabledMacroNames.add(macro);
5092
+ * }
5093
+ * ```
5094
+ *
5095
+ * @see {@link analyzeMacroMetadata} for the function that generates this metadata
5096
+ * @see {@link MacrosStateInterface} for the stage interface that contains this metadata
5097
+ *
5098
+ * @since 2.0.0
5099
+ */
5100
+ interface MacrosMetadataInterface {
5101
+ /**
5102
+ * Set of absolute file paths that contain macro expressions.
5103
+ *
5104
+ * @remarks
5105
+ * Files in this set require macro transformation during the build process.
5106
+ * Files not in this set can skip macro processing entirely, improving build performance.
5107
+ *
5108
+ * Includes files with any of:
5109
+ * - `$$ifdef` expressions
5110
+ * - `$$ifndef` expressions
5111
+ * - Macro variable declarations
5112
+ * - Inline macro calls
5113
+ *
5114
+ * @example
5115
+ * ```ts
5116
+ * filesWithMacros: new Set([
5117
+ * '/project/src/config.ts', // Has: const $$debug = $$ifdef('DEBUG', ...)
5118
+ * '/project/src/features.ts', // Has: $$ifdef('ANALYTICS', ...)
5119
+ * '/project/src/utils/logger.ts' // Has: export const $$log = $$ifndef('PROD', ...)
5120
+ * ])
5121
+ * ```
5122
+ *
5123
+ * @since 2.0.0
5124
+ */
5125
+ filesWithMacros: Set<string>;
5126
+ /**
5127
+ * Set of macro function names that should be removed from the output.
5128
+ *
5129
+ * @remarks
5130
+ * Contains macro names that evaluated to false based on the current build definitions.
5131
+ * These macros and their calls will be replaced with `undefined` during transformation.
5132
+ *
5133
+ * A macro is disabled when:
5134
+ * - `$$ifdef('X', ...)` and X is false or undefined
5135
+ * - `$$ifndef('X', ...)` and X is true
5136
+ *
5137
+ * @example
5138
+ * ```ts
5139
+ * // With definitions: { DEBUG: false, PRODUCTION: true, TEST: false }
5140
+ * disabledMacroNames: new Set([
5141
+ * '$$hasDebug', // from $$ifdef('DEBUG', ...) - DEBUG is false
5142
+ * '$$noProd', // from $$ifndef('PRODUCTION', ...) - PRODUCTION is true
5143
+ * '$$testMode' // from $$ifdef('TEST', ...) - TEST is false
5144
+ * ])
5145
+ * ```
5146
+ *
5147
+ * @since 2.0.0
5148
+ */
5149
+ disabledMacroNames: Set<string>;
5150
+ }
5151
+ /**
5152
+ * Describes a single text replacement produced by macro analysis/transformation.
5153
+ *
5154
+ * @remarks
5155
+ * This is a small helper contract used to capture:
5156
+ * - the original source fragment ({@link MacroReplacementInterface.source}), and
5157
+ * - the text that should replace it ({@link MacroReplacementInterface.replacement}).
5158
+ *
5159
+ * It is useful for debugging, reporting, and applying deterministic transformations.
5160
+ *
5161
+ * @example Recording a replacement
5162
+ * ```ts
5163
+ * const r: MacroReplacementInterface = {
5164
+ * source: "$$ifdef('DEBUG', () => log())",
5165
+ * replacement: "undefined"
5166
+ * };
5167
+ * ```
5168
+ *
5169
+ * @since 2.0.0
5170
+ */
5171
+ interface MacroReplacementInterface {
5172
+ /**
5173
+ * Original source text that should be replaced.
5174
+ *
5175
+ * @remarks
5176
+ * Typically, this is an exact substring extracted from a file (e.g., a macro call,
5177
+ * a macro variable initializer, or any other segment discovered during analysis).
5178
+ *
5179
+ * Consumers can use this to:
5180
+ * - build diagnostics ("what was replaced?")
5181
+ * - provide debug output / reports
5182
+ * - verify transformations are deterministic
5183
+ *
5184
+ * @since 2.0.0
5185
+ */
5186
+ source: string;
5187
+ /**
5188
+ * Replacement text that should be substituted in place of {@link source}.
5189
+ *
5190
+ * @remarks
5191
+ * This is the final text representation that should appear in the transformed output.
5192
+ * For disabled macros this is often `'undefined'`, but it may also be an inlined constant,
5193
+ * rewritten function body, or other generated code.
5194
+ *
5195
+ * @since 2.0.0
5196
+ */
5197
+ replacement: string;
5198
+ }
5199
+ /**
5200
+ * Extended lifecycle stage interface with macro-specific metadata.
5201
+ *
5202
+ * @remarks
5203
+ * This interface extends the base {@link LifecycleStageInterface} to include
5204
+ * macro analysis metadata, making it available throughout the build lifecycle.
5205
+ *
5206
+ * The metadata is:
5207
+ * - Populated during the analysis phase by {@link analyzeMacroMetadata}
5208
+ * - Consumed during the transformation phase by {@link transformerDirective}
5209
+ * - Accessible to all lifecycle hooks that need macro information
5210
+ *
5211
+ * @example Using in build lifecycle
5212
+ * ```ts
5213
+ * async function onBuild(context: { stage: MacrosStateInterface }) {
5214
+ * const { defineMetadata } = context.stage;
5215
+ *
5216
+ * console.log(`Files with macros: ${defineMetadata.filesWithMacros.size}`);
5217
+ * console.log(`Disabled macros: ${defineMetadata.disabledMacroNames.size}`);
5218
+ * }
5219
+ * ```
5220
+ *
5221
+ * @example Checking macro status in plugin
5222
+ * ```ts
5223
+ * function myPlugin(stage: MacrosStateInterface) {
5224
+ * return {
5225
+ * name: 'my-plugin',
5226
+ * setup(build) {
5227
+ * build.onLoad({ filter: /\.ts$/ }, (args) => {
5228
+ * if (!stage.defineMetadata.filesWithMacros.has(args.path)) {
5229
+ * // Skip macro processing for this file
5230
+ * return null;
5231
+ * }
5232
+ *
5233
+ * // Process macros...
5234
+ * });
5235
+ * }
5236
+ * };
5237
+ * }
5238
+ * ```
5239
+ *
5240
+ * @example Accessing in transformer
5241
+ * ```ts
5242
+ * function transform(code: string, stage: MacrosStateInterface): string {
5243
+ * const { disabledMacroNames } = stage.defineMetadata;
5244
+ *
5245
+ * // Remove disabled macros
5246
+ * for (const macroName of disabledMacroNames) {
5247
+ * code = code.replace(new RegExp(macroName, 'g'), 'undefined');
5248
+ * }
5249
+ *
5250
+ * return code;
5251
+ * }
5252
+ * ```
5253
+ *
5254
+ * @see {@link analyzeMacroMetadata} for metadata generation
5255
+ * @see {@link MacrosMetadataInterface} for metadata structure
5256
+ * @see {@link LifecycleStageInterface} for base stage properties
5257
+ *
5258
+ * @since 2.0.0
5259
+ */
5260
+ interface MacrosStateInterface extends LifecycleStageInterface {
5261
+ /**
5262
+ * Macro analysis metadata for the current build.
5263
+ *
5264
+ * @remarks
5265
+ * Contains information about:
5266
+ * - Which files contain macros and need processing
5267
+ * - Which macro names should be removed based on definitions
5268
+ *
5269
+ * This metadata is shared across all build plugins and transformers
5270
+ * to ensure consistent macro handling throughout the build process.
5271
+ *
5272
+ * @since 2.0.0
5273
+ */
5274
+ defineMetadata: MacrosMetadataInterface;
5275
+ /**
5276
+ * Optional map of macro-driven source replacements recorded during transformation.
5277
+ *
5278
+ * @remarks
5279
+ * When present, this can be used for:
5280
+ * - debugging ("what exactly changed?"),
5281
+ * - producing transformation reports, or
5282
+ * - testing/verifying deterministic output.
5283
+ *
5284
+ * The keys are the name of the variant, and each value is an array of replacements made.
5285
+ * Each entry describes the original fragment and its replacement via
5286
+ * {@link MacroReplacementInterface}.
5287
+ *
5288
+ * @example
5289
+ * ```ts
5290
+ * stage.replacementInfo = {
5291
+ * 'index': [
5292
+ * { source: "$$inline(() => 1 + 1)", replacement: "2" },
5293
+ * { source: "$$debug()", replacement: "undefined" }
5294
+ * ],
5295
+ * 'config': [
5296
+ * { source: "$$ifdef('PROD', ...)", replacement: "undefined" }
5297
+ * ]
5298
+ * };
5299
+ * ```
5300
+ *
5301
+ * @since 2.0.0
5302
+ */
5303
+ replacementInfo?: Record<string, Array<MacroReplacementInterface>>;
5304
+ }
4599
5305
  /**
4600
5306
  * User-defined command-line options that extend the base xBuild CLI.
4601
5307
  *
@@ -5959,6 +6665,7 @@ export {
5959
6665
  LifecycleContextInterface,
5960
6666
  LifecycleStageInterface,
5961
6667
  LoadContextInterface,
6668
+ MacroContextInterface,
5962
6669
  MaybeUndefinedPromiseType,
5963
6670
  MaybeVoidPromiseType,
5964
6671
  OnEndType,