1 | "use strict";
|
---|
2 | /**
|
---|
3 | * @license
|
---|
4 | * Copyright Google LLC All Rights Reserved.
|
---|
5 | *
|
---|
6 | * Use of this source code is governed by an MIT-style license that can be
|
---|
7 | * found in the LICENSE file at https://angular.io/license
|
---|
8 | */
|
---|
9 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
---|
10 | if (k2 === undefined) k2 = k;
|
---|
11 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
---|
12 | }) : (function(o, m, k, k2) {
|
---|
13 | if (k2 === undefined) k2 = k;
|
---|
14 | o[k2] = m[k];
|
---|
15 | }));
|
---|
16 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
---|
17 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
---|
18 | }) : function(o, v) {
|
---|
19 | o["default"] = v;
|
---|
20 | });
|
---|
21 | var __importStar = (this && this.__importStar) || function (mod) {
|
---|
22 | if (mod && mod.__esModule) return mod;
|
---|
23 | var result = {};
|
---|
24 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
---|
25 | __setModuleDefault(result, mod);
|
---|
26 | return result;
|
---|
27 | };
|
---|
28 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
29 | exports.BundleActionCache = void 0;
|
---|
30 | const cacache = __importStar(require("cacache"));
|
---|
31 | const crypto_1 = require("crypto");
|
---|
32 | const fs = __importStar(require("fs"));
|
---|
33 | const copy_file_1 = require("./copy-file");
|
---|
34 | const environment_options_1 = require("./environment-options");
|
---|
35 | const packageVersion = require('../../package.json').version;
|
---|
36 | class BundleActionCache {
|
---|
37 | constructor(cachePath, integrityAlgorithm) {
|
---|
38 | this.cachePath = cachePath;
|
---|
39 | this.integrityAlgorithm = integrityAlgorithm;
|
---|
40 | }
|
---|
41 | static copyEntryContent(entry, dest) {
|
---|
42 | copy_file_1.copyFile(typeof entry === 'string' ? entry : entry.path, dest);
|
---|
43 | if (process.platform !== 'win32') {
|
---|
44 | // The cache writes entries as readonly and when using copyFile the permissions will also be copied.
|
---|
45 | // See: https://github.com/npm/cacache/blob/073fbe1a9f789ba42d9a41de7b8429c93cf61579/lib/util/move-file.js#L36
|
---|
46 | fs.chmodSync(dest, 0o644);
|
---|
47 | }
|
---|
48 | }
|
---|
49 | generateIntegrityValue(content) {
|
---|
50 | const algorithm = this.integrityAlgorithm || 'sha1';
|
---|
51 | const codeHash = crypto_1.createHash(algorithm).update(content).digest('base64');
|
---|
52 | return `${algorithm}-${codeHash}`;
|
---|
53 | }
|
---|
54 | generateBaseCacheKey(content) {
|
---|
55 | // Create base cache key with elements:
|
---|
56 | // * package version - different build-angular versions cause different final outputs
|
---|
57 | // * code length/hash - ensure cached version matches the same input code
|
---|
58 | const integrity = this.generateIntegrityValue(content);
|
---|
59 | let baseCacheKey = `${packageVersion}|${content.length}|${integrity}`;
|
---|
60 | if (!environment_options_1.allowMangle) {
|
---|
61 | baseCacheKey += '|MD';
|
---|
62 | }
|
---|
63 | return baseCacheKey;
|
---|
64 | }
|
---|
65 | generateCacheKeys(action) {
|
---|
66 | // Postfix added to sourcemap cache keys when vendor, hidden sourcemaps are present
|
---|
67 | // Allows non-destructive caching of both variants
|
---|
68 | const sourceMapVendorPostfix = action.sourceMaps && action.vendorSourceMaps ? '|vendor' : '';
|
---|
69 | // sourceMappingURL is added at the very end which causes the code to be the same when sourcemaps are enabled/disabled
|
---|
70 | // When using hiddenSourceMaps we can omit the postfix since sourceMappingURL will not be added.
|
---|
71 | // When having sourcemaps a hashed file and non hashed file can have the same content. But the sourceMappingURL will differ.
|
---|
72 | const sourceMapPostFix = action.sourceMaps && !action.hiddenSourceMaps ? `|sourcemap|${action.filename}` : '';
|
---|
73 | const baseCacheKey = this.generateBaseCacheKey(action.code);
|
---|
74 | // Determine cache entries required based on build settings
|
---|
75 | const cacheKeys = [];
|
---|
76 | // If optimizing and the original is not ignored, add original as required
|
---|
77 | if (!action.ignoreOriginal) {
|
---|
78 | cacheKeys[0 /* OriginalCode */] = baseCacheKey + sourceMapPostFix + '|orig';
|
---|
79 | // If sourcemaps are enabled, add original sourcemap as required
|
---|
80 | if (action.sourceMaps) {
|
---|
81 | cacheKeys[1 /* OriginalMap */] = baseCacheKey + sourceMapVendorPostfix + '|orig-map';
|
---|
82 | }
|
---|
83 | }
|
---|
84 | // If not only optimizing, add downlevel as required
|
---|
85 | if (!action.optimizeOnly) {
|
---|
86 | cacheKeys[2 /* DownlevelCode */] = baseCacheKey + sourceMapPostFix + '|dl';
|
---|
87 | // If sourcemaps are enabled, add downlevel sourcemap as required
|
---|
88 | if (action.sourceMaps) {
|
---|
89 | cacheKeys[3 /* DownlevelMap */] = baseCacheKey + sourceMapVendorPostfix + '|dl-map';
|
---|
90 | }
|
---|
91 | }
|
---|
92 | return cacheKeys;
|
---|
93 | }
|
---|
94 | async getCacheEntries(cacheKeys) {
|
---|
95 | // Attempt to get required cache entries
|
---|
96 | const cacheEntries = [];
|
---|
97 | for (const key of cacheKeys) {
|
---|
98 | if (key) {
|
---|
99 | const entry = await cacache.get.info(this.cachePath, key);
|
---|
100 | if (!entry) {
|
---|
101 | return false;
|
---|
102 | }
|
---|
103 | cacheEntries.push({
|
---|
104 | path: entry.path,
|
---|
105 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
---|
106 | size: entry.size,
|
---|
107 | integrity: entry.metadata && entry.metadata.integrity,
|
---|
108 | });
|
---|
109 | }
|
---|
110 | else {
|
---|
111 | cacheEntries.push(null);
|
---|
112 | }
|
---|
113 | }
|
---|
114 | return cacheEntries;
|
---|
115 | }
|
---|
116 | async getCachedBundleResult(action) {
|
---|
117 | const entries = action.cacheKeys && (await this.getCacheEntries(action.cacheKeys));
|
---|
118 | if (!entries) {
|
---|
119 | return null;
|
---|
120 | }
|
---|
121 | const result = {
|
---|
122 | name: action.name,
|
---|
123 | integrity: this.generateIntegrityValue(action.code),
|
---|
124 | };
|
---|
125 | let cacheEntry = entries[0 /* OriginalCode */];
|
---|
126 | if (cacheEntry) {
|
---|
127 | result.original = {
|
---|
128 | filename: action.filename,
|
---|
129 | size: cacheEntry.size,
|
---|
130 | integrity: cacheEntry.integrity,
|
---|
131 | };
|
---|
132 | BundleActionCache.copyEntryContent(cacheEntry, result.original.filename);
|
---|
133 | cacheEntry = entries[1 /* OriginalMap */];
|
---|
134 | if (cacheEntry) {
|
---|
135 | result.original.map = {
|
---|
136 | filename: action.filename + '.map',
|
---|
137 | size: cacheEntry.size,
|
---|
138 | };
|
---|
139 | BundleActionCache.copyEntryContent(cacheEntry, result.original.filename + '.map');
|
---|
140 | }
|
---|
141 | }
|
---|
142 | else if (!action.ignoreOriginal) {
|
---|
143 | // If the original wasn't processed (and therefore not cached), add info
|
---|
144 | result.original = {
|
---|
145 | filename: action.filename,
|
---|
146 | size: Buffer.byteLength(action.code, 'utf8'),
|
---|
147 | map: action.map === undefined
|
---|
148 | ? undefined
|
---|
149 | : {
|
---|
150 | filename: action.filename + '.map',
|
---|
151 | size: Buffer.byteLength(action.map, 'utf8'),
|
---|
152 | },
|
---|
153 | };
|
---|
154 | }
|
---|
155 | cacheEntry = entries[2 /* DownlevelCode */];
|
---|
156 | if (cacheEntry) {
|
---|
157 | result.downlevel = {
|
---|
158 | filename: action.filename.replace(/\-(es20\d{2}|esnext)/, '-es5'),
|
---|
159 | size: cacheEntry.size,
|
---|
160 | integrity: cacheEntry.integrity,
|
---|
161 | };
|
---|
162 | BundleActionCache.copyEntryContent(cacheEntry, result.downlevel.filename);
|
---|
163 | cacheEntry = entries[3 /* DownlevelMap */];
|
---|
164 | if (cacheEntry) {
|
---|
165 | result.downlevel.map = {
|
---|
166 | filename: action.filename.replace(/\-(es20\d{2}|esnext)/, '-es5') + '.map',
|
---|
167 | size: cacheEntry.size,
|
---|
168 | };
|
---|
169 | BundleActionCache.copyEntryContent(cacheEntry, result.downlevel.filename + '.map');
|
---|
170 | }
|
---|
171 | }
|
---|
172 | return result;
|
---|
173 | }
|
---|
174 | }
|
---|
175 | exports.BundleActionCache = BundleActionCache;
|
---|