1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
10 | if (k2 === undefined) k2 = k;
|
11 | var desc = Object.getOwnPropertyDescriptor(m, k);
|
12 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
13 | desc = { enumerable: true, get: function() { return m[k]; } };
|
14 | }
|
15 | Object.defineProperty(o, k2, desc);
|
16 | }) : (function(o, m, k, k2) {
|
17 | if (k2 === undefined) k2 = k;
|
18 | o[k2] = m[k];
|
19 | }));
|
20 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
21 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
22 | }) : function(o, v) {
|
23 | o["default"] = v;
|
24 | });
|
25 | var __importStar = (this && this.__importStar) || function (mod) {
|
26 | if (mod && mod.__esModule) return mod;
|
27 | var result = {};
|
28 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
29 | __setModuleDefault(result, mod);
|
30 | return result;
|
31 | };
|
32 | Object.defineProperty(exports, "__esModule", { value: true });
|
33 | exports.WebpackResourceLoader = void 0;
|
34 | const path = __importStar(require("path"));
|
35 | const vm = __importStar(require("vm"));
|
36 | const paths_1 = require("./ivy/paths");
|
37 | const inline_resource_1 = require("./loaders/inline-resource");
|
38 | const replace_resources_1 = require("./transformers/replace_resources");
|
39 | class WebpackResourceLoader {
|
40 | constructor(shouldCache) {
|
41 | this._fileDependencies = new Map();
|
42 | this._reverseDependencies = new Map();
|
43 | this.modifiedResources = new Set();
|
44 | this.outputPathCounter = 1;
|
45 | this.inlineDataLoaderPath = inline_resource_1.InlineAngularResourceLoaderPath;
|
46 | if (shouldCache) {
|
47 | this.fileCache = new Map();
|
48 | this.assetCache = new Map();
|
49 | }
|
50 | }
|
51 | update(parentCompilation, changedFiles) {
|
52 | var _a, _b, _c, _d, _e;
|
53 | this._parentCompilation = parentCompilation;
|
54 |
|
55 | this.modifiedResources.clear();
|
56 | if (changedFiles) {
|
57 | for (const changedFile of changedFiles) {
|
58 | const changedFileNormalized = (0, paths_1.normalizePath)(changedFile);
|
59 | (_a = this.assetCache) === null || _a === void 0 ? void 0 : _a.delete(changedFileNormalized);
|
60 | for (const affectedResource of this.getAffectedResources(changedFile)) {
|
61 | const affectedResourceNormalized = (0, paths_1.normalizePath)(affectedResource);
|
62 | (_b = this.fileCache) === null || _b === void 0 ? void 0 : _b.delete(affectedResourceNormalized);
|
63 | this.modifiedResources.add(affectedResource);
|
64 | for (const effectedDependencies of this.getResourceDependencies(affectedResourceNormalized)) {
|
65 | (_c = this.assetCache) === null || _c === void 0 ? void 0 : _c.delete((0, paths_1.normalizePath)(effectedDependencies));
|
66 | }
|
67 | }
|
68 | }
|
69 | }
|
70 | else {
|
71 | (_d = this.fileCache) === null || _d === void 0 ? void 0 : _d.clear();
|
72 | (_e = this.assetCache) === null || _e === void 0 ? void 0 : _e.clear();
|
73 | }
|
74 |
|
75 | if (this.assetCache) {
|
76 | for (const [, { name, source, info }] of this.assetCache) {
|
77 | this._parentCompilation.emitAsset(name, source, info);
|
78 | }
|
79 | }
|
80 | }
|
81 | clearParentCompilation() {
|
82 | this._parentCompilation = undefined;
|
83 | }
|
84 | getModifiedResourceFiles() {
|
85 | return this.modifiedResources;
|
86 | }
|
87 | getResourceDependencies(filePath) {
|
88 | return this._fileDependencies.get(filePath) || [];
|
89 | }
|
90 | getAffectedResources(file) {
|
91 | return this._reverseDependencies.get(file) || [];
|
92 | }
|
93 | setAffectedResources(file, resources) {
|
94 | this._reverseDependencies.set(file, new Set(resources));
|
95 | }
|
96 |
|
97 | async _compile(filePath, data, fileExtension, resourceType, containingFile) {
|
98 | if (!this._parentCompilation) {
|
99 | throw new Error('WebpackResourceLoader cannot be used without parentCompilation');
|
100 | }
|
101 | const { context, webpack } = this._parentCompilation.compiler;
|
102 | const { EntryPlugin, NormalModule, library, node, sources, util: { createHash }, } = webpack;
|
103 | const getEntry = () => {
|
104 | if (filePath) {
|
105 | return `${filePath}?${replace_resources_1.NG_COMPONENT_RESOURCE_QUERY}`;
|
106 | }
|
107 | else if (resourceType) {
|
108 | return (
|
109 |
|
110 | `${containingFile}-${this.outputPathCounter}.${fileExtension}` +
|
111 | `?${replace_resources_1.NG_COMPONENT_RESOURCE_QUERY}!=!${this.inlineDataLoaderPath}!${containingFile}`);
|
112 | }
|
113 | else if (data) {
|
114 |
|
115 | return `angular-resource:${resourceType},${createHash('xxhash64')
|
116 | .update(data)
|
117 | .digest('hex')}`;
|
118 | }
|
119 | throw new Error(`"filePath", "resourceType" or "data" must be specified.`);
|
120 | };
|
121 | const entry = getEntry();
|
122 |
|
123 | if (filePath === null || filePath === void 0 ? void 0 : filePath.match(/\.[jt]s$/)) {
|
124 | throw new Error(`Cannot use a JavaScript or TypeScript file (${filePath}) in a component's styleUrls or templateUrl.`);
|
125 | }
|
126 | const outputFilePath = filePath ||
|
127 | `${containingFile}-angular-inline--${this.outputPathCounter++}.${resourceType === 'template' ? 'html' : 'css'}`;
|
128 | const outputOptions = {
|
129 | filename: outputFilePath,
|
130 | library: {
|
131 | type: 'var',
|
132 | name: 'resource',
|
133 | },
|
134 | };
|
135 | const childCompiler = this._parentCompilation.createChildCompiler('angular-compiler:resource', outputOptions, [
|
136 | new node.NodeTemplatePlugin(outputOptions),
|
137 | new node.NodeTargetPlugin(),
|
138 | new EntryPlugin(context, entry, { name: 'resource' }),
|
139 | new library.EnableLibraryPlugin('var'),
|
140 | ]);
|
141 | childCompiler.hooks.thisCompilation.tap('angular-compiler', (compilation, { normalModuleFactory }) => {
|
142 |
|
143 | if (data !== undefined) {
|
144 | normalModuleFactory.hooks.resolveForScheme
|
145 | .for('angular-resource')
|
146 | .tap('angular-compiler', (resourceData) => {
|
147 | if (filePath) {
|
148 | resourceData.path = filePath;
|
149 | resourceData.resource = filePath;
|
150 | }
|
151 | return true;
|
152 | });
|
153 | NormalModule.getCompilationHooks(compilation)
|
154 | .readResourceForScheme.for('angular-resource')
|
155 | .tap('angular-compiler', () => data);
|
156 | compilation[inline_resource_1.InlineAngularResourceSymbol] = data;
|
157 | }
|
158 | compilation.hooks.additionalAssets.tap('angular-compiler', () => {
|
159 | const asset = compilation.assets[outputFilePath];
|
160 | if (!asset) {
|
161 | return;
|
162 | }
|
163 | try {
|
164 | const output = this._evaluate(outputFilePath, asset.source().toString());
|
165 | if (typeof output === 'string') {
|
166 | compilation.assets[outputFilePath] = new sources.RawSource(output);
|
167 | }
|
168 | }
|
169 | catch (error) {
|
170 |
|
171 | compilation.errors.push(error);
|
172 | }
|
173 | });
|
174 | });
|
175 | let finalContent;
|
176 | childCompiler.hooks.compilation.tap('angular-compiler', (childCompilation) => {
|
177 | childCompilation.hooks.processAssets.tap({ name: 'angular-compiler', stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT }, () => {
|
178 | var _a;
|
179 | finalContent = (_a = childCompilation.assets[outputFilePath]) === null || _a === void 0 ? void 0 : _a.source().toString();
|
180 | for (const { files } of childCompilation.chunks) {
|
181 | for (const file of files) {
|
182 | childCompilation.deleteAsset(file);
|
183 | }
|
184 | }
|
185 | });
|
186 | });
|
187 | return new Promise((resolve, reject) => {
|
188 | childCompiler.runAsChild((error, _, childCompilation) => {
|
189 | var _a, _b;
|
190 | if (error) {
|
191 | reject(error);
|
192 | return;
|
193 | }
|
194 | else if (!childCompilation) {
|
195 | reject(new Error('Unknown child compilation error'));
|
196 | return;
|
197 | }
|
198 |
|
199 |
|
200 |
|
201 | const parent = childCompiler.parentCompilation;
|
202 | if (parent) {
|
203 | parent.children = parent.children.filter((child) => child !== childCompilation);
|
204 | let fileDependencies;
|
205 | for (const dependency of childCompilation.fileDependencies) {
|
206 |
|
207 |
|
208 |
|
209 | if (!path.extname(dependency)) {
|
210 | continue;
|
211 | }
|
212 | if (data && containingFile && dependency.endsWith(entry)) {
|
213 |
|
214 | parent.fileDependencies.add(containingFile);
|
215 | }
|
216 | else {
|
217 | parent.fileDependencies.add(dependency);
|
218 | }
|
219 |
|
220 | if (filePath) {
|
221 | const resolvedFile = (0, paths_1.normalizePath)(dependency);
|
222 | const entry = this._reverseDependencies.get(resolvedFile);
|
223 | if (entry) {
|
224 | entry.add(filePath);
|
225 | }
|
226 | else {
|
227 | this._reverseDependencies.set(resolvedFile, new Set([filePath]));
|
228 | }
|
229 | if (fileDependencies) {
|
230 | fileDependencies.add(dependency);
|
231 | }
|
232 | else {
|
233 | fileDependencies = new Set([dependency]);
|
234 | this._fileDependencies.set(filePath, fileDependencies);
|
235 | }
|
236 | }
|
237 | }
|
238 | parent.contextDependencies.addAll(childCompilation.contextDependencies);
|
239 | parent.missingDependencies.addAll(childCompilation.missingDependencies);
|
240 | parent.buildDependencies.addAll(childCompilation.buildDependencies);
|
241 | parent.warnings.push(...childCompilation.warnings);
|
242 | parent.errors.push(...childCompilation.errors);
|
243 | if (this.assetCache) {
|
244 | for (const { info, name, source } of childCompilation.getAssets()) {
|
245 |
|
246 |
|
247 | const cacheKey = (_a = info.sourceFilename) !== null && _a !== void 0 ? _a : `!![GENERATED]:${name}`;
|
248 | this.assetCache.set(cacheKey, { info, name, source });
|
249 | }
|
250 | }
|
251 | }
|
252 | resolve({
|
253 | content: finalContent !== null && finalContent !== void 0 ? finalContent : '',
|
254 | success: ((_b = childCompilation.errors) === null || _b === void 0 ? void 0 : _b.length) === 0,
|
255 | });
|
256 | });
|
257 | });
|
258 | }
|
259 | _evaluate(filename, source) {
|
260 | var _a;
|
261 |
|
262 | const context = {};
|
263 | try {
|
264 | vm.runInNewContext(source, context, { filename });
|
265 | }
|
266 | catch {
|
267 |
|
268 | return null;
|
269 | }
|
270 | if (typeof context.resource === 'string') {
|
271 | return context.resource;
|
272 | }
|
273 | else if (typeof ((_a = context.resource) === null || _a === void 0 ? void 0 : _a.default) === 'string') {
|
274 | return context.resource.default;
|
275 | }
|
276 | throw new Error(`The loader "${filename}" didn't return a string.`);
|
277 | }
|
278 | async get(filePath) {
|
279 | var _a;
|
280 | const normalizedFile = (0, paths_1.normalizePath)(filePath);
|
281 | let compilationResult = (_a = this.fileCache) === null || _a === void 0 ? void 0 : _a.get(normalizedFile);
|
282 | if (compilationResult === undefined) {
|
283 |
|
284 | compilationResult = await this._compile(filePath);
|
285 |
|
286 | if (this.fileCache && compilationResult.success) {
|
287 | this.fileCache.set(normalizedFile, compilationResult);
|
288 | }
|
289 | }
|
290 | return compilationResult.content;
|
291 | }
|
292 | async process(data, fileExtension, resourceType, containingFile) {
|
293 | if (data.trim().length === 0) {
|
294 | return '';
|
295 | }
|
296 | const compilationResult = await this._compile(undefined, data, fileExtension, resourceType, containingFile);
|
297 | return compilationResult.content;
|
298 | }
|
299 | }
|
300 | exports.WebpackResourceLoader = WebpackResourceLoader;
|