@e-mc/document 0.0.1
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 +11 -0
- package/README.md +5 -0
- package/android/document.d.ts +66 -0
- package/android/extensions/app/manifest/index.js +186 -0
- package/android/extensions/gradle/dependencies/index.js +212 -0
- package/android/extensions/gradle/settings/index.js +82 -0
- package/android/extensions/task/index.js +110 -0
- package/android/index.d.ts +7 -0
- package/android/index.js +217 -0
- package/android/template/AndroidManifest.xml +23 -0
- package/android/template/java/build.gradle +39 -0
- package/android/template/java/settings.gradle +18 -0
- package/android/template/java+kotlin/build.gradle +44 -0
- package/android/template/java+kotlin/settings.gradle +18 -0
- package/android/template/kotlin/build.gradle.kts +46 -0
- package/android/template/kotlin/settings.gradle.kts +18 -0
- package/asset.d.ts +8 -0
- package/asset.js +11 -0
- package/chrome/document.d.ts +119 -0
- package/chrome/index.d.ts +7 -0
- package/chrome/index.js +3546 -0
- package/index.d.ts +5 -0
- package/index.js +1296 -0
- package/package.json +31 -0
- package/parse/document.d.ts +237 -0
- package/parse/dom.d.ts +9 -0
- package/parse/dom.js +256 -0
- package/parse/index.d.ts +9 -0
- package/parse/index.js +1452 -0
- package/transform/index.d.ts +8 -0
- package/transform/index.js +310 -0
- package/util.d.ts +16 -0
- package/util.js +191 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Copyright 2023 An Pham
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
|
|
7
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
|
|
9
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
+
|
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { FinalizedElement } from '../../types/lib/squared';
|
|
2
|
+
import type { DocumentOutput } from '../../types/lib/android';
|
|
3
|
+
|
|
4
|
+
import type { DocumentConstructor, IDocument, IFileManager } from '../../types/lib';
|
|
5
|
+
import type { ExternalAsset } from '../../types/lib/asset';
|
|
6
|
+
import type { DocumentDirectory as IDocumentDirectory, DocumentModule as IDocumentModule } from '../../types/lib/settings';
|
|
7
|
+
|
|
8
|
+
interface DocumentDirectory extends IDocumentDirectory {
|
|
9
|
+
template?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface AndroidDocumentSettings extends PlainObject {
|
|
13
|
+
extensions?: {
|
|
14
|
+
task?: {
|
|
15
|
+
command?: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
language?: {
|
|
19
|
+
gradle?: "java" | "kotlin" | "java+kotlin";
|
|
20
|
+
};
|
|
21
|
+
directory?: DocumentDirectory;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type LanguageType = "gradle";
|
|
25
|
+
type DocumentProperties = "targetAPI" | "elements" | "extensionData" | "directories";
|
|
26
|
+
|
|
27
|
+
export interface UserConfig extends Omit<DocumentOutput, DocumentProperties> {
|
|
28
|
+
mainParentDir: string;
|
|
29
|
+
mainSrcDir: string;
|
|
30
|
+
mainActivityFile: string;
|
|
31
|
+
javaVersion: number;
|
|
32
|
+
dataBinding: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface DocumentModule extends IDocumentModule {
|
|
36
|
+
settings?: AndroidDocumentSettings;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface TemplateData {
|
|
40
|
+
localUri?: string;
|
|
41
|
+
source?: string;
|
|
42
|
+
existing?: boolean;
|
|
43
|
+
kotlin?: boolean;
|
|
44
|
+
language?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface FindTemplateOptions {
|
|
48
|
+
detect?: boolean;
|
|
49
|
+
languageOf?: LanguageType;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface IAndroidDocument<T extends IFileManager<U>, U extends DocumentAsset = DocumentAsset> extends IDocument<T, U>, Pick<DocumentOutput, DocumentProperties> {
|
|
53
|
+
config: UserConfig;
|
|
54
|
+
elements: FinalizedElement[];
|
|
55
|
+
extensionData: PlainObject;
|
|
56
|
+
findTemplate(baseDir: string, filename: string, options?: FindTemplateOptions): TemplateData;
|
|
57
|
+
detectKts(...paths: string[]): Null<boolean>;
|
|
58
|
+
get settings(): AndroidDocumentSettings;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface AndroidDocumentConstructor<T extends IFileManager<U>, U extends DocumentAsset = DocumentAsset> extends DocumentConstructor<T, U> {
|
|
62
|
+
readonly prototype: IAndroidDocument<T, U>;
|
|
63
|
+
new(module?: DocumentModule, ...args: unknown[]): IAndroidDocument<T, U>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type DocumentAsset = ExternalAsset;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const htmlparser2 = require("htmlparser2");
|
|
5
|
+
const domhandler = require("domhandler");
|
|
6
|
+
const domutils = require("domutils");
|
|
7
|
+
const domserializer = require("dom-serializer");
|
|
8
|
+
const util_1 = require("../../../../util");
|
|
9
|
+
const types_1 = require("../../../../../types");
|
|
10
|
+
const Parser = htmlparser2.Parser;
|
|
11
|
+
const DomHandler = domhandler.DomHandler;
|
|
12
|
+
function finalize(instance) {
|
|
13
|
+
const config = instance.config;
|
|
14
|
+
if (!config.manifest) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let { localUri, source, existing } = instance.findTemplate(path.join(this.baseDirectory, config.mainParentDir, config.mainSrcDir), "AndroidManifest.xml" /* MANIFEST.FILENAME */, { detect: !this.archiving });
|
|
18
|
+
if (localUri && source && instance.canWrite(localUri, { ownPermissionOnly: true })) {
|
|
19
|
+
const { package: manifestPackage, application = {} } = config.manifest;
|
|
20
|
+
const { supportsRtl, label, theme, activity, metaData = [], activityName, fontProvider } = application;
|
|
21
|
+
const profileable = config.profileable;
|
|
22
|
+
let modified;
|
|
23
|
+
if (!existing) {
|
|
24
|
+
source = (0, util_1.replaceAll)(source.replace(manifestPackage ? '{{package}}' : ' package="{{package}}"', manifestPackage || ''), (name) => {
|
|
25
|
+
switch (name) {
|
|
26
|
+
case 'supportsRtl':
|
|
27
|
+
return supportsRtl === false ? 'false' : 'true';
|
|
28
|
+
case 'label':
|
|
29
|
+
return '@string/' + (label || 'app_name');
|
|
30
|
+
case 'theme':
|
|
31
|
+
return theme ? '@style/' + theme : '';
|
|
32
|
+
case 'activityName':
|
|
33
|
+
return activityName || '';
|
|
34
|
+
case 'profileable':
|
|
35
|
+
return profileable ? 'true' : 'false';
|
|
36
|
+
default:
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else if (manifestPackage || theme || activityName || activity || supportsRtl !== undefined) {
|
|
42
|
+
new Parser(new DomHandler((err, dom) => {
|
|
43
|
+
if (err) {
|
|
44
|
+
instance.writeFail(['Unable to parse XML document', "AndroidManifest.xml" /* MANIFEST.FILENAME */], err, 0 /* LOG_TYPE.UNKNOWN */);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let target = null;
|
|
48
|
+
if (manifestPackage && (target = domutils.findOne(elem => elem.tagName === 'manifest', dom, true))) {
|
|
49
|
+
target.attribs['package'] = manifestPackage;
|
|
50
|
+
modified = true;
|
|
51
|
+
}
|
|
52
|
+
if (target = domutils.findOne(elem => elem.tagName === 'application', dom, true)) {
|
|
53
|
+
if (label) {
|
|
54
|
+
target.attribs['android:label'] = '@string/' + label;
|
|
55
|
+
modified = true;
|
|
56
|
+
}
|
|
57
|
+
if (theme) {
|
|
58
|
+
target.attribs['android:theme'] = '@style/' + theme;
|
|
59
|
+
modified = true;
|
|
60
|
+
}
|
|
61
|
+
if (supportsRtl !== undefined) {
|
|
62
|
+
target.attribs['android:supportsRtl'] = supportsRtl.toString();
|
|
63
|
+
modified = true;
|
|
64
|
+
}
|
|
65
|
+
if (activityName || activity) {
|
|
66
|
+
const activities = domutils.getElementsByTagName('activity', target, true);
|
|
67
|
+
if (activityName) {
|
|
68
|
+
for (const item of activities) {
|
|
69
|
+
const intentFilter = domutils.findAll(elem => elem.tagName === 'intent-filter', [item]);
|
|
70
|
+
if (intentFilter.length) {
|
|
71
|
+
const action = domutils.findOne(elem => elem.tagName === 'action' && elem.attribs['android:name'] === 'android.intent.action.MAIN', intentFilter);
|
|
72
|
+
if (action) {
|
|
73
|
+
const attribs = item.attribs;
|
|
74
|
+
attribs['android:name'] = activityName;
|
|
75
|
+
attribs['android:exported'] = 'true';
|
|
76
|
+
modified = true;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (activity) {
|
|
83
|
+
for (const name in activity) {
|
|
84
|
+
const { layout: attribs } = activity[name];
|
|
85
|
+
if (attribs) {
|
|
86
|
+
let element = domutils.findOne(elem => elem.attribs['android:name'] === name, activities);
|
|
87
|
+
if (!element) {
|
|
88
|
+
domutils.appendChild(target, element = new domhandler.Element('activity', { 'android:name': name }));
|
|
89
|
+
domutils.append(element, new domhandler.Text('\n'));
|
|
90
|
+
}
|
|
91
|
+
let layout = domutils.findOne(elem => elem.tagName === 'layout', [element]), found = true;
|
|
92
|
+
if (!layout) {
|
|
93
|
+
domutils.appendChild(element, layout = new domhandler.Element('layout', {}));
|
|
94
|
+
domutils.append(layout, new domhandler.Text('\n'));
|
|
95
|
+
found = false;
|
|
96
|
+
}
|
|
97
|
+
for (const attr in attribs) {
|
|
98
|
+
switch (attr) {
|
|
99
|
+
case 'defaultHeight':
|
|
100
|
+
case 'defaultWidth':
|
|
101
|
+
case 'minHeight':
|
|
102
|
+
case 'minWidth':
|
|
103
|
+
case 'gravity': {
|
|
104
|
+
const value = attribs[attr];
|
|
105
|
+
if (!found || layout.attribs['android:' + attr] !== value) {
|
|
106
|
+
layout.attribs['android:' + attr] = value;
|
|
107
|
+
modified = true;
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (profileable !== undefined) {
|
|
118
|
+
const attribs = profileable ? { 'android:shell': 'true', 'android:enabled': 'true' } : { 'android:enabled': 'false' };
|
|
119
|
+
const element = domutils.findOne(elem => elem.tagName === 'profileable', [target]);
|
|
120
|
+
if (element) {
|
|
121
|
+
Object.assign(element.attribs, attribs);
|
|
122
|
+
}
|
|
123
|
+
else if (profileable) {
|
|
124
|
+
domutils.appendChild(target, new domhandler.Element('profileable', attribs));
|
|
125
|
+
domutils.appendChild(target, new domhandler.Text('\n'));
|
|
126
|
+
}
|
|
127
|
+
modified = true;
|
|
128
|
+
}
|
|
129
|
+
if (modified) {
|
|
130
|
+
source = domserializer.default(dom, { xmlMode: true });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}), { xmlMode: true, decodeEntities: false }).end(source);
|
|
134
|
+
}
|
|
135
|
+
if (fontProvider) {
|
|
136
|
+
metaData.push({ name: 'preloaded_fonts', resource: '@array/' + fontProvider });
|
|
137
|
+
}
|
|
138
|
+
if ((0, types_1.isArray)(metaData)) {
|
|
139
|
+
new Parser(new DomHandler((err, dom) => {
|
|
140
|
+
if (err) {
|
|
141
|
+
instance.writeFail(['Unable to parse XML document', "AndroidManifest.xml" /* MANIFEST.FILENAME */], err, 0 /* LOG_TYPE.UNKNOWN */);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const app = domutils.findOne(elem => elem.tagName === 'application', dom, true);
|
|
145
|
+
if (app) {
|
|
146
|
+
for (const { name, resource, value } of metaData) {
|
|
147
|
+
if (name && (resource || value)) {
|
|
148
|
+
let item = domutils.findOne(elem => elem.tagName === 'meta-data' && elem.attribs['android:name'] === name, app.childNodes);
|
|
149
|
+
if (!item) {
|
|
150
|
+
domutils.appendChild(app, item = new domhandler.Element('meta-data', { 'android:name': name }));
|
|
151
|
+
domutils.append(item, new domhandler.Text('\n'));
|
|
152
|
+
}
|
|
153
|
+
else if (item.attribs['android:resource'] === resource || item.attribs['android:value'] === value) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (resource) {
|
|
157
|
+
item.attribs['android:resource'] = resource;
|
|
158
|
+
}
|
|
159
|
+
if (value) {
|
|
160
|
+
item.attribs['android:value'] = value;
|
|
161
|
+
}
|
|
162
|
+
source = domserializer.default(dom, { xmlMode: true });
|
|
163
|
+
modified = true;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}), { xmlMode: true, decodeEntities: false }).end(source);
|
|
168
|
+
}
|
|
169
|
+
if (modified || !existing) {
|
|
170
|
+
try {
|
|
171
|
+
if (instance.writeFile(localUri, source, { encoding: 'utf-8', ownPermissionOnly: true, throwsPermission: true }) && !existing) {
|
|
172
|
+
this.add(localUri);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
this.writeFail(["Unable to write file" /* ERR_MESSAGE.WRITE_FILE */, path.basename(localUri)], err, 8192 /* LOG_TYPE.PERMISSION */);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.default = finalize;
|
|
182
|
+
|
|
183
|
+
if (exports.default) {
|
|
184
|
+
module.exports = exports.default;
|
|
185
|
+
module.exports.default = exports.default;
|
|
186
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const util_1 = require("../../../../util");
|
|
5
|
+
const types_1 = require("../../../../../types");
|
|
6
|
+
const index_1 = require("../../../../index");
|
|
7
|
+
function finalize(instance) {
|
|
8
|
+
const config = instance.config;
|
|
9
|
+
const { profileable, dependencies, dataBinding, versionName, versionCode } = config;
|
|
10
|
+
if (!profileable && !dependencies && !dataBinding && !versionName && !versionCode && !config.namespace) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let { localUri, source, existing, kotlin } = instance.findTemplate(path.join(this.baseDirectory, config.mainParentDir), 'build.gradle', { detect: !this.archiving, languageOf: 'gradle' });
|
|
14
|
+
if (localUri && source && instance.canWrite(localUri, { ownPermissionOnly: true })) {
|
|
15
|
+
let { namespace, javaVersion } = config, jvmTarget, modified;
|
|
16
|
+
const upgrade = javaVersion > 0;
|
|
17
|
+
const setModified = (output) => {
|
|
18
|
+
if (output !== source) {
|
|
19
|
+
source = output;
|
|
20
|
+
modified = true;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
if (dependencies) {
|
|
24
|
+
const items = dependencies.map(item => item.split(':'));
|
|
25
|
+
if (!kotlin && items.some(value => value[1].endsWith('-ktx'))) {
|
|
26
|
+
setModified(index_1.default.updateGradle(source, ['plugins'], "id 'kotlin-android'", { multiple: true }));
|
|
27
|
+
}
|
|
28
|
+
const match = /dependencies\s+\{([^}]+)\}/.exec(source);
|
|
29
|
+
if (match) {
|
|
30
|
+
const writeImpl = (item) => 'implementation' + (kotlin ? `("${item.join(':')}")` : ` '${item.join(':')}'`);
|
|
31
|
+
const pattern = kotlin ? /([ \t]*)implementation\((?:\s*"([^"]+)"\s*\))?/g : /([ \t]*)implementation(?:\s*\(?\s*["']([^"']+)["']\s*\)?|\s+((?:\s*(?:group|name|version)\s*:\s*["'][^"']+["']\s*,?){3}))?/g;
|
|
32
|
+
let content = match[1], indent, impl;
|
|
33
|
+
while (impl = pattern.exec(match[1])) {
|
|
34
|
+
let group, name, version;
|
|
35
|
+
if (impl[2]) {
|
|
36
|
+
[group, name, version] = impl[2].trim().split(/\s*:\s*/);
|
|
37
|
+
}
|
|
38
|
+
else if (impl[3]) {
|
|
39
|
+
const method = /(group|name|version)\s*:\s*["']([^"']+)["']/g;
|
|
40
|
+
let param;
|
|
41
|
+
while (param = method.exec(impl[3])) {
|
|
42
|
+
const value = param[2].trim();
|
|
43
|
+
switch (param[1]) {
|
|
44
|
+
case 'group':
|
|
45
|
+
group = value;
|
|
46
|
+
break;
|
|
47
|
+
case 'name':
|
|
48
|
+
name = value;
|
|
49
|
+
break;
|
|
50
|
+
case 'version':
|
|
51
|
+
version = value;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (group && name) {
|
|
57
|
+
let found = 0, index = -1;
|
|
58
|
+
if (version) {
|
|
59
|
+
index = items.findIndex(seg => seg[0] === group && seg[1] === name);
|
|
60
|
+
if (index !== -1) {
|
|
61
|
+
found = 1;
|
|
62
|
+
if (version[0] !== '$' || !kotlin && impl[0].indexOf("'") !== -1) {
|
|
63
|
+
const current = items[index][2].split('.').map(seg => +seg);
|
|
64
|
+
const parts = version.split('.');
|
|
65
|
+
for (let i = 0, value; i < parts.length; ++i) {
|
|
66
|
+
if (isNaN(value = +parts[i]) || +current[i] > value) {
|
|
67
|
+
found = 2;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (found) {
|
|
75
|
+
if (found === 2) {
|
|
76
|
+
content = content.replace(impl[0].trim(), writeImpl(items[index]));
|
|
77
|
+
modified = true;
|
|
78
|
+
}
|
|
79
|
+
items.splice(index, 1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (impl[1]) {
|
|
83
|
+
indent = impl[1];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (items.length) {
|
|
87
|
+
indent || (indent = (0, util_1.getIndent)(source));
|
|
88
|
+
content = items.reduce((a, b) => a + indent + writeImpl(b) + '\n', content);
|
|
89
|
+
modified = true;
|
|
90
|
+
}
|
|
91
|
+
if (modified || !existing) {
|
|
92
|
+
setModified(source.substring(0, match.index) + `dependencies {${content}}` + source.substring(match.index + match[0].length));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (items.some(value => value[0] === 'androidx.compose.ui')) {
|
|
96
|
+
let output = source;
|
|
97
|
+
if (kotlin) {
|
|
98
|
+
output = index_1.default.updateGradle(output, ['plugins'], 'kotlin("android")');
|
|
99
|
+
output = index_1.default.updateGradle(output, ['android', 'buildFeatures'], 'compose = true');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
output = index_1.default.updateGradle(output, ['plugins'], "id 'org.jetbrains.kotlin.android'", { upgrade: true, multiple: true, addendum: `version '${instance.findVersion('org.jetbrains.kotlin:kotlin-stdlib', "1.8.10" /* VERSIONS.KOTLIN_STDLIB */)}'` });
|
|
103
|
+
output = index_1.default.updateGradle(output, ['android', 'buildFeatures'], "compose true");
|
|
104
|
+
output = index_1.default.updateGradle(output, ['android', 'composeOptions'], `kotlinCompilerExtensionVersion '${instance.findVersion('kotlinCompilerExtensionVersion', "1.4.3" /* VERSIONS.KOTLIN_COMPILER */)}'`, true);
|
|
105
|
+
if (upgrade) {
|
|
106
|
+
output = index_1.default.updateGradle(output, ['android', 'kotlinOptions'], `jvmTarget = '${javaVersion}'`, true);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
output = index_1.default.updateGradle(output, ['android', 'kotlinOptions'], "jvmTarget = '1.8'");
|
|
110
|
+
jvmTarget = '1_8';
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
setModified(output);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (upgrade || jvmTarget) {
|
|
117
|
+
const compatibility = 'JavaVersion.VERSION_' + (upgrade ? javaVersion.toString().replace(/\./g, '_') : jvmTarget);
|
|
118
|
+
let output = source;
|
|
119
|
+
if (kotlin) {
|
|
120
|
+
output = index_1.default.updateGradle(output, ['java'], 'sourceCompatibility = ' + compatibility, upgrade);
|
|
121
|
+
output = index_1.default.updateGradle(output, ['java'], 'targetCompatibility = ' + compatibility, upgrade);
|
|
122
|
+
output = index_1.default.updateGradle(output, ['android', 'kotlinOptions'], `jvmTarget = "${javaVersion}"`, upgrade);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
output = index_1.default.updateGradle(output, ['android', 'compileOptions'], 'sourceCompatibility ' + compatibility, upgrade);
|
|
126
|
+
output = index_1.default.updateGradle(output, ['android', 'compileOptions'], 'targetCompatibility ' + compatibility, upgrade);
|
|
127
|
+
}
|
|
128
|
+
setModified(output);
|
|
129
|
+
}
|
|
130
|
+
if (!existing) {
|
|
131
|
+
const targetAPI = instance.targetAPI;
|
|
132
|
+
let output = source;
|
|
133
|
+
if (targetAPI) {
|
|
134
|
+
const values = typeof targetAPI === 'string' ? [`"android-${targetAPI}"`, `"${targetAPI}"`] : [targetAPI, targetAPI];
|
|
135
|
+
const updateOnly = +targetAPI >= 31;
|
|
136
|
+
let revised = index_1.default.updateGradle(output, ['android'], kotlin ? `compileSdkVersion(${values[0]})` : 'compileSdkVersion ' + values[0], { upgrade: true, updateOnly });
|
|
137
|
+
if (revised === output) {
|
|
138
|
+
output = index_1.default.updateGradle(output, ['android'], kotlin ? `compileSdk(${values[0]})` : 'compileSdk ' + values[0], true);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
output = revised;
|
|
142
|
+
}
|
|
143
|
+
revised = index_1.default.updateGradle(output, ['android', 'defaultConfig'], kotlin ? `targetSdkVersion(${values[1]})` : 'targetSdkVersion ' + values[1], { upgrade: true, updateOnly });
|
|
144
|
+
if (revised === output) {
|
|
145
|
+
output = index_1.default.updateGradle(output, ['android', 'defaultConfig'], kotlin ? `targetSdk(${values[1]})` : 'targetSdk ' + values[1], true);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
output = revised;
|
|
149
|
+
}
|
|
150
|
+
const version = instance.findVersion('buildToolsVersion');
|
|
151
|
+
if (version) {
|
|
152
|
+
output = index_1.default.updateGradle(output, ['android'], kotlin ? `buildToolsVersion = "${version}"` : `buildToolsVersion "${version}"`, true);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (namespace || (namespace = config.manifest?.package)) {
|
|
156
|
+
output = index_1.default.updateGradle(output, ['android', 'defaultConfig'], (kotlin ? 'applicationId = ' : 'applicationId ') + `"${namespace}"`, true);
|
|
157
|
+
}
|
|
158
|
+
setModified(output);
|
|
159
|
+
}
|
|
160
|
+
if (dataBinding) {
|
|
161
|
+
setModified(index_1.default.updateGradle(source, ['android', 'buildFeatures'], kotlin ? 'dataBinding = true' : 'dataBinding true', true));
|
|
162
|
+
}
|
|
163
|
+
if (namespace) {
|
|
164
|
+
setModified(index_1.default.updateGradle(source, ['android'], (kotlin ? 'namespace = ' : 'namespace ') + `"${namespace}"`, true));
|
|
165
|
+
}
|
|
166
|
+
if (profileable) {
|
|
167
|
+
let name, items;
|
|
168
|
+
if (Array.isArray(profileable)) {
|
|
169
|
+
if (profileable.length && !profileable[0].startsWith('--')) {
|
|
170
|
+
name = profileable.shift();
|
|
171
|
+
}
|
|
172
|
+
items = profileable;
|
|
173
|
+
}
|
|
174
|
+
else if (typeof profileable === 'string') {
|
|
175
|
+
if (profileable.startsWith('--')) {
|
|
176
|
+
items = [profileable];
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
name = profileable;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
name || (name = 'debug');
|
|
183
|
+
setModified(index_1.default.updateGradle(source, ['android', 'buildTypes', kotlin ? 'getByName("release")' : 'release'], 'signingConfig ' + (kotlin ? `= signingConfigs.getByName("${name}")` : 'signingConfigs.' + name), true));
|
|
184
|
+
if ((0, types_1.isArray)(items)) {
|
|
185
|
+
const parameters = items.map(value => `"${value}"`).join(', ');
|
|
186
|
+
setModified(index_1.default.updateGradle(source, ['android', 'aaptOptions'], 'additionalParameters ' + (kotlin ? `= [${parameters}]` : parameters), true));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (versionName) {
|
|
190
|
+
setModified(index_1.default.updateGradle(source, ['android', 'defaultConfig'], (kotlin ? 'versionName = ' : 'versionName ') + `"${versionName}"`, true));
|
|
191
|
+
}
|
|
192
|
+
if (versionCode) {
|
|
193
|
+
setModified(index_1.default.updateGradle(source, ['android', 'defaultConfig'], (kotlin ? 'versionCode = ' : 'versionCode ') + versionCode, true));
|
|
194
|
+
}
|
|
195
|
+
if (modified || !existing) {
|
|
196
|
+
try {
|
|
197
|
+
if (instance.writeFile(localUri, source, { encoding: 'utf-8', ownPermissionOnly: true, throwsPermission: true }) && !existing) {
|
|
198
|
+
this.add(localUri);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
this.writeFail(["Unable to write file" /* ERR_MESSAGE.WRITE_FILE */, path.basename(localUri)], err, 8192 /* LOG_TYPE.PERMISSION */);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
exports.default = finalize;
|
|
208
|
+
|
|
209
|
+
if (exports.default) {
|
|
210
|
+
module.exports = exports.default;
|
|
211
|
+
module.exports.default = exports.default;
|
|
212
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const util_1 = require("../../../../util");
|
|
5
|
+
const parse_1 = require("../../../../parse");
|
|
6
|
+
function finalize(instance) {
|
|
7
|
+
const { dependencies, projectName, mainParentDir } = instance.config;
|
|
8
|
+
if (!dependencies && !projectName) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
let { localUri, source, existing, kotlin } = instance.findTemplate(this.baseDirectory, 'settings.gradle', { detect: !this.archiving, languageOf: 'gradle' });
|
|
12
|
+
if (localUri && source && instance.canWrite(localUri, { ownPermissionOnly: true })) {
|
|
13
|
+
const targetName = projectName ? projectName.replace(/"/g, '\\"') : '';
|
|
14
|
+
let modified;
|
|
15
|
+
if (existing) {
|
|
16
|
+
let match;
|
|
17
|
+
if (dependencies) {
|
|
18
|
+
found: {
|
|
19
|
+
const pattern = kotlin ? /^\s*include\(((?:\s*"[^"]+"\s*,?\s*)+)\)/gm : /^\s*include\s*((?:(?:"[^"]+"|'[^']+')\s*,?\s*)+)/gm;
|
|
20
|
+
while (match = pattern.exec(source)) {
|
|
21
|
+
const namespace = /":?([^"]+)"|':?([^']+)'/g;
|
|
22
|
+
let app;
|
|
23
|
+
while (app = namespace.exec(match[1])) {
|
|
24
|
+
if (app[1] === mainParentDir || app[2] === mainParentDir) {
|
|
25
|
+
break found;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
pattern.lastIndex = 0;
|
|
30
|
+
if (match = pattern.exec(source)) {
|
|
31
|
+
const index = match.index + match[0].length;
|
|
32
|
+
if (kotlin) {
|
|
33
|
+
source = source.substring(0, index - 1).trimEnd() + `, "${mainParentDir}")` + source.substring(index);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
source = parse_1.XmlWriter.replaceMatch(match, source, `, '${mainParentDir}'`, { trimLeading: true });
|
|
37
|
+
}
|
|
38
|
+
modified = true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (targetName) {
|
|
43
|
+
const value = `rootProject.name = "${targetName}"`;
|
|
44
|
+
if (match = new RegExp('^\\s*rootProject\\.name\\s*=\\s*' + parse_1.XmlWriter.PATTERN_QUOTEVALUE, 'm').exec(source)) {
|
|
45
|
+
source = parse_1.XmlWriter.replaceMatch(match, source, value);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
source += (0, util_1.getNewline)(source) + value;
|
|
49
|
+
}
|
|
50
|
+
modified = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
source = (0, util_1.replaceAll)(source, (name) => {
|
|
55
|
+
switch (name) {
|
|
56
|
+
case 'projectName':
|
|
57
|
+
return targetName;
|
|
58
|
+
case 'name':
|
|
59
|
+
return ':' + mainParentDir;
|
|
60
|
+
default:
|
|
61
|
+
return '';
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (modified || !existing) {
|
|
66
|
+
try {
|
|
67
|
+
if (instance.writeFile(localUri, source, { encoding: 'utf-8', ownPermissionOnly: true, throwsPermission: true }) && !existing) {
|
|
68
|
+
this.add(localUri);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
this.writeFail(["Unable to write file" /* ERR_MESSAGE.WRITE_FILE */, path.basename(localUri)], err, 8192 /* LOG_TYPE.PERMISSION */);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.default = finalize;
|
|
78
|
+
|
|
79
|
+
if (exports.default) {
|
|
80
|
+
module.exports = exports.default;
|
|
81
|
+
module.exports.default = exports.default;
|
|
82
|
+
}
|