1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const path_1 = tslib_1.__importDefault(require("path"));
|
5 | const stream_1 = require("stream");
|
6 | const t = tslib_1.__importStar(require("io-ts"));
|
7 | const PathReporter_1 = require("io-ts/lib/PathReporter");
|
8 | const pipeable_1 = require("fp-ts/lib/pipeable");
|
9 | const Either_1 = require("fp-ts/lib/Either");
|
10 | const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
11 | const plugin_error_1 = tslib_1.__importDefault(require("plugin-error"));
|
12 | const vinyl_1 = tslib_1.__importDefault(require("vinyl"));
|
13 | const capabilities_1 = require("./capabilities");
|
14 | const pathUtils_1 = require("./pathUtils");
|
15 | const sdkVersion_1 = require("./sdkVersion");
|
16 | const manifestPath = 'manifest.json';
|
17 | const PLUGIN_NAME = 'appPackageManifest';
|
18 | const ComponentBundleTag = t.taggedUnion('type', [
|
19 | t.intersection([
|
20 | t.interface({
|
21 | type: t.literal('device'),
|
22 | family: t.string,
|
23 | platform: t.array(t.string),
|
24 | }),
|
25 | t.partial({
|
26 | isNative: t.literal(true),
|
27 | }),
|
28 | ]),
|
29 | t.type({
|
30 | type: t.literal('companion'),
|
31 | }),
|
32 | ]);
|
33 | function getBundleInfo(file) {
|
34 | return pipeable_1.pipe(ComponentBundleTag.decode(file.componentBundle), Either_1.fold((errors) => {
|
35 | throw new plugin_error_1.default(PLUGIN_NAME, `Unknown bundle component tag: ${PathReporter_1.failure(errors).join('\n')}`, { fileName: file.relative });
|
36 | }, (tag) => tag));
|
37 | }
|
38 | class AppPackageManifestTransform extends stream_1.Transform {
|
39 | constructor(projectConfig, buildID) {
|
40 | super({ objectMode: true });
|
41 | this.projectConfig = projectConfig;
|
42 | this.buildID = buildID;
|
43 | this.sourceMaps = {};
|
44 | this.components = {};
|
45 | this.hasJS = false;
|
46 | this.hasNative = false;
|
47 | }
|
48 | transformComponentBundle(file) {
|
49 | const bundleInfo = getBundleInfo(file);
|
50 | function throwDuplicateComponent(existingPath) {
|
51 | const componentType = bundleInfo.type === 'device'
|
52 | ? `${bundleInfo.type}/${bundleInfo.family}`
|
53 | : bundleInfo.type;
|
54 | throw new plugin_error_1.default(PLUGIN_NAME, `Duplicate ${componentType} component bundles: ${file.relative} / ${existingPath}`);
|
55 | }
|
56 | if (bundleInfo.type === 'device') {
|
57 | if (bundleInfo.isNative)
|
58 | this.hasNative = true;
|
59 | else
|
60 | this.hasJS = true;
|
61 | if (this.hasJS && this.hasNative) {
|
62 | throw new plugin_error_1.default(PLUGIN_NAME, 'Cannot bundle mixed native/JS device components', { fileName: file.relative });
|
63 | }
|
64 | if (!this.components.watch)
|
65 | this.components.watch = {};
|
66 | if (this.components.watch[bundleInfo.family]) {
|
67 | throwDuplicateComponent(this.components.watch[bundleInfo.family].filename);
|
68 | }
|
69 | const supports = capabilities_1.SupportedDeviceCapabilities.create(bundleInfo.family);
|
70 | this.components.watch[bundleInfo.family] = Object.assign({ platform: bundleInfo.platform, filename: file.relative }, (this.hasJS && supports && { supports }));
|
71 | }
|
72 | else {
|
73 | if (this.components[bundleInfo.type] !== undefined) {
|
74 | throwDuplicateComponent(this.components[bundleInfo.type].filename);
|
75 | }
|
76 | this.components[bundleInfo.type] = { filename: file.relative };
|
77 | }
|
78 | }
|
79 | _transform(file, _, next) {
|
80 | if (file.componentMapKey) {
|
81 | lodash_1.default.merge(this.sourceMaps, lodash_1.default.set({}, file.componentMapKey, pathUtils_1.normalizeToPOSIX(file.relative)));
|
82 | }
|
83 | if (file.componentBundle) {
|
84 | try {
|
85 | this.transformComponentBundle(file);
|
86 | }
|
87 | catch (ex) {
|
88 | return next(ex);
|
89 | }
|
90 | }
|
91 | return next(undefined, file);
|
92 | }
|
93 | _flush(callback) {
|
94 | const setSDKVersion = (this.components.watch && this.hasJS) || this.components.companion;
|
95 | const { deviceApi, companionApi } = sdkVersion_1.apiVersions(this.projectConfig);
|
96 | const manifestJSON = JSON.stringify(Object.assign(Object.assign({ buildId: this.buildID, components: this.components, sourceMaps: this.sourceMaps, manifestVersion: 6 }, (setSDKVersion && {
|
97 | sdkVersion: Object.assign(Object.assign({}, (this.components.watch && this.hasJS && { deviceApi })), (this.components.companion && { companionApi })),
|
98 | })), { requestedPermissions: this.projectConfig.requestedPermissions, appId: this.projectConfig.appUUID }), undefined, 2);
|
99 | this.push(new vinyl_1.default({
|
100 | contents: Buffer.from(manifestJSON, 'utf8'),
|
101 | path: path_1.default.resolve(process.cwd(), manifestPath),
|
102 | }));
|
103 | callback();
|
104 | }
|
105 | }
|
106 | function appPackageManifest({ projectConfig, buildId, }) {
|
107 | return new AppPackageManifestTransform(projectConfig, buildId);
|
108 | }
|
109 | exports.default = appPackageManifest;
|