@atlaspack/core 2.12.1-canary.3354
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/LICENSE +201 -0
- package/index.d.ts +22 -0
- package/lib/AssetGraph.js +518 -0
- package/lib/Atlaspack.js +587 -0
- package/lib/AtlaspackConfig.js +298 -0
- package/lib/AtlaspackConfig.schema.js +125 -0
- package/lib/BundleGraph.js +1445 -0
- package/lib/CommittedAsset.js +133 -0
- package/lib/Dependency.js +88 -0
- package/lib/Environment.js +128 -0
- package/lib/InternalConfig.js +48 -0
- package/lib/PackagerRunner.js +519 -0
- package/lib/ReporterRunner.js +151 -0
- package/lib/RequestTracker.js +1089 -0
- package/lib/SymbolPropagation.js +625 -0
- package/lib/TargetDescriptor.schema.js +115 -0
- package/lib/Transformation.js +536 -0
- package/lib/UncommittedAsset.js +342 -0
- package/lib/Validation.js +215 -0
- package/lib/applyRuntimes.js +279 -0
- package/lib/assetUtils.js +189 -0
- package/lib/atlaspack-v3/AtlaspackV3.js +74 -0
- package/lib/atlaspack-v3/fs.js +30 -0
- package/lib/atlaspack-v3/index.js +19 -0
- package/lib/atlaspack-v3/jsCallable.js +15 -0
- package/lib/atlaspack-v3/plugins/Resolver.js +12 -0
- package/lib/atlaspack-v3/plugins/index.js +16 -0
- package/lib/atlaspack-v3/worker/index.js +3 -0
- package/lib/atlaspack-v3/worker/worker.js +30 -0
- package/lib/buildCache.js +18 -0
- package/lib/constants.js +21 -0
- package/lib/dumpGraphToGraphViz.js +206 -0
- package/lib/index.js +106 -0
- package/lib/loadAtlaspackPlugin.js +148 -0
- package/lib/loadDotEnv.js +54 -0
- package/lib/projectPath.js +86 -0
- package/lib/public/Asset.js +259 -0
- package/lib/public/Bundle.js +231 -0
- package/lib/public/BundleGraph.js +193 -0
- package/lib/public/BundleGroup.js +44 -0
- package/lib/public/Config.js +202 -0
- package/lib/public/Dependency.js +131 -0
- package/lib/public/Environment.js +244 -0
- package/lib/public/MutableBundleGraph.js +184 -0
- package/lib/public/PluginOptions.js +71 -0
- package/lib/public/Symbols.js +247 -0
- package/lib/public/Target.js +64 -0
- package/lib/registerCoreWithSerializer.js +45 -0
- package/lib/requests/AssetGraphRequest.js +427 -0
- package/lib/requests/AssetGraphRequestRust.js +187 -0
- package/lib/requests/AssetRequest.js +137 -0
- package/lib/requests/AtlaspackBuildRequest.js +78 -0
- package/lib/requests/AtlaspackConfigRequest.js +473 -0
- package/lib/requests/BundleGraphRequest.js +419 -0
- package/lib/requests/ConfigRequest.js +198 -0
- package/lib/requests/DevDepRequest.js +166 -0
- package/lib/requests/EntryRequest.js +295 -0
- package/lib/requests/PackageRequest.js +88 -0
- package/lib/requests/PathRequest.js +349 -0
- package/lib/requests/TargetRequest.js +1177 -0
- package/lib/requests/ValidationRequest.js +66 -0
- package/lib/requests/WriteBundleRequest.js +252 -0
- package/lib/requests/WriteBundlesRequest.js +153 -0
- package/lib/resolveOptions.js +234 -0
- package/lib/serializer.js +216 -0
- package/lib/serializerCore.browser.js +29 -0
- package/lib/serializerCore.js +16 -0
- package/lib/summarizeRequest.js +55 -0
- package/lib/types.js +35 -0
- package/lib/utils.js +160 -0
- package/lib/worker.js +170 -0
- package/package.json +59 -0
- package/src/AssetGraph.js +646 -0
- package/src/Atlaspack.js +632 -0
- package/src/AtlaspackConfig.js +490 -0
- package/src/AtlaspackConfig.schema.js +141 -0
- package/src/BundleGraph.js +2193 -0
- package/src/CommittedAsset.js +143 -0
- package/src/Dependency.js +142 -0
- package/src/Environment.js +151 -0
- package/src/InternalConfig.js +72 -0
- package/src/PackagerRunner.js +790 -0
- package/src/ReporterRunner.js +158 -0
- package/src/RequestTracker.js +1697 -0
- package/src/SymbolPropagation.js +794 -0
- package/src/TargetDescriptor.schema.js +136 -0
- package/src/Transformation.js +752 -0
- package/src/UncommittedAsset.js +426 -0
- package/src/Validation.js +223 -0
- package/src/applyRuntimes.js +341 -0
- package/src/assetUtils.js +254 -0
- package/src/atlaspack-v3/AtlaspackV3.js +73 -0
- package/src/atlaspack-v3/fs.js +36 -0
- package/src/atlaspack-v3/index.js +5 -0
- package/src/atlaspack-v3/jsCallable.js +13 -0
- package/src/atlaspack-v3/plugins/Resolver.js +9 -0
- package/src/atlaspack-v3/plugins/index.js +3 -0
- package/src/atlaspack-v3/worker/index.js +8 -0
- package/src/atlaspack-v3/worker/worker.js +14 -0
- package/src/buildCache.js +15 -0
- package/src/constants.js +22 -0
- package/src/dumpGraphToGraphViz.js +244 -0
- package/src/index.js +22 -0
- package/src/loadAtlaspackPlugin.js +239 -0
- package/src/loadDotEnv.js +56 -0
- package/src/projectPath.js +87 -0
- package/src/public/Asset.js +359 -0
- package/src/public/Bundle.js +337 -0
- package/src/public/BundleGraph.js +335 -0
- package/src/public/BundleGroup.js +55 -0
- package/src/public/Config.js +261 -0
- package/src/public/Dependency.js +176 -0
- package/src/public/Environment.js +316 -0
- package/src/public/MutableBundleGraph.js +320 -0
- package/src/public/PluginOptions.js +99 -0
- package/src/public/Symbols.js +315 -0
- package/src/public/Target.js +71 -0
- package/src/registerCoreWithSerializer.js +34 -0
- package/src/requests/AssetGraphRequest.js +577 -0
- package/src/requests/AssetGraphRequestRust.js +222 -0
- package/src/requests/AssetRequest.js +179 -0
- package/src/requests/AtlaspackBuildRequest.js +109 -0
- package/src/requests/AtlaspackConfigRequest.js +709 -0
- package/src/requests/BundleGraphRequest.js +547 -0
- package/src/requests/ConfigRequest.js +287 -0
- package/src/requests/DevDepRequest.js +246 -0
- package/src/requests/EntryRequest.js +385 -0
- package/src/requests/PackageRequest.js +105 -0
- package/src/requests/PathRequest.js +454 -0
- package/src/requests/TargetRequest.js +1632 -0
- package/src/requests/ValidationRequest.js +79 -0
- package/src/requests/WriteBundleRequest.js +362 -0
- package/src/requests/WriteBundlesRequest.js +209 -0
- package/src/resolveOptions.js +278 -0
- package/src/serializer.js +255 -0
- package/src/serializerCore.browser.js +8 -0
- package/src/serializerCore.js +5 -0
- package/src/summarizeRequest.js +47 -0
- package/src/types.js +581 -0
- package/src/utils.js +211 -0
- package/src/worker.js +189 -0
- package/test/AssetGraph.test.js +679 -0
- package/test/Atlaspack.test.js +142 -0
- package/test/AtlaspackConfig.test.js +405 -0
- package/test/AtlaspackConfigRequest.test.js +993 -0
- package/test/BundleGraph.test.js +121 -0
- package/test/EntryRequest.test.js +215 -0
- package/test/Environment.test.js +99 -0
- package/test/InternalAsset.test.js +76 -0
- package/test/PackagerRunner.test.js +27 -0
- package/test/PublicAsset.test.js +40 -0
- package/test/PublicBundle.test.js +68 -0
- package/test/PublicDependency.test.js +22 -0
- package/test/PublicEnvironment.test.js +27 -0
- package/test/PublicMutableBundleGraph.test.js +192 -0
- package/test/RequestTracker.test.js +448 -0
- package/test/SymbolPropagation.test.js +716 -0
- package/test/TargetRequest.test.js +1715 -0
- package/test/fixtures/application-targets/package.json +3 -0
- package/test/fixtures/atlaspack/index.js +1 -0
- package/test/fixtures/atlaspack/other.js +3 -0
- package/test/fixtures/atlaspack/package.json +1 -0
- package/test/fixtures/atlaspack/yarn.lock +0 -0
- package/test/fixtures/bundle.js +10 -0
- package/test/fixtures/common-targets/package.json +24 -0
- package/test/fixtures/common-targets-ignore/package.json +13 -0
- package/test/fixtures/config/.atlaspackrc +6 -0
- package/test/fixtures/config/subfolder/.atlaspackrc +6 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc +3 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc-json5 +3 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc-multiple +3 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc-node-modules +3 -0
- package/test/fixtures/config-malformed/.atlaspackrc +3 -0
- package/test/fixtures/config-node-pipeline/.atlaspackrc +6 -0
- package/test/fixtures/config-plugin-not-found/.atlaspackrc +6 -0
- package/test/fixtures/context/package.json +8 -0
- package/test/fixtures/custom-format-infer-ext/package.json +6 -0
- package/test/fixtures/custom-format-infer-type/package.json +7 -0
- package/test/fixtures/custom-format-mismatch/package.json +8 -0
- package/test/fixtures/custom-targets/package.json +20 -0
- package/test/fixtures/custom-targets-distdir/package.json +11 -0
- package/test/fixtures/duplicate-targets/package.json +4 -0
- package/test/fixtures/glob-like/[entry].js +0 -0
- package/test/fixtures/invalid-distpath/package.json +11 -0
- package/test/fixtures/invalid-engines/package.json +12 -0
- package/test/fixtures/invalid-source-missing/package.json +5 -0
- package/test/fixtures/invalid-source-not-file/package.json +5 -0
- package/test/fixtures/invalid-source-not-file/src/index.js +1 -0
- package/test/fixtures/invalid-target-source-missing/package.json +9 -0
- package/test/fixtures/invalid-target-source-not-file/package.json +9 -0
- package/test/fixtures/invalid-target-source-not-file/src/index.js +1 -0
- package/test/fixtures/invalid-targets/package.json +19 -0
- package/test/fixtures/library-custom-scopehoist/package.json +9 -0
- package/test/fixtures/library-scopehoist/package.json +8 -0
- package/test/fixtures/local-plugin-config-pkg/.atlaspackrc +3 -0
- package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/index.json +8 -0
- package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/local-plugin.js +7 -0
- package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/package.json +7 -0
- package/test/fixtures/main-format-mismatch/package.json +8 -0
- package/test/fixtures/main-global/package.json +8 -0
- package/test/fixtures/main-mjs/package.json +8 -0
- package/test/fixtures/module-a.js +1 -0
- package/test/fixtures/module-b.js +1 -0
- package/test/fixtures/plugins/local-plugin.js +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-bad-engines/index.js +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-bad-engines/package.json +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-no-engines/index.js +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-no-engines/package.json +4 -0
- package/test/fixtures/targets-default-distdir-none/package.json +5 -0
- package/test/fixtures/targets-default-distdir-one/package.json +8 -0
- package/test/fixtures/targets-default-distdir-two/package.json +18 -0
- package/test/requests/ConfigRequest.test.js +254 -0
- package/test/serializer.test.js +302 -0
- package/test/test-utils.js +80 -0
- package/test/utils.test.js +43 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
AST,
|
|
5
|
+
Blob,
|
|
6
|
+
DependencyOptions,
|
|
7
|
+
FileCreateInvalidation,
|
|
8
|
+
GenerateOutput,
|
|
9
|
+
PackageName,
|
|
10
|
+
TransformerResult,
|
|
11
|
+
} from '@atlaspack/types';
|
|
12
|
+
import type {Asset, Dependency, AtlaspackOptions, Invalidations} from './types';
|
|
13
|
+
|
|
14
|
+
import invariant from 'assert';
|
|
15
|
+
import {Readable} from 'stream';
|
|
16
|
+
import SourceMap from '@parcel/source-map';
|
|
17
|
+
import {
|
|
18
|
+
blobToStream,
|
|
19
|
+
bufferStream,
|
|
20
|
+
streamFromPromise,
|
|
21
|
+
TapStream,
|
|
22
|
+
loadSourceMap,
|
|
23
|
+
SOURCEMAP_RE,
|
|
24
|
+
} from '@atlaspack/utils';
|
|
25
|
+
import {hashString, hashBuffer, Hash} from '@atlaspack/rust';
|
|
26
|
+
import {serializeRaw} from './serializer';
|
|
27
|
+
import {createDependency, mergeDependencies} from './Dependency';
|
|
28
|
+
import {mergeEnvironments} from './Environment';
|
|
29
|
+
import {ATLASPACK_VERSION} from './constants';
|
|
30
|
+
import {createAsset, createAssetIdFromOptions} from './assetUtils';
|
|
31
|
+
import {BundleBehaviorNames} from './types';
|
|
32
|
+
import {invalidateOnFileCreateToInternal, createInvalidations} from './utils';
|
|
33
|
+
import {type ProjectPath, fromProjectPath} from './projectPath';
|
|
34
|
+
|
|
35
|
+
type UncommittedAssetOptions = {|
|
|
36
|
+
value: Asset,
|
|
37
|
+
options: AtlaspackOptions,
|
|
38
|
+
content?: ?Blob,
|
|
39
|
+
mapBuffer?: ?Buffer,
|
|
40
|
+
ast?: ?AST,
|
|
41
|
+
isASTDirty?: ?boolean,
|
|
42
|
+
idBase?: ?string,
|
|
43
|
+
invalidations?: Invalidations,
|
|
44
|
+
|};
|
|
45
|
+
|
|
46
|
+
export default class UncommittedAsset {
|
|
47
|
+
value: Asset;
|
|
48
|
+
options: AtlaspackOptions;
|
|
49
|
+
content: ?(Blob | Promise<Buffer>);
|
|
50
|
+
mapBuffer: ?Buffer;
|
|
51
|
+
sourceContent: ?string;
|
|
52
|
+
map: ?SourceMap;
|
|
53
|
+
ast: ?AST;
|
|
54
|
+
isASTDirty: boolean;
|
|
55
|
+
idBase: ?string;
|
|
56
|
+
invalidations: Invalidations;
|
|
57
|
+
generate: ?() => Promise<GenerateOutput>;
|
|
58
|
+
|
|
59
|
+
constructor({
|
|
60
|
+
value,
|
|
61
|
+
options,
|
|
62
|
+
content,
|
|
63
|
+
mapBuffer,
|
|
64
|
+
ast,
|
|
65
|
+
isASTDirty,
|
|
66
|
+
idBase,
|
|
67
|
+
invalidations,
|
|
68
|
+
}: UncommittedAssetOptions) {
|
|
69
|
+
this.value = value;
|
|
70
|
+
this.options = options;
|
|
71
|
+
this.content = content;
|
|
72
|
+
this.mapBuffer = mapBuffer;
|
|
73
|
+
this.ast = ast;
|
|
74
|
+
this.isASTDirty = isASTDirty || false;
|
|
75
|
+
this.idBase = idBase;
|
|
76
|
+
this.invalidations = invalidations || createInvalidations();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/*
|
|
80
|
+
* Prepares the asset for being serialized to the cache by committing its
|
|
81
|
+
* content and map of the asset to the cache.
|
|
82
|
+
*/
|
|
83
|
+
async commit(): Promise<void> {
|
|
84
|
+
// If there is a dirty AST, clear out any old content and map as these
|
|
85
|
+
// must be regenerated later and shouldn't be committed.
|
|
86
|
+
if (this.ast != null && this.isASTDirty) {
|
|
87
|
+
this.content = null;
|
|
88
|
+
this.mapBuffer = null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let size = 0;
|
|
92
|
+
let outputHash = '';
|
|
93
|
+
let contentKey = this.content == null ? null : this.getCacheKey('content');
|
|
94
|
+
let mapKey = this.mapBuffer == null ? null : this.getCacheKey('map');
|
|
95
|
+
let astKey = this.ast == null ? null : this.getCacheKey('ast');
|
|
96
|
+
|
|
97
|
+
// Since we can only read from the stream once, compute the content length
|
|
98
|
+
// and hash while it's being written to the cache.
|
|
99
|
+
await Promise.all([
|
|
100
|
+
contentKey != null &&
|
|
101
|
+
this.commitContent(contentKey).then(
|
|
102
|
+
s => ((size = s.size), (outputHash = s.hash)),
|
|
103
|
+
),
|
|
104
|
+
this.mapBuffer != null &&
|
|
105
|
+
mapKey != null &&
|
|
106
|
+
this.options.cache.setBlob(mapKey, this.mapBuffer),
|
|
107
|
+
astKey != null &&
|
|
108
|
+
this.options.cache.setBlob(astKey, serializeRaw(this.ast)),
|
|
109
|
+
]);
|
|
110
|
+
this.value.contentKey = contentKey;
|
|
111
|
+
this.value.mapKey = mapKey;
|
|
112
|
+
this.value.astKey = astKey;
|
|
113
|
+
this.value.outputHash = outputHash;
|
|
114
|
+
|
|
115
|
+
if (this.content != null) {
|
|
116
|
+
this.value.stats.size = size;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.value.isLargeBlob = this.content instanceof Readable;
|
|
120
|
+
this.value.committed = true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async commitContent(
|
|
124
|
+
contentKey: string,
|
|
125
|
+
): Promise<{|size: number, hash: string|}> {
|
|
126
|
+
let content = await this.content;
|
|
127
|
+
if (content == null) {
|
|
128
|
+
return {size: 0, hash: ''};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let size = 0;
|
|
132
|
+
if (content instanceof Readable) {
|
|
133
|
+
let hash = new Hash();
|
|
134
|
+
await this.options.cache.setStream(
|
|
135
|
+
contentKey,
|
|
136
|
+
content.pipe(
|
|
137
|
+
new TapStream(buf => {
|
|
138
|
+
hash.writeBuffer(buf);
|
|
139
|
+
size += buf.length;
|
|
140
|
+
}),
|
|
141
|
+
),
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
return {size, hash: hash.finish()};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let hash;
|
|
148
|
+
if (typeof content === 'string') {
|
|
149
|
+
hash = hashString(content);
|
|
150
|
+
size = Buffer.byteLength(content);
|
|
151
|
+
} else {
|
|
152
|
+
hash = hashBuffer(content);
|
|
153
|
+
size = content.length;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
await this.options.cache.setBlob(contentKey, content);
|
|
157
|
+
return {size, hash};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async getCode(): Promise<string> {
|
|
161
|
+
if (this.ast != null && this.isASTDirty) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
'Cannot call getCode() on an asset with a dirty AST. For transformers, implement canReuseAST() and check asset.isASTDirty.',
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let content = await this.content;
|
|
168
|
+
if (typeof content === 'string' || content instanceof Buffer) {
|
|
169
|
+
return content.toString();
|
|
170
|
+
} else if (content != null) {
|
|
171
|
+
this.content = bufferStream(content);
|
|
172
|
+
return (await this.content).toString();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
invariant(false, 'Internal error: missing content');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async getBuffer(): Promise<Buffer> {
|
|
179
|
+
let content = await this.content;
|
|
180
|
+
if (content == null) {
|
|
181
|
+
return Buffer.alloc(0);
|
|
182
|
+
} else if (content instanceof Buffer) {
|
|
183
|
+
return content;
|
|
184
|
+
} else if (typeof content === 'string') {
|
|
185
|
+
return Buffer.from(content);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
this.content = bufferStream(content);
|
|
189
|
+
return this.content;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
getStream(): Readable {
|
|
193
|
+
if (this.content instanceof Readable) {
|
|
194
|
+
// Remove content if it's a stream, as it should not be reused.
|
|
195
|
+
let content = this.content;
|
|
196
|
+
this.content = null;
|
|
197
|
+
return content;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (this.content instanceof Promise) {
|
|
201
|
+
return streamFromPromise(this.content);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return blobToStream(this.content ?? Buffer.alloc(0));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
setCode(code: string) {
|
|
208
|
+
this.content = code;
|
|
209
|
+
this.clearAST();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
setBuffer(buffer: Buffer) {
|
|
213
|
+
this.content = buffer;
|
|
214
|
+
this.clearAST();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
setStream(stream: Readable) {
|
|
218
|
+
this.content = stream;
|
|
219
|
+
this.clearAST();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async loadExistingSourcemap(): Promise<?SourceMap> {
|
|
223
|
+
if (this.map) {
|
|
224
|
+
return this.map;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let code = await this.getCode();
|
|
228
|
+
let map = await loadSourceMap(
|
|
229
|
+
fromProjectPath(this.options.projectRoot, this.value.filePath),
|
|
230
|
+
code,
|
|
231
|
+
{
|
|
232
|
+
fs: this.options.inputFS,
|
|
233
|
+
projectRoot: this.options.projectRoot,
|
|
234
|
+
},
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
if (map) {
|
|
238
|
+
this.map = map;
|
|
239
|
+
this.mapBuffer = map.toBuffer();
|
|
240
|
+
this.setCode(code.replace(SOURCEMAP_RE, ''));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return this.map;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
getMapBuffer(): Promise<?Buffer> {
|
|
247
|
+
return Promise.resolve(this.mapBuffer);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async getMap(): Promise<?SourceMap> {
|
|
251
|
+
if (this.map == null) {
|
|
252
|
+
let mapBuffer = this.mapBuffer ?? (await this.getMapBuffer());
|
|
253
|
+
if (mapBuffer) {
|
|
254
|
+
// Get sourcemap from flatbuffer
|
|
255
|
+
this.map = new SourceMap(this.options.projectRoot, mapBuffer);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return this.map;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
setMap(map: ?SourceMap): void {
|
|
263
|
+
// If we have sourceContent available, it means this asset is source code without
|
|
264
|
+
// a previous source map. Ensure that the map set by the transformer has the original
|
|
265
|
+
// source content available.
|
|
266
|
+
if (map != null && this.sourceContent != null) {
|
|
267
|
+
map.setSourceContent(
|
|
268
|
+
fromProjectPath(this.options.projectRoot, this.value.filePath),
|
|
269
|
+
// $FlowFixMe
|
|
270
|
+
this.sourceContent,
|
|
271
|
+
);
|
|
272
|
+
this.sourceContent = null;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
this.map = map;
|
|
276
|
+
this.mapBuffer = this.map?.toBuffer();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
getAST(): Promise<?AST> {
|
|
280
|
+
return Promise.resolve(this.ast);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
setAST(ast: AST): void {
|
|
284
|
+
this.ast = ast;
|
|
285
|
+
this.isASTDirty = true;
|
|
286
|
+
this.value.astGenerator = {
|
|
287
|
+
type: ast.type,
|
|
288
|
+
version: ast.version,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
clearAST() {
|
|
293
|
+
this.ast = null;
|
|
294
|
+
this.isASTDirty = false;
|
|
295
|
+
this.value.astGenerator = null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
getCacheKey(key: string): string {
|
|
299
|
+
return hashString(ATLASPACK_VERSION + key + this.value.id);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
addDependency(opts: DependencyOptions): string {
|
|
303
|
+
// eslint-disable-next-line no-unused-vars
|
|
304
|
+
let {env, symbols, ...rest} = opts;
|
|
305
|
+
let dep = createDependency(this.options.projectRoot, {
|
|
306
|
+
...rest,
|
|
307
|
+
// $FlowFixMe "convert" the $ReadOnlyMaps to the interal mutable one
|
|
308
|
+
symbols,
|
|
309
|
+
env: mergeEnvironments(this.options.projectRoot, this.value.env, env),
|
|
310
|
+
sourceAssetId: this.value.id,
|
|
311
|
+
sourcePath: fromProjectPath(
|
|
312
|
+
this.options.projectRoot,
|
|
313
|
+
this.value.filePath,
|
|
314
|
+
),
|
|
315
|
+
});
|
|
316
|
+
let existing = this.value.dependencies.get(dep.id);
|
|
317
|
+
if (existing) {
|
|
318
|
+
mergeDependencies(existing, dep);
|
|
319
|
+
} else {
|
|
320
|
+
this.value.dependencies.set(dep.id, dep);
|
|
321
|
+
}
|
|
322
|
+
return dep.id;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
invalidateOnFileChange(filePath: ProjectPath) {
|
|
326
|
+
this.invalidations.invalidateOnFileChange.add(filePath);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
invalidateOnFileCreate(invalidation: FileCreateInvalidation) {
|
|
330
|
+
this.invalidations.invalidateOnFileCreate.push(
|
|
331
|
+
invalidateOnFileCreateToInternal(this.options.projectRoot, invalidation),
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
invalidateOnEnvChange(key: string) {
|
|
336
|
+
this.invalidations.invalidateOnEnvChange.add(key);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
invalidateOnBuild() {
|
|
340
|
+
this.invalidations.invalidateOnBuild = true;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
invalidateOnStartup() {
|
|
344
|
+
this.invalidations.invalidateOnStartup = true;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
getDependencies(): Array<Dependency> {
|
|
348
|
+
return Array.from(this.value.dependencies.values());
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
createChildAsset(
|
|
352
|
+
result: TransformerResult,
|
|
353
|
+
plugin: PackageName,
|
|
354
|
+
configPath: ProjectPath,
|
|
355
|
+
configKeyPath?: string,
|
|
356
|
+
): UncommittedAsset {
|
|
357
|
+
let content = result.content ?? null;
|
|
358
|
+
|
|
359
|
+
let asset = new UncommittedAsset({
|
|
360
|
+
value: createAsset(this.options.projectRoot, {
|
|
361
|
+
idBase: this.idBase,
|
|
362
|
+
filePath: this.value.filePath,
|
|
363
|
+
type: result.type,
|
|
364
|
+
bundleBehavior:
|
|
365
|
+
result.bundleBehavior ??
|
|
366
|
+
(this.value.bundleBehavior == null
|
|
367
|
+
? null
|
|
368
|
+
: BundleBehaviorNames[this.value.bundleBehavior]),
|
|
369
|
+
isBundleSplittable:
|
|
370
|
+
result.isBundleSplittable ?? this.value.isBundleSplittable,
|
|
371
|
+
isSource: this.value.isSource,
|
|
372
|
+
env: mergeEnvironments(
|
|
373
|
+
this.options.projectRoot,
|
|
374
|
+
this.value.env,
|
|
375
|
+
result.env,
|
|
376
|
+
),
|
|
377
|
+
dependencies:
|
|
378
|
+
this.value.type === result.type
|
|
379
|
+
? new Map(this.value.dependencies)
|
|
380
|
+
: new Map(),
|
|
381
|
+
meta: {
|
|
382
|
+
...this.value.meta,
|
|
383
|
+
...result.meta,
|
|
384
|
+
},
|
|
385
|
+
pipeline:
|
|
386
|
+
result.pipeline ??
|
|
387
|
+
(this.value.type === result.type ? this.value.pipeline : null),
|
|
388
|
+
stats: {
|
|
389
|
+
time: 0,
|
|
390
|
+
size: this.value.stats.size,
|
|
391
|
+
},
|
|
392
|
+
// $FlowFixMe
|
|
393
|
+
symbols: result.symbols,
|
|
394
|
+
sideEffects: result.sideEffects ?? this.value.sideEffects,
|
|
395
|
+
uniqueKey: result.uniqueKey,
|
|
396
|
+
astGenerator: result.ast
|
|
397
|
+
? {type: result.ast.type, version: result.ast.version}
|
|
398
|
+
: null,
|
|
399
|
+
plugin,
|
|
400
|
+
configPath,
|
|
401
|
+
configKeyPath,
|
|
402
|
+
}),
|
|
403
|
+
options: this.options,
|
|
404
|
+
content,
|
|
405
|
+
ast: result.ast,
|
|
406
|
+
isASTDirty: result.ast === this.ast ? this.isASTDirty : true,
|
|
407
|
+
mapBuffer: result.map ? result.map.toBuffer() : null,
|
|
408
|
+
idBase: this.idBase,
|
|
409
|
+
invalidations: this.invalidations,
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
let dependencies = result.dependencies;
|
|
413
|
+
if (dependencies) {
|
|
414
|
+
for (let dep of dependencies) {
|
|
415
|
+
asset.addDependency(dep);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return asset;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
updateId() {
|
|
423
|
+
// $FlowFixMe - this is fine
|
|
424
|
+
this.value.id = createAssetIdFromOptions(this.value);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import type {WorkerApi} from '@atlaspack/workers';
|
|
4
|
+
import type {AssetGroup, AtlaspackOptions, ReportFn} from './types';
|
|
5
|
+
import type {Validator, ValidateResult} from '@atlaspack/types';
|
|
6
|
+
import type {Diagnostic} from '@atlaspack/diagnostic';
|
|
7
|
+
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import {resolveConfig} from '@atlaspack/utils';
|
|
10
|
+
import logger, {PluginLogger} from '@atlaspack/logger';
|
|
11
|
+
import ThrowableDiagnostic, {errorToDiagnostic} from '@atlaspack/diagnostic';
|
|
12
|
+
import AtlaspackConfig from './AtlaspackConfig';
|
|
13
|
+
import UncommittedAsset from './UncommittedAsset';
|
|
14
|
+
import {createAsset} from './assetUtils';
|
|
15
|
+
import {Asset} from './public/Asset';
|
|
16
|
+
import PluginOptions from './public/PluginOptions';
|
|
17
|
+
import summarizeRequest from './summarizeRequest';
|
|
18
|
+
import {fromProjectPath, fromProjectPathRelative} from './projectPath';
|
|
19
|
+
import {PluginTracer} from '@atlaspack/profiler';
|
|
20
|
+
import {hashString} from '@atlaspack/rust';
|
|
21
|
+
|
|
22
|
+
export type ValidationOpts = {|
|
|
23
|
+
config: AtlaspackConfig,
|
|
24
|
+
/**
|
|
25
|
+
* If true, this Validation instance will run all validators that implement the single-threaded "validateAll" method.
|
|
26
|
+
* If falsy, it will run validators that implement the one-asset-at-a-time "validate" method.
|
|
27
|
+
*/
|
|
28
|
+
dedicatedThread?: boolean,
|
|
29
|
+
options: AtlaspackOptions,
|
|
30
|
+
requests: AssetGroup[],
|
|
31
|
+
report: ReportFn,
|
|
32
|
+
workerApi?: WorkerApi,
|
|
33
|
+
|};
|
|
34
|
+
|
|
35
|
+
export default class Validation {
|
|
36
|
+
allAssets: {[validatorName: string]: UncommittedAsset[], ...} = {};
|
|
37
|
+
allValidators: {[validatorName: string]: Validator, ...} = {};
|
|
38
|
+
dedicatedThread: boolean;
|
|
39
|
+
impactfulOptions: $Shape<AtlaspackOptions>;
|
|
40
|
+
options: AtlaspackOptions;
|
|
41
|
+
atlaspackConfig: AtlaspackConfig;
|
|
42
|
+
report: ReportFn;
|
|
43
|
+
requests: AssetGroup[];
|
|
44
|
+
workerApi: ?WorkerApi;
|
|
45
|
+
|
|
46
|
+
constructor({
|
|
47
|
+
config,
|
|
48
|
+
dedicatedThread,
|
|
49
|
+
options,
|
|
50
|
+
requests,
|
|
51
|
+
report,
|
|
52
|
+
workerApi,
|
|
53
|
+
}: ValidationOpts) {
|
|
54
|
+
this.dedicatedThread = dedicatedThread ?? false;
|
|
55
|
+
this.options = options;
|
|
56
|
+
this.atlaspackConfig = config;
|
|
57
|
+
this.report = report;
|
|
58
|
+
this.requests = requests;
|
|
59
|
+
this.workerApi = workerApi;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async run(): Promise<void> {
|
|
63
|
+
let pluginOptions = new PluginOptions(this.options);
|
|
64
|
+
await this.buildAssetsAndValidators();
|
|
65
|
+
await Promise.all(
|
|
66
|
+
Object.keys(this.allValidators).map(async validatorName => {
|
|
67
|
+
let assets = this.allAssets[validatorName];
|
|
68
|
+
if (assets) {
|
|
69
|
+
let plugin = this.allValidators[validatorName];
|
|
70
|
+
let validatorLogger = new PluginLogger({origin: validatorName});
|
|
71
|
+
let validatorTracer = new PluginTracer({
|
|
72
|
+
origin: validatorName,
|
|
73
|
+
category: 'validator',
|
|
74
|
+
});
|
|
75
|
+
let validatorResults: Array<?ValidateResult> = [];
|
|
76
|
+
try {
|
|
77
|
+
// If the plugin supports the single-threading validateAll method, pass all assets to it.
|
|
78
|
+
if (plugin.validateAll && this.dedicatedThread) {
|
|
79
|
+
validatorResults = await plugin.validateAll({
|
|
80
|
+
assets: assets.map(asset => new Asset(asset)),
|
|
81
|
+
options: pluginOptions,
|
|
82
|
+
logger: validatorLogger,
|
|
83
|
+
tracer: validatorTracer,
|
|
84
|
+
resolveConfigWithPath: (
|
|
85
|
+
configNames: Array<string>,
|
|
86
|
+
assetFilePath: string,
|
|
87
|
+
) =>
|
|
88
|
+
resolveConfig(
|
|
89
|
+
this.options.inputFS,
|
|
90
|
+
assetFilePath,
|
|
91
|
+
configNames,
|
|
92
|
+
this.options.projectRoot,
|
|
93
|
+
),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Otherwise, pass the assets one-at-a-time
|
|
98
|
+
else if (plugin.validate && !this.dedicatedThread) {
|
|
99
|
+
await Promise.all(
|
|
100
|
+
assets.map(async input => {
|
|
101
|
+
let config = null;
|
|
102
|
+
let publicAsset = new Asset(input);
|
|
103
|
+
if (plugin.getConfig) {
|
|
104
|
+
config = await plugin.getConfig({
|
|
105
|
+
asset: publicAsset,
|
|
106
|
+
options: pluginOptions,
|
|
107
|
+
logger: validatorLogger,
|
|
108
|
+
tracer: validatorTracer,
|
|
109
|
+
resolveConfig: (configNames: Array<string>) =>
|
|
110
|
+
resolveConfig(
|
|
111
|
+
this.options.inputFS,
|
|
112
|
+
publicAsset.filePath,
|
|
113
|
+
configNames,
|
|
114
|
+
this.options.projectRoot,
|
|
115
|
+
),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let validatorResult = await plugin.validate({
|
|
120
|
+
asset: publicAsset,
|
|
121
|
+
options: pluginOptions,
|
|
122
|
+
config,
|
|
123
|
+
logger: validatorLogger,
|
|
124
|
+
tracer: validatorTracer,
|
|
125
|
+
});
|
|
126
|
+
validatorResults.push(validatorResult);
|
|
127
|
+
}),
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
this.handleResults(validatorResults);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
throw new ThrowableDiagnostic({
|
|
133
|
+
diagnostic: errorToDiagnostic(e, {
|
|
134
|
+
origin: validatorName,
|
|
135
|
+
}),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async buildAssetsAndValidators() {
|
|
144
|
+
// Figure out what validators need to be run, and group the assets by the relevant validators.
|
|
145
|
+
await Promise.all(
|
|
146
|
+
this.requests.map(async request => {
|
|
147
|
+
this.report({
|
|
148
|
+
type: 'validation',
|
|
149
|
+
filePath: fromProjectPath(this.options.projectRoot, request.filePath),
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
let asset = await this.loadAsset(request);
|
|
153
|
+
|
|
154
|
+
let validators = await this.atlaspackConfig.getValidators(
|
|
155
|
+
request.filePath,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
for (let validator of validators) {
|
|
159
|
+
this.allValidators[validator.name] = validator.plugin;
|
|
160
|
+
if (this.allAssets[validator.name]) {
|
|
161
|
+
this.allAssets[validator.name].push(asset);
|
|
162
|
+
} else {
|
|
163
|
+
this.allAssets[validator.name] = [asset];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
handleResults(validatorResults: Array<?ValidateResult>) {
|
|
171
|
+
let warnings: Array<Diagnostic> = [];
|
|
172
|
+
let errors: Array<Diagnostic> = [];
|
|
173
|
+
validatorResults.forEach(result => {
|
|
174
|
+
if (result) {
|
|
175
|
+
warnings.push(...result.warnings);
|
|
176
|
+
errors.push(...result.errors);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
if (errors.length > 0) {
|
|
181
|
+
throw new ThrowableDiagnostic({
|
|
182
|
+
diagnostic: errors,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (warnings.length > 0) {
|
|
187
|
+
logger.warn(warnings);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async loadAsset(request: AssetGroup): Promise<UncommittedAsset> {
|
|
192
|
+
let {filePath, env, code, sideEffects, query} = request;
|
|
193
|
+
let {content, size, isSource} = await summarizeRequest(
|
|
194
|
+
this.options.inputFS,
|
|
195
|
+
{
|
|
196
|
+
filePath: fromProjectPath(this.options.projectRoot, request.filePath),
|
|
197
|
+
},
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// If the transformer request passed code rather than a filename,
|
|
201
|
+
// use a hash as the base for the id to ensure it is unique.
|
|
202
|
+
let idBase =
|
|
203
|
+
code != null ? hashString(code) : fromProjectPathRelative(filePath);
|
|
204
|
+
return new UncommittedAsset({
|
|
205
|
+
idBase,
|
|
206
|
+
value: createAsset(this.options.projectRoot, {
|
|
207
|
+
idBase,
|
|
208
|
+
filePath: filePath,
|
|
209
|
+
isSource,
|
|
210
|
+
type: path.extname(fromProjectPathRelative(filePath)).slice(1),
|
|
211
|
+
query,
|
|
212
|
+
env: env,
|
|
213
|
+
stats: {
|
|
214
|
+
time: 0,
|
|
215
|
+
size,
|
|
216
|
+
},
|
|
217
|
+
sideEffects: sideEffects,
|
|
218
|
+
}),
|
|
219
|
+
options: this.options,
|
|
220
|
+
content,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|