react-native-legal 1.0.0-next.1 → 1.1.0

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/README.md CHANGED
@@ -4,7 +4,7 @@ Automagically generate license acknowledgements for your React Native app 🚀
4
4
 
5
5
  | Android | iOS | AndroidTV | tvOS |
6
6
  | - | - | - | - |
7
- | ![Android example](./static/android-expo.gif) | ![iOS example](./static/ios-expo.gif) | ![AndroidTV example](./static/android-tv.gif) | ![tvOS example](./static/tvos.gif) |
7
+ | ![Android example](https://github.com/callstackincubator/react-native-legal/raw/main/static/android-expo.gif) | ![iOS example](https://github.com/callstackincubator/react-native-legal/raw/main/static/ios-expo.gif) | ![AndroidTV example](https://github.com/callstackincubator/react-native-legal/raw/main/static/android-tv.gif) | ![tvOS example](https://github.com/callstackincubator/react-native-legal/raw/main/static/tvos.gif) |
8
8
 
9
9
  ## Installation
10
10
 
@@ -55,14 +55,8 @@ repositories {
55
55
  google()
56
56
  }
57
57
 
58
- apply from: "$projectDir/react-native-helpers.gradle"
59
-
60
58
  dependencies {
61
- if (project.ext.shouldConsumeReactNativeFromMavenCentral()) {
62
- implementation "com.facebook.react:react-android" // Set by the React Native Gradle Plugin
63
- } else {
64
- implementation 'com.facebook.react:react-native:+' // From node_modules
65
- }
59
+ implementation "com.facebook.react:react-android" // Set by the React Native Gradle Plugin
66
60
 
67
61
  def aboutLibrariesPluginVersion = "10.8.3"
68
62
  implementation("com.mikepenz:aboutlibraries-core-android:$aboutLibrariesPluginVersion")
@@ -1,6 +1,10 @@
1
1
  #import "ReactNativeLegalModule.h"
2
2
 
3
+ #if __has_include(<ReactNativeLegal/ReactNativeLegal-Swift.h>)
4
+ #import <ReactNativeLegal/ReactNativeLegal-Swift.h>
5
+ #else
3
6
  #import "ReactNativeLegal-Swift.h"
7
+ #endif
4
8
 
5
9
  #if RCT_NEW_ARCH_ENABLED
6
10
  #import "ReactNativeLegal.h"
@@ -1,5 +1,5 @@
1
1
  class ReactNativeLegalTableViewController: UITableViewController {
2
- private let CELL_IDENTIFIER = "OSSNoticeCell"
2
+ private let CELL_IDENTIFIER = "ReactNativeLegalCell"
3
3
 
4
4
  private var data: [ReactNativeLegalLicenseMetadata] = [] {
5
5
  didSet {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-legal",
3
- "version": "1.0.0-next.1",
3
+ "version": "1.1.0",
4
4
  "description": "Acknowledge OSS libraries used in your React Native app",
5
5
  "keywords": [
6
6
  "react-native",
@@ -24,14 +24,13 @@
24
24
  "bugs": {
25
25
  "url": "https://github.com/callstackincubator/react-native-legal/issues"
26
26
  },
27
- "homepage": "https://github.com/callstackincubator/react-native-legal#readme",
27
+ "homepage": "https://callstackincubator.github.io/react-native-legal/",
28
28
  "publishConfig": {
29
29
  "registry": "https://registry.npmjs.org/"
30
30
  },
31
31
  "files": [
32
32
  "android/src",
33
33
  "android/build.gradle",
34
- "android/react-native-helpers.gradle",
35
34
  "bare-plugin",
36
35
  "ios",
37
36
  "lib",
@@ -94,4 +93,4 @@
94
93
  "javaPackageName": "com.reactnativelegal"
95
94
  }
96
95
  }
97
- }
96
+ }
@@ -34,19 +34,23 @@ function arrayIncludesObject(array, object) {
34
34
  }
35
35
  exports.arrayIncludesObject = arrayIncludesObject;
36
36
  /**
37
- * Scans `package.json` and searches for all packages under `dependencies` field. Supports monorepo projects.
37
+ * Scans a single package and its dependencies for license information
38
38
  */
39
- function scanDependencies(appPackageJsonPath) {
40
- const appPackageJson = require(path_1.default.resolve(appPackageJsonPath));
41
- const dependencies = appPackageJson.dependencies;
42
- return Object.keys(dependencies).reduce((acc, dependency) => {
43
- try {
44
- const localPackageJsonPath = getPackageJsonPath(dependency);
45
- if (!localPackageJsonPath) {
46
- console.warn(`[react-native-legal] skipping ${dependency} could not find package.json`);
47
- return acc;
48
- }
49
- const localPackageJson = require(path_1.default.resolve(localPackageJsonPath));
39
+ function scanPackage(packageName, version, processedPackages, result) {
40
+ const packageKey = `${packageName}@${version}`;
41
+ // Skip if already processed to avoid circular dependencies
42
+ if (processedPackages.has(packageKey)) {
43
+ return;
44
+ }
45
+ processedPackages.add(packageKey);
46
+ try {
47
+ const localPackageJsonPath = getPackageJsonPath(packageName);
48
+ if (!localPackageJsonPath) {
49
+ console.warn(`[react-native-legal] skipping ${packageName} could not find package.json`);
50
+ return;
51
+ }
52
+ const localPackageJson = require(path_1.default.resolve(localPackageJsonPath));
53
+ if (localPackageJson.private !== true) {
50
54
  const licenseFiles = glob.sync('LICEN{S,C}E{.md,}', {
51
55
  cwd: path_1.default.dirname(localPackageJsonPath),
52
56
  absolute: true,
@@ -54,7 +58,7 @@ function scanDependencies(appPackageJsonPath) {
54
58
  nodir: true,
55
59
  ignore: '**/{__tests__,__fixtures__,__mocks__}/**',
56
60
  });
57
- acc[dependency] = {
61
+ result[packageName] = {
58
62
  author: parseAuthorField(localPackageJson),
59
63
  content: licenseFiles?.[0] ? fs_1.default.readFileSync(licenseFiles[0], { encoding: 'utf-8' }) : undefined,
60
64
  description: localPackageJson.description,
@@ -63,11 +67,30 @@ function scanDependencies(appPackageJsonPath) {
63
67
  version: localPackageJson.version,
64
68
  };
65
69
  }
66
- catch (error) {
67
- console.warn(`[react-native-legal] could not process package.json for ${dependency}`);
68
- }
69
- return acc;
70
- }, {});
70
+ const dependencies = localPackageJson.dependencies || {};
71
+ const isWorkspacePackage = version.startsWith('workspace:');
72
+ if (!isWorkspacePackage)
73
+ return;
74
+ Object.entries(dependencies).forEach(([depName, depVersion]) => {
75
+ scanPackage(depName, depVersion, processedPackages, result);
76
+ });
77
+ }
78
+ catch (error) {
79
+ console.warn(`[react-native-legal] could not process package.json for ${packageName}`);
80
+ }
81
+ }
82
+ /**
83
+ * Scans `package.json` and searches for all packages under `dependencies` field. Supports monorepo projects.
84
+ */
85
+ function scanDependencies(appPackageJsonPath) {
86
+ const appPackageJson = require(path_1.default.resolve(appPackageJsonPath));
87
+ const dependencies = appPackageJson.dependencies;
88
+ const result = {};
89
+ const processedPackages = new Set();
90
+ Object.entries(dependencies).forEach(([packageName, version]) => {
91
+ scanPackage(packageName, version, processedPackages, result);
92
+ });
93
+ return result;
71
94
  }
72
95
  exports.scanDependencies = scanDependencies;
73
96
  function needsQuoting(value) {
@@ -70,48 +70,81 @@ export function arrayIncludesObject(array?: unknown[], object?: unknown) {
70
70
  return array?.map((item) => compareObjects(item, object)).reduce((acc, curr) => acc || curr, false);
71
71
  }
72
72
 
73
+ /**
74
+ * Scans a single package and its dependencies for license information
75
+ */
76
+ function scanPackage(
77
+ packageName: string,
78
+ version: string,
79
+ processedPackages: Set<string>,
80
+ result: Record<string, LicenseObj>,
81
+ ) {
82
+ const packageKey = `${packageName}@${version}`;
83
+
84
+ // Skip if already processed to avoid circular dependencies
85
+ if (processedPackages.has(packageKey)) {
86
+ return;
87
+ }
88
+
89
+ processedPackages.add(packageKey);
90
+
91
+ try {
92
+ const localPackageJsonPath = getPackageJsonPath(packageName);
93
+
94
+ if (!localPackageJsonPath) {
95
+ console.warn(`[react-native-legal] skipping ${packageName} could not find package.json`);
96
+ return;
97
+ }
98
+
99
+ const localPackageJson = require(path.resolve(localPackageJsonPath));
100
+
101
+ if (localPackageJson.private !== true) {
102
+ const licenseFiles = glob.sync('LICEN{S,C}E{.md,}', {
103
+ cwd: path.dirname(localPackageJsonPath),
104
+ absolute: true,
105
+ nocase: true,
106
+ nodir: true,
107
+ ignore: '**/{__tests__,__fixtures__,__mocks__}/**',
108
+ });
109
+
110
+ result[packageName] = {
111
+ author: parseAuthorField(localPackageJson),
112
+ content: licenseFiles?.[0] ? fs.readFileSync(licenseFiles[0], { encoding: 'utf-8' }) : undefined,
113
+ description: localPackageJson.description,
114
+ type: parseLicenseField(localPackageJson),
115
+ url: parseRepositoryFieldToUrl(localPackageJson),
116
+ version: localPackageJson.version,
117
+ };
118
+ }
119
+
120
+ const dependencies = localPackageJson.dependencies || {};
121
+
122
+ const isWorkspacePackage = version.startsWith('workspace:');
123
+
124
+ if (!isWorkspacePackage) return;
125
+
126
+ Object.entries(dependencies).forEach(([depName, depVersion]) => {
127
+ scanPackage(depName, depVersion as string, processedPackages, result);
128
+ });
129
+ } catch (error) {
130
+ console.warn(`[react-native-legal] could not process package.json for ${packageName}`);
131
+ }
132
+ }
133
+
73
134
  /**
74
135
  * Scans `package.json` and searches for all packages under `dependencies` field. Supports monorepo projects.
75
136
  */
76
137
  export function scanDependencies(appPackageJsonPath: string) {
77
138
  const appPackageJson = require(path.resolve(appPackageJsonPath));
78
139
  const dependencies: Record<string, string> = appPackageJson.dependencies;
140
+ const result: Record<string, LicenseObj> = {};
141
+ const processedPackages = new Set<string>();
79
142
 
80
- return Object.keys(dependencies).reduce(
81
- (acc, dependency) => {
82
- try {
83
- const localPackageJsonPath = getPackageJsonPath(dependency);
84
-
85
- if (!localPackageJsonPath) {
86
- console.warn(`[react-native-legal] skipping ${dependency} could not find package.json`);
87
- return acc;
88
- }
89
-
90
- const localPackageJson = require(path.resolve(localPackageJsonPath));
91
- const licenseFiles = glob.sync('LICEN{S,C}E{.md,}', {
92
- cwd: path.dirname(localPackageJsonPath),
93
- absolute: true,
94
- nocase: true,
95
- nodir: true,
96
- ignore: '**/{__tests__,__fixtures__,__mocks__}/**',
97
- });
98
-
99
- acc[dependency] = {
100
- author: parseAuthorField(localPackageJson),
101
- content: licenseFiles?.[0] ? fs.readFileSync(licenseFiles[0], { encoding: 'utf-8' }) : undefined,
102
- description: localPackageJson.description,
103
- type: parseLicenseField(localPackageJson),
104
- url: parseRepositoryFieldToUrl(localPackageJson),
105
- version: localPackageJson.version,
106
- };
107
- } catch (error) {
108
- console.warn(`[react-native-legal] could not process package.json for ${dependency}`);
109
- }
143
+ Object.entries(dependencies).forEach(([packageName, version]) => {
144
+ scanPackage(packageName, version, processedPackages, result);
145
+ });
110
146
 
111
- return acc;
112
- },
113
- {} as Record<string, LicenseObj>,
114
- );
147
+ return result;
115
148
  }
116
149
 
117
150
  function needsQuoting(value: string) {
@@ -1,45 +0,0 @@
1
- def safeAppExtGet(prop, fallback) {
2
- def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
3
- appProject?.ext?.has(prop) ? appProject.ext.get(prop) : fallback
4
- }
5
-
6
- // Let's detect react-native's directory, it will be used to determine RN's version
7
- // https://github.com/software-mansion/react-native-reanimated/blob/cda4627c3337c33674f05f755b7485165c6caca9/android/build.gradle#L88
8
- def resolveReactNativeDirectory() {
9
- def reactNativeLocation = safeAppExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
10
- if (reactNativeLocation != null) {
11
- return file(reactNativeLocation)
12
- }
13
-
14
- // monorepo workaround
15
- // react-native can be hoisted or in project's own node_modules
16
- def reactNativeFromNodeModules = file("${projectDir}/../../react-native")
17
- if (reactNativeFromNodeModules.exists()) {
18
- return reactNativeFromNodeModules
19
- }
20
-
21
- def reactNativeFromProjectNodeModules = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
22
- if (reactNativeFromProjectNodeModules.exists()) {
23
- return reactNativeFromProjectNodeModules
24
- }
25
-
26
- throw new GradleException(
27
- "[react-native-legal] Unable to resolve react-native location in " +
28
- "node_modules. You should project extension property (in app/build.gradle) " +
29
- "`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
30
- )
31
- }
32
-
33
- // https://github.com/software-mansion/react-native-reanimated/blob/cda4627c3337c33674f05f755b7485165c6caca9/android/build.gradle#L199#L205
34
- def reactNativeRootDir = resolveReactNativeDirectory()
35
-
36
- def reactProperties = new Properties()
37
- print("$reactNativeRootDir")
38
- file("$reactNativeRootDir/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
39
-
40
- def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME")
41
- def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.startsWith("0.0.0-") ? 1000 : REACT_NATIVE_VERSION.split("\\.")[1].toInteger()
42
-
43
- project.ext.shouldConsumeReactNativeFromMavenCentral = { ->
44
- return REACT_NATIVE_MINOR_VERSION >= 71
45
- }