@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/README.md +4 -3
- package/dist/bash.js +32 -32
- package/dist/bash.js.map +5 -5
- package/dist/index.d.ts +709 -2
- package/dist/index.js +13 -15
- package/dist/index.js.map +5 -5
- package/package.json +7 -7
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
|
|
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,
|