react-native-legal 1.0.0-next.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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/ReactNativeLegal.podspec +46 -0
  4. package/android/build.gradle +75 -0
  5. package/android/react-native-helpers.gradle +45 -0
  6. package/android/src/main/java/com/reactnativelegal/ReactNativeLegalActivity.kt +98 -0
  7. package/android/src/main/java/com/reactnativelegal/ReactNativeLegalModuleImpl.kt +19 -0
  8. package/android/src/main/java/com/reactnativelegal/ReactNativeLegalTurboPackage.kt +38 -0
  9. package/android/src/main/res/layout/activity_licenses.xml +28 -0
  10. package/android/src/main/res/values/styles.xml +7 -0
  11. package/android/src/main/res/values-v29/styles.xml +8 -0
  12. package/android/src/newarch/java/com/reactnativelegal/ReactNativeLegalModule.kt +17 -0
  13. package/android/src/oldarch/java/com/reactnativelegal/ReactNativeLegalModule.kt +23 -0
  14. package/app.plugin.js +1 -0
  15. package/bare-plugin/build/android/addListActivity.d.ts +4 -0
  16. package/bare-plugin/build/android/addListActivity.js +22 -0
  17. package/bare-plugin/build/android/androidCommand.d.ts +7 -0
  18. package/bare-plugin/build/android/androidCommand.js +25 -0
  19. package/bare-plugin/build/android/applyAndConfigureAboutLibrariesPlugin.d.ts +6 -0
  20. package/bare-plugin/build/android/applyAndConfigureAboutLibrariesPlugin.js +27 -0
  21. package/bare-plugin/build/android/declareAboutLibrariesPlugin.d.ts +6 -0
  22. package/bare-plugin/build/android/declareAboutLibrariesPlugin.js +27 -0
  23. package/bare-plugin/build/android/utils.d.ts +14 -0
  24. package/bare-plugin/build/android/utils.js +37 -0
  25. package/bare-plugin/build/index.d.ts +2 -0
  26. package/bare-plugin/build/index.js +9 -0
  27. package/bare-plugin/build/ios/addSettingsBundle.d.ts +4 -0
  28. package/bare-plugin/build/ios/addSettingsBundle.js +27 -0
  29. package/bare-plugin/build/ios/iosCommand.d.ts +7 -0
  30. package/bare-plugin/build/ios/iosCommand.js +23 -0
  31. package/bare-plugin/build/ios/registerLicensePlistBuildPhase.d.ts +7 -0
  32. package/bare-plugin/build/ios/registerLicensePlistBuildPhase.js +24 -0
  33. package/bare-plugin/build/ios/utils.d.ts +33 -0
  34. package/bare-plugin/build/ios/utils.js +98 -0
  35. package/bare-plugin/src/android/addListActivity.ts +22 -0
  36. package/bare-plugin/src/android/androidCommand.ts +23 -0
  37. package/bare-plugin/src/android/applyAndConfigureAboutLibrariesPlugin.ts +21 -0
  38. package/bare-plugin/src/android/declareAboutLibrariesPlugin.ts +21 -0
  39. package/bare-plugin/src/android/utils.ts +34 -0
  40. package/bare-plugin/src/index.ts +9 -0
  41. package/bare-plugin/src/ios/addSettingsBundle.ts +27 -0
  42. package/bare-plugin/src/ios/iosCommand.ts +21 -0
  43. package/bare-plugin/src/ios/registerLicensePlistBuildPhase.ts +22 -0
  44. package/bare-plugin/src/ios/utils.ts +120 -0
  45. package/bare-plugin/tsconfig.json +20 -0
  46. package/ios/ReactNativeLegal-Bridging-Header.h +1 -0
  47. package/ios/ReactNativeLegalDetailViewController.swift +156 -0
  48. package/ios/ReactNativeLegalLicenseMetadata.swift +4 -0
  49. package/ios/ReactNativeLegalModule.h +7 -0
  50. package/ios/ReactNativeLegalModule.mm +29 -0
  51. package/ios/ReactNativeLegalModuleImpl.swift +78 -0
  52. package/ios/ReactNativeLegalTableViewController.swift +72 -0
  53. package/lib/commonjs/NativeReactNativeLegal.js +10 -0
  54. package/lib/commonjs/NativeReactNativeLegal.js.map +1 -0
  55. package/lib/commonjs/ReactNativeLegal.android.js +18 -0
  56. package/lib/commonjs/ReactNativeLegal.android.js.map +1 -0
  57. package/lib/commonjs/ReactNativeLegal.ios.js +18 -0
  58. package/lib/commonjs/ReactNativeLegal.ios.js.map +1 -0
  59. package/lib/commonjs/ReactNativeLegal.js +13 -0
  60. package/lib/commonjs/ReactNativeLegal.js.map +1 -0
  61. package/lib/commonjs/index.js +13 -0
  62. package/lib/commonjs/index.js.map +1 -0
  63. package/lib/module/NativeReactNativeLegal.js +3 -0
  64. package/lib/module/NativeReactNativeLegal.js.map +1 -0
  65. package/lib/module/ReactNativeLegal.android.js +10 -0
  66. package/lib/module/ReactNativeLegal.android.js.map +1 -0
  67. package/lib/module/ReactNativeLegal.ios.js +10 -0
  68. package/lib/module/ReactNativeLegal.ios.js.map +1 -0
  69. package/lib/module/ReactNativeLegal.js +6 -0
  70. package/lib/module/ReactNativeLegal.js.map +1 -0
  71. package/lib/module/index.js +2 -0
  72. package/lib/module/index.js.map +1 -0
  73. package/lib/typescript/NativeReactNativeLegal.d.ts +7 -0
  74. package/lib/typescript/NativeReactNativeLegal.d.ts.map +1 -0
  75. package/lib/typescript/ReactNativeLegal.android.d.ts +4 -0
  76. package/lib/typescript/ReactNativeLegal.android.d.ts.map +1 -0
  77. package/lib/typescript/ReactNativeLegal.d.ts +4 -0
  78. package/lib/typescript/ReactNativeLegal.d.ts.map +1 -0
  79. package/lib/typescript/ReactNativeLegal.ios.d.ts +4 -0
  80. package/lib/typescript/ReactNativeLegal.ios.d.ts.map +1 -0
  81. package/lib/typescript/index.d.ts +2 -0
  82. package/lib/typescript/index.d.ts.map +1 -0
  83. package/package.json +97 -0
  84. package/plugin/build/android/addListActivity.d.ts +5 -0
  85. package/plugin/build/android/addListActivity.js +17 -0
  86. package/plugin/build/android/applyAndConfigureAboutLibrariesPlugin.d.ts +7 -0
  87. package/plugin/build/android/applyAndConfigureAboutLibrariesPlugin.js +22 -0
  88. package/plugin/build/android/declareAboutLibrariesPlugin.d.ts +7 -0
  89. package/plugin/build/android/declareAboutLibrariesPlugin.js +22 -0
  90. package/plugin/build/android/withAndroidLegal.d.ts +8 -0
  91. package/plugin/build/android/withAndroidLegal.js +30 -0
  92. package/plugin/build/index.d.ts +3 -0
  93. package/plugin/build/index.js +11 -0
  94. package/plugin/build/ios/addSettingsBundle.d.ts +5 -0
  95. package/plugin/build/ios/addSettingsBundle.js +28 -0
  96. package/plugin/build/ios/registerLicensePlistBuildPhase.d.ts +8 -0
  97. package/plugin/build/ios/registerLicensePlistBuildPhase.js +23 -0
  98. package/plugin/build/ios/withIosLegal.d.ts +8 -0
  99. package/plugin/build/ios/withIosLegal.js +28 -0
  100. package/plugin/jest.config.js +1 -0
  101. package/plugin/src/android/addListActivity.ts +19 -0
  102. package/plugin/src/android/applyAndConfigureAboutLibrariesPlugin.ts +23 -0
  103. package/plugin/src/android/declareAboutLibrariesPlugin.ts +21 -0
  104. package/plugin/src/android/withAndroidLegal.ts +28 -0
  105. package/plugin/src/index.ts +14 -0
  106. package/plugin/src/ios/addSettingsBundle.ts +29 -0
  107. package/plugin/src/ios/registerLicensePlistBuildPhase.ts +24 -0
  108. package/plugin/src/ios/withIosLegal.ts +26 -0
  109. package/plugin/tsconfig.json +9 -0
  110. package/plugin-utils/build/android.d.ts +12 -0
  111. package/plugin-utils/build/android.js +91 -0
  112. package/plugin-utils/build/common.d.ts +45 -0
  113. package/plugin-utils/build/common.js +312 -0
  114. package/plugin-utils/build/ios.d.ts +11 -0
  115. package/plugin-utils/build/ios.js +86 -0
  116. package/plugin-utils/src/android.ts +99 -0
  117. package/plugin-utils/src/common.ts +398 -0
  118. package/plugin-utils/src/ios.ts +102 -0
  119. package/plugin-utils/tsconfig.json +20 -0
  120. package/react-native.config.js +13 -0
  121. package/src/NativeReactNativeLegal.ts +8 -0
  122. package/src/ReactNativeLegal.android.ts +10 -0
  123. package/src/ReactNativeLegal.ios.ts +10 -0
  124. package/src/ReactNativeLegal.ts +5 -0
  125. package/src/index.ts +1 -0
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.declareAboutLibrariesPlugin = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const android_1 = require("../../../plugin-utils/build/android");
10
+ const utils_1 = require("./utils");
11
+ /**
12
+ * Modifies root build.gradle with a declaration for AboutLibraries Gradle plugin
13
+ *
14
+ * NOTE: As of now, it doesn't support build.gradle.kts (Gradle Kotlin Script)
15
+ */
16
+ function declareAboutLibrariesPlugin(androidProjectPath) {
17
+ if (fs_1.default.existsSync(path_1.default.join(androidProjectPath, 'build.gradle.kts'))) {
18
+ console.warn('Gradle Kotlin scripts are not supported yet');
19
+ }
20
+ else if (fs_1.default.existsSync(path_1.default.join(androidProjectPath, 'build.gradle'))) {
21
+ (0, utils_1.modifyFileContent)(path_1.default.join(androidProjectPath, 'build.gradle'), android_1.declareAboutLibrariesPluginUtil);
22
+ }
23
+ else {
24
+ console.warn('Cannot find build.gradle file');
25
+ }
26
+ }
27
+ exports.declareAboutLibrariesPlugin = declareAboutLibrariesPlugin;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Used to modify a file at a specified file path
3
+ *
4
+ * It provides the file content as a utf-8 string inside a callback parameter.
5
+ * The modified result should be returned from a callback parameter as a utf-8 string
6
+ */
7
+ export declare function modifyFileContent(filepath: string, transformFile: (fileContent: string) => string): void;
8
+ /**
9
+ * Used to modify a XML file at a specified file path
10
+ *
11
+ * It provides XML content parsed to a JS object inside a callback parameter
12
+ * The modified result should be a JS object returned from a callback parameter
13
+ */
14
+ export declare function modifyXMLFileContent(filepath: string, transformXMLFile: (xmlObj: any) => any): Promise<void>;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.modifyXMLFileContent = exports.modifyFileContent = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const xml2js_1 = __importDefault(require("xml2js"));
9
+ /**
10
+ * Used to modify a file at a specified file path
11
+ *
12
+ * It provides the file content as a utf-8 string inside a callback parameter.
13
+ * The modified result should be returned from a callback parameter as a utf-8 string
14
+ */
15
+ function modifyFileContent(filepath, transformFile) {
16
+ const content = fs_1.default.readFileSync(filepath, { encoding: 'utf-8' });
17
+ const modifiedContent = transformFile(content);
18
+ fs_1.default.writeFileSync(filepath, modifiedContent);
19
+ }
20
+ exports.modifyFileContent = modifyFileContent;
21
+ /**
22
+ * Used to modify a XML file at a specified file path
23
+ *
24
+ * It provides XML content parsed to a JS object inside a callback parameter
25
+ * The modified result should be a JS object returned from a callback parameter
26
+ */
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ async function modifyXMLFileContent(filepath, transformXMLFile) {
29
+ const content = fs_1.default.readFileSync(filepath, { encoding: 'utf-8' });
30
+ const parser = new xml2js_1.default.Parser();
31
+ const obj = await parser.parseStringPromise(content);
32
+ const modifiedObj = transformXMLFile(obj);
33
+ const builder = new xml2js_1.default.Builder({ headless: true });
34
+ const modifiedContent = builder.buildObject(modifiedObj);
35
+ fs_1.default.writeFileSync(filepath, modifiedContent);
36
+ }
37
+ exports.modifyXMLFileContent = modifyXMLFileContent;
@@ -0,0 +1,2 @@
1
+ declare function generateLegal(androidProjectPath: string, iosProjectPath: string): void;
2
+ export default generateLegal;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const androidCommand_1 = require("./android/androidCommand");
4
+ const iosCommand_1 = require("./ios/iosCommand");
5
+ function generateLegal(androidProjectPath, iosProjectPath) {
6
+ (0, androidCommand_1.androidCommand)(androidProjectPath);
7
+ (0, iosCommand_1.iosCommand)(iosProjectPath);
8
+ }
9
+ exports.default = generateLegal;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Creates a Settings.bundle and links it to all application native targets
3
+ */
4
+ export declare function addSettingsBundle(iosProjectPath: string): void;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addSettingsBundle = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const ios_1 = require("../../../plugin-utils/build/ios");
9
+ const utils_1 = require("./utils");
10
+ /**
11
+ * Creates a Settings.bundle and links it to all application native targets
12
+ */
13
+ function addSettingsBundle(iosProjectPath) {
14
+ (0, ios_1.addSettingsBundleUtil)(iosProjectPath, ({ settingsBundleFilename }) => {
15
+ const projectName = (0, utils_1.getIOSProjectName)(iosProjectPath);
16
+ const { pbxproj, pbxprojPath } = (0, utils_1.getIOSPbxProj)(iosProjectPath);
17
+ const settingsBundleFile = pbxproj.addFile(settingsBundleFilename, pbxproj.findPBXGroupKey({ name: projectName }));
18
+ if (!settingsBundleFile) {
19
+ throw new Error('Could not add Settings.bundle file reference to xcode project');
20
+ }
21
+ settingsBundleFile.uuid = pbxproj.generateUuid();
22
+ pbxproj.addToPbxBuildFileSection(settingsBundleFile);
23
+ (0, utils_1.addToAllPbxResourcesBuildPhases)(pbxproj, settingsBundleFile);
24
+ fs_1.default.writeFileSync(pbxprojPath, pbxproj.writeSync());
25
+ });
26
+ }
27
+ exports.addSettingsBundle = addSettingsBundle;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Implementation of bare plugin's iOS/tvOS setup
3
+ *
4
+ * It scans the NPM dependencies, generates LicensePlist-compatible metadata for them,
5
+ * configures Settings.bundle and registers a shell script generating LicensePlist metadata for iOS dependencies
6
+ */
7
+ export declare function iosCommand(iosProjectPath: string): void;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.iosCommand = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const common_1 = require("../../../plugin-utils/build/common");
9
+ const addSettingsBundle_1 = require("./addSettingsBundle");
10
+ const registerLicensePlistBuildPhase_1 = require("./registerLicensePlistBuildPhase");
11
+ /**
12
+ * Implementation of bare plugin's iOS/tvOS setup
13
+ *
14
+ * It scans the NPM dependencies, generates LicensePlist-compatible metadata for them,
15
+ * configures Settings.bundle and registers a shell script generating LicensePlist metadata for iOS dependencies
16
+ */
17
+ function iosCommand(iosProjectPath) {
18
+ const licenses = (0, common_1.scanDependencies)(path_1.default.join(path_1.default.resolve(iosProjectPath, '..'), 'package.json'));
19
+ (0, common_1.generateLicensePlistNPMOutput)(licenses, iosProjectPath);
20
+ (0, addSettingsBundle_1.addSettingsBundle)(iosProjectPath);
21
+ (0, registerLicensePlistBuildPhase_1.registerLicensePlistBuildPhase)(iosProjectPath);
22
+ }
23
+ exports.iosCommand = iosCommand;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Registers a shell script that invokes generation of license metadata with LicensePlist
3
+ *
4
+ * It scans available application native targets and for each of them
5
+ * creates and links a shell script build phase responsible for iOS native deps license metadata
6
+ */
7
+ export declare function registerLicensePlistBuildPhase(iosProjectPath: string): void;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerLicensePlistBuildPhase = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const ios_1 = require("../../../plugin-utils/build/ios");
9
+ const utils_1 = require("./utils");
10
+ /**
11
+ * Registers a shell script that invokes generation of license metadata with LicensePlist
12
+ *
13
+ * It scans available application native targets and for each of them
14
+ * creates and links a shell script build phase responsible for iOS native deps license metadata
15
+ */
16
+ function registerLicensePlistBuildPhase(iosProjectPath) {
17
+ const { pbxproj, pbxprojPath } = (0, utils_1.getIOSPbxProj)(iosProjectPath);
18
+ const nativeTargets = (0, utils_1.getAllApplicationNativeTargets)(pbxproj);
19
+ nativeTargets.map((nativeTarget) => {
20
+ (0, ios_1.registerLicensePlistBuildPhaseUtil)(nativeTarget.uuid, pbxproj);
21
+ });
22
+ fs_1.default.writeFileSync(pbxprojPath, pbxproj.writeSync());
23
+ }
24
+ exports.registerLicensePlistBuildPhase = registerLicensePlistBuildPhase;
@@ -0,0 +1,33 @@
1
+ import type { XcodeProject } from 'xcode';
2
+ import xcode from 'xcode';
3
+ /**
4
+ * Used to obtain first target of type "com.apple.product-type.application"
5
+ */
6
+ export declare function getFirstApplicationNativeTarget(pbxproj: XcodeProject): {
7
+ uuid: string;
8
+ target: xcode.PBXNativeTarget;
9
+ } | null;
10
+ /**
11
+ * Used to get all targets of type "com.apple.product-type.application"
12
+ */
13
+ export declare function getAllApplicationNativeTargets(pbxproj: XcodeProject): {
14
+ uuid: string;
15
+ target: xcode.PBXNativeTarget;
16
+ }[];
17
+ /**
18
+ * Used to add the file to all "Resources" build phases
19
+ *
20
+ * It's very handy especially when we have multiple application targets and each of them has separate "Resources" build phase
21
+ */
22
+ export declare function addToAllPbxResourcesBuildPhases(pbxproj: XcodeProject, pbxFile: pbxFile): void;
23
+ /**
24
+ * Returns the name of the main group in the project (the main folder where `AppDelegate` usually lives)
25
+ */
26
+ export declare function getIOSProjectName(iosProjectPath: string): string;
27
+ /**
28
+ * Used to grab the XcodeProject instance
29
+ */
30
+ export declare function getIOSPbxProj(iosProjectPath: string): {
31
+ pbxproj: XcodeProject;
32
+ pbxprojPath: string;
33
+ };
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getIOSPbxProj = exports.getIOSProjectName = exports.addToAllPbxResourcesBuildPhases = exports.getAllApplicationNativeTargets = exports.getFirstApplicationNativeTarget = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const xcode_1 = __importDefault(require("xcode"));
9
+ const glob = require('glob');
10
+ const ignoredPaths = ['**/@(Carthage|Pods|vendor|node_modules)/**'];
11
+ /**
12
+ * Used to obtain first target of type "com.apple.product-type.application"
13
+ */
14
+ function getFirstApplicationNativeTarget(pbxproj) {
15
+ return pbxproj.getTarget('com.apple.product-type.application');
16
+ }
17
+ exports.getFirstApplicationNativeTarget = getFirstApplicationNativeTarget;
18
+ /**
19
+ * Used to get all targets of type "com.apple.product-type.application"
20
+ */
21
+ function getAllApplicationNativeTargets(pbxproj) {
22
+ const targets = pbxproj.getFirstProject().firstProject.targets;
23
+ const nativeTargets = pbxproj.pbxNativeTargetSection();
24
+ return targets.reduce((acc, target) => {
25
+ const targetUuid = target.value;
26
+ if (nativeTargets[targetUuid].productType === '"com.apple.product-type.application"') {
27
+ return [...acc, { uuid: targetUuid, target: nativeTargets[targetUuid] }];
28
+ }
29
+ return acc;
30
+ }, []);
31
+ }
32
+ exports.getAllApplicationNativeTargets = getAllApplicationNativeTargets;
33
+ /**
34
+ * Used to add the file to all "Resources" build phases
35
+ *
36
+ * It's very handy especially when we have multiple application targets and each of them has separate "Resources" build phase
37
+ */
38
+ function addToAllPbxResourcesBuildPhases(pbxproj, pbxFile) {
39
+ getAllApplicationNativeTargets(pbxproj).map((nativeTarget) => {
40
+ nativeTarget.target.buildPhases.map((buildPhase) => {
41
+ if (buildPhase.comment !== RESOURCES_BUILD_PHASE_IDENTIFIER) {
42
+ return;
43
+ }
44
+ const section = pbxproj.hash.project.objects['PBXResourcesBuildPhase'];
45
+ const buildPhaseKey = buildPhase.value + '_comment';
46
+ for (const key in section) {
47
+ if (!COMMENT_KEY.test(key) || (buildPhaseKey && buildPhaseKey !== key)) {
48
+ continue;
49
+ }
50
+ if (typeof section[key] === 'string' && section[key] === RESOURCES_BUILD_PHASE_IDENTIFIER) {
51
+ const sectionKey = key.split(COMMENT_KEY)[0];
52
+ const sources = section[sectionKey];
53
+ if (typeof sources === 'object') {
54
+ sources.files.push({
55
+ value: pbxFile.uuid,
56
+ comment: `${pbxFile.basename} in ${pbxFile.group}`,
57
+ });
58
+ pbxproj.hash.project.objects['PBXResourcesBuildPhase'][sectionKey] = sources;
59
+ }
60
+ }
61
+ }
62
+ });
63
+ });
64
+ }
65
+ exports.addToAllPbxResourcesBuildPhases = addToAllPbxResourcesBuildPhases;
66
+ /**
67
+ * Returns the name of the main group in the project (the main folder where `AppDelegate` usually lives)
68
+ */
69
+ function getIOSProjectName(iosProjectPath) {
70
+ const [appDelegatePath] = glob.sync('*/AppDelegate.@(m|mm|swift)', {
71
+ cwd: iosProjectPath,
72
+ absolute: true,
73
+ nocase: true,
74
+ nodir: true,
75
+ ignore: ignoredPaths,
76
+ });
77
+ return path_1.default.basename(path_1.default.dirname(appDelegatePath));
78
+ }
79
+ exports.getIOSProjectName = getIOSProjectName;
80
+ /**
81
+ * Used to grab the XcodeProject instance
82
+ */
83
+ function getIOSPbxProj(iosProjectPath) {
84
+ const [xcodeprojPath] = glob.sync('*.xcodeproj', {
85
+ cwd: iosProjectPath,
86
+ absolute: true,
87
+ nocase: true,
88
+ nodir: false,
89
+ ignore: ignoredPaths,
90
+ });
91
+ const pbxprojPath = path_1.default.join(xcodeprojPath, 'project.pbxproj');
92
+ const pbxproj = xcode_1.default.project(pbxprojPath);
93
+ pbxproj.parseSync();
94
+ return { pbxproj, pbxprojPath };
95
+ }
96
+ exports.getIOSPbxProj = getIOSPbxProj;
97
+ const RESOURCES_BUILD_PHASE_IDENTIFIER = 'Resources';
98
+ const COMMENT_KEY = /_comment$/;
@@ -0,0 +1,22 @@
1
+ import path from 'path';
2
+
3
+ import { addListActivityUtil } from '../../../plugin-utils/build/android';
4
+
5
+ import { modifyXMLFileContent } from './utils';
6
+
7
+ /**
8
+ * Adds an Android Activity with list of dependencies and their licenses to project's AndroidManifest.xml
9
+ */
10
+ export async function addListActivity(androidProjectPath: string) {
11
+ const androidManifestPath = path.join(androidProjectPath, 'app', 'src', 'main', 'AndroidManifest.xml');
12
+
13
+ await modifyXMLFileContent(androidManifestPath, (manifestObj) => {
14
+ if (manifestObj.manifest.application?.[0].activity) {
15
+ manifestObj.manifest.application[0].activity = addListActivityUtil(
16
+ manifestObj.manifest.application?.[0].activity,
17
+ );
18
+ }
19
+
20
+ return manifestObj;
21
+ });
22
+ }
@@ -0,0 +1,23 @@
1
+ import path from 'path';
2
+
3
+ import { generateAboutLibrariesNPMOutput, scanDependencies } from '../../../plugin-utils/build/common';
4
+
5
+ import { addListActivity } from './addListActivity';
6
+ import { applyAndConfigureAboutLibrariesPlugin } from './applyAndConfigureAboutLibrariesPlugin';
7
+ import { declareAboutLibrariesPlugin } from './declareAboutLibrariesPlugin';
8
+
9
+ /**
10
+ * Implementation of bare plugin's Android/Android TV setup
11
+ *
12
+ * It scans the NPM dependencies, generates AboutLibraries-compatible metadata for them,
13
+ * installs & configures AboutLibraries Gradle plugin and adds Android Activity with a list of dependencies and their licenses
14
+ */
15
+ export function androidCommand(androidProjectPath: string) {
16
+ const licenses = scanDependencies(path.join(path.resolve(androidProjectPath, '..'), 'package.json'));
17
+
18
+ generateAboutLibrariesNPMOutput(licenses, androidProjectPath);
19
+
20
+ declareAboutLibrariesPlugin(androidProjectPath);
21
+ applyAndConfigureAboutLibrariesPlugin(androidProjectPath);
22
+ addListActivity(androidProjectPath);
23
+ }
@@ -0,0 +1,21 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ import { applyAndConfigureAboutLibrariesPluginUtil } from '../../../plugin-utils/build/android';
5
+
6
+ import { modifyFileContent } from './utils';
7
+
8
+ /**
9
+ * Modifies application's build.gradle with AboutLibraries plugin
10
+ *
11
+ * NOTE: As of now, it doesn't support build.gradle.kts (Gradle Kotlin Script)
12
+ */
13
+ export function applyAndConfigureAboutLibrariesPlugin(androidProjectPath: string) {
14
+ if (fs.existsSync(path.join(androidProjectPath, 'app', 'build.gradle.kts'))) {
15
+ console.warn('Gradle Kotlin scripts are not supported yet');
16
+ } else if (fs.existsSync(path.join(androidProjectPath, 'app', 'build.gradle'))) {
17
+ modifyFileContent(path.join(androidProjectPath, 'app', 'build.gradle'), applyAndConfigureAboutLibrariesPluginUtil);
18
+ } else {
19
+ console.warn('Cannot find app/build.gradle file');
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ import { declareAboutLibrariesPluginUtil } from '../../../plugin-utils/build/android';
5
+
6
+ import { modifyFileContent } from './utils';
7
+
8
+ /**
9
+ * Modifies root build.gradle with a declaration for AboutLibraries Gradle plugin
10
+ *
11
+ * NOTE: As of now, it doesn't support build.gradle.kts (Gradle Kotlin Script)
12
+ */
13
+ export function declareAboutLibrariesPlugin(androidProjectPath: string) {
14
+ if (fs.existsSync(path.join(androidProjectPath, 'build.gradle.kts'))) {
15
+ console.warn('Gradle Kotlin scripts are not supported yet');
16
+ } else if (fs.existsSync(path.join(androidProjectPath, 'build.gradle'))) {
17
+ modifyFileContent(path.join(androidProjectPath, 'build.gradle'), declareAboutLibrariesPluginUtil);
18
+ } else {
19
+ console.warn('Cannot find build.gradle file');
20
+ }
21
+ }
@@ -0,0 +1,34 @@
1
+ import fs from 'fs';
2
+
3
+ import xml2js from 'xml2js';
4
+
5
+ /**
6
+ * Used to modify a file at a specified file path
7
+ *
8
+ * It provides the file content as a utf-8 string inside a callback parameter.
9
+ * The modified result should be returned from a callback parameter as a utf-8 string
10
+ */
11
+ export function modifyFileContent(filepath: string, transformFile: (fileContent: string) => string) {
12
+ const content = fs.readFileSync(filepath, { encoding: 'utf-8' });
13
+ const modifiedContent = transformFile(content);
14
+
15
+ fs.writeFileSync(filepath, modifiedContent);
16
+ }
17
+
18
+ /**
19
+ * Used to modify a XML file at a specified file path
20
+ *
21
+ * It provides XML content parsed to a JS object inside a callback parameter
22
+ * The modified result should be a JS object returned from a callback parameter
23
+ */
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ export async function modifyXMLFileContent(filepath: string, transformXMLFile: (xmlObj: any) => any) {
26
+ const content = fs.readFileSync(filepath, { encoding: 'utf-8' });
27
+ const parser = new xml2js.Parser();
28
+ const obj = await parser.parseStringPromise(content);
29
+ const modifiedObj = transformXMLFile(obj);
30
+ const builder = new xml2js.Builder({ headless: true });
31
+ const modifiedContent = builder.buildObject(modifiedObj);
32
+
33
+ fs.writeFileSync(filepath, modifiedContent);
34
+ }
@@ -0,0 +1,9 @@
1
+ import { androidCommand } from './android/androidCommand';
2
+ import { iosCommand } from './ios/iosCommand';
3
+
4
+ function generateLegal(androidProjectPath: string, iosProjectPath: string) {
5
+ androidCommand(androidProjectPath);
6
+ iosCommand(iosProjectPath);
7
+ }
8
+
9
+ export default generateLegal;
@@ -0,0 +1,27 @@
1
+ import fs from 'fs';
2
+
3
+ import { addSettingsBundleUtil } from '../../../plugin-utils/build/ios';
4
+
5
+ import { addToAllPbxResourcesBuildPhases, getIOSPbxProj, getIOSProjectName } from './utils';
6
+
7
+ /**
8
+ * Creates a Settings.bundle and links it to all application native targets
9
+ */
10
+ export function addSettingsBundle(iosProjectPath: string) {
11
+ addSettingsBundleUtil(iosProjectPath, ({ settingsBundleFilename }) => {
12
+ const projectName = getIOSProjectName(iosProjectPath);
13
+ const { pbxproj, pbxprojPath } = getIOSPbxProj(iosProjectPath);
14
+ const settingsBundleFile = pbxproj.addFile(settingsBundleFilename, pbxproj.findPBXGroupKey({ name: projectName }));
15
+
16
+ if (!settingsBundleFile) {
17
+ throw new Error('Could not add Settings.bundle file reference to xcode project');
18
+ }
19
+
20
+ settingsBundleFile.uuid = pbxproj.generateUuid();
21
+
22
+ pbxproj.addToPbxBuildFileSection(settingsBundleFile);
23
+ addToAllPbxResourcesBuildPhases(pbxproj, settingsBundleFile);
24
+
25
+ fs.writeFileSync(pbxprojPath, pbxproj.writeSync());
26
+ });
27
+ }
@@ -0,0 +1,21 @@
1
+ import path from 'path';
2
+
3
+ import { generateLicensePlistNPMOutput, scanDependencies } from '../../../plugin-utils/build/common';
4
+
5
+ import { addSettingsBundle } from './addSettingsBundle';
6
+ import { registerLicensePlistBuildPhase } from './registerLicensePlistBuildPhase';
7
+
8
+ /**
9
+ * Implementation of bare plugin's iOS/tvOS setup
10
+ *
11
+ * It scans the NPM dependencies, generates LicensePlist-compatible metadata for them,
12
+ * configures Settings.bundle and registers a shell script generating LicensePlist metadata for iOS dependencies
13
+ */
14
+ export function iosCommand(iosProjectPath: string) {
15
+ const licenses = scanDependencies(path.join(path.resolve(iosProjectPath, '..'), 'package.json'));
16
+
17
+ generateLicensePlistNPMOutput(licenses, iosProjectPath);
18
+
19
+ addSettingsBundle(iosProjectPath);
20
+ registerLicensePlistBuildPhase(iosProjectPath);
21
+ }
@@ -0,0 +1,22 @@
1
+ import fs from 'fs';
2
+
3
+ import { registerLicensePlistBuildPhaseUtil } from '../../../plugin-utils/build/ios';
4
+
5
+ import { getAllApplicationNativeTargets, getIOSPbxProj } from './utils';
6
+
7
+ /**
8
+ * Registers a shell script that invokes generation of license metadata with LicensePlist
9
+ *
10
+ * It scans available application native targets and for each of them
11
+ * creates and links a shell script build phase responsible for iOS native deps license metadata
12
+ */
13
+ export function registerLicensePlistBuildPhase(iosProjectPath: string) {
14
+ const { pbxproj, pbxprojPath } = getIOSPbxProj(iosProjectPath);
15
+ const nativeTargets = getAllApplicationNativeTargets(pbxproj);
16
+
17
+ nativeTargets.map((nativeTarget) => {
18
+ registerLicensePlistBuildPhaseUtil(nativeTarget.uuid, pbxproj);
19
+ });
20
+
21
+ fs.writeFileSync(pbxprojPath, pbxproj.writeSync());
22
+ }
@@ -0,0 +1,120 @@
1
+ import path from 'path';
2
+
3
+ import type { XcodeProject } from 'xcode';
4
+ import xcode from 'xcode';
5
+
6
+ const glob = require('glob');
7
+
8
+ const ignoredPaths = ['**/@(Carthage|Pods|vendor|node_modules)/**'];
9
+
10
+ /**
11
+ * Used to obtain first target of type "com.apple.product-type.application"
12
+ */
13
+ export function getFirstApplicationNativeTarget(pbxproj: XcodeProject) {
14
+ return pbxproj.getTarget('com.apple.product-type.application');
15
+ }
16
+
17
+ /**
18
+ * Used to get all targets of type "com.apple.product-type.application"
19
+ */
20
+ export function getAllApplicationNativeTargets(pbxproj: XcodeProject) {
21
+ const targets = pbxproj.getFirstProject().firstProject.targets;
22
+ const nativeTargets = pbxproj.pbxNativeTargetSection();
23
+
24
+ return targets.reduce(
25
+ (acc, target) => {
26
+ const targetUuid = target.value;
27
+
28
+ if (nativeTargets[targetUuid].productType === '"com.apple.product-type.application"') {
29
+ return [...acc, { uuid: targetUuid, target: nativeTargets[targetUuid] }];
30
+ }
31
+
32
+ return acc;
33
+ },
34
+ [] as {
35
+ uuid: string;
36
+ target: xcode.PBXNativeTarget;
37
+ }[],
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Used to add the file to all "Resources" build phases
43
+ *
44
+ * It's very handy especially when we have multiple application targets and each of them has separate "Resources" build phase
45
+ */
46
+ export function addToAllPbxResourcesBuildPhases(pbxproj: XcodeProject, pbxFile: pbxFile) {
47
+ getAllApplicationNativeTargets(pbxproj).map((nativeTarget) => {
48
+ nativeTarget.target.buildPhases.map((buildPhase) => {
49
+ if (buildPhase.comment !== RESOURCES_BUILD_PHASE_IDENTIFIER) {
50
+ return;
51
+ }
52
+
53
+ const section: Record<
54
+ string,
55
+ | {
56
+ [key: string]: any;
57
+ isa: 'PBXResourcesBuildPhase';
58
+ name: string;
59
+ }
60
+ | string
61
+ > = pbxproj.hash.project.objects['PBXResourcesBuildPhase'];
62
+ const buildPhaseKey = buildPhase.value + '_comment';
63
+
64
+ for (const key in section) {
65
+ if (!COMMENT_KEY.test(key) || (buildPhaseKey && buildPhaseKey !== key)) {
66
+ continue;
67
+ }
68
+
69
+ if (typeof section[key] === 'string' && section[key] === RESOURCES_BUILD_PHASE_IDENTIFIER) {
70
+ const sectionKey = key.split(COMMENT_KEY)[0];
71
+ const sources = section[sectionKey];
72
+
73
+ if (typeof sources === 'object') {
74
+ sources.files.push({
75
+ value: pbxFile.uuid,
76
+ comment: `${pbxFile.basename} in ${pbxFile.group}`,
77
+ });
78
+ pbxproj.hash.project.objects['PBXResourcesBuildPhase'][sectionKey] = sources;
79
+ }
80
+ }
81
+ }
82
+ });
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Returns the name of the main group in the project (the main folder where `AppDelegate` usually lives)
88
+ */
89
+ export function getIOSProjectName(iosProjectPath: string) {
90
+ const [appDelegatePath] = glob.sync('*/AppDelegate.@(m|mm|swift)', {
91
+ cwd: iosProjectPath,
92
+ absolute: true,
93
+ nocase: true,
94
+ nodir: true,
95
+ ignore: ignoredPaths,
96
+ });
97
+
98
+ return path.basename(path.dirname(appDelegatePath));
99
+ }
100
+
101
+ /**
102
+ * Used to grab the XcodeProject instance
103
+ */
104
+ export function getIOSPbxProj(iosProjectPath: string) {
105
+ const [xcodeprojPath] = glob.sync('*.xcodeproj', {
106
+ cwd: iosProjectPath,
107
+ absolute: true,
108
+ nocase: true,
109
+ nodir: false,
110
+ ignore: ignoredPaths,
111
+ });
112
+ const pbxprojPath = path.join(xcodeprojPath, 'project.pbxproj');
113
+ const pbxproj = xcode.project(pbxprojPath);
114
+
115
+ pbxproj.parseSync();
116
+ return { pbxproj, pbxprojPath };
117
+ }
118
+
119
+ const RESOURCES_BUILD_PHASE_IDENTIFIER = 'Resources';
120
+ const COMMENT_KEY = /_comment$/;