diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..6f46588 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,14 @@ +**Fixes** # (*issue*) + +## Type of change +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update +## Checklist: +- [ ] Version upgraded (project, README, gradle, podspec etc) +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have added unit tests for the code +- [ ] I have made corresponding changes to the documentation diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..e248a67 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,83 @@ +name: CI + +on: + push: + branches: [ 'master' ] + pull_request: + branches: [ 'master' ] + types: [ 'opened', 'reopened', 'edited', 'synchronize' ] + workflow_dispatch: + +jobs: + cancel_previous: + + runs-on: ubuntu-latest + steps: + - uses: styfle/cancel-workflow-action@0.9.1 + with: + workflow_id: ${{ github.event.workflow.id }} + + appsflyer-test: + needs: cancel_previous + runs-on: ubuntu-latest + + steps: + - name: Checkout source branch + uses: actions/checkout@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: cache gradle dependencies + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-core-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle-core- + + - name: Run Tests + run: ./gradlew appsflyer:test +# - name: Generate coverage report +# run: ./gradlew appsflyer:codeCoverageReport +# - name: Upload coverage to Codecov +# uses: codecov/codecov-action@v2 + +# android-test: +# needs: cancel_previous +# runs-on: ubuntu-latest +# +# steps: +# - uses: actions/checkout@v2 +# - name: Grant execute permission for gradlew +# run: chmod +x gradlew +# - name: cache gradle dependencies +# uses: actions/cache@v2 +# with: +# path: | +# ~/.gradle/caches +# ~/.gradle/wrapper +# key: ${{ runner.os }}-gradle-android-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} +# restore-keys: | +# ${{ runner.os }}-gradle-android- +# - name: Run Tests +# run: ./gradlew android:test +# - name: Generate coverage report +# run: ./gradlew android:codeCoverageReport +# - name: Upload coverage to Codecov +# uses: codecov/codecov-action@v2 + +# security: +# needs: cancel_previous +# runs-on: ubuntu-latest +# +# steps: +# - uses: actions/checkout@v2 +# - name: Grant execute permission for gradlew +# run: chmod +x gradlew +# - name: Snyk +# run: ./gradlew snyk-test +# env: +# SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} diff --git a/.github/workflows/check_pr_title.yml b/.github/workflows/check_pr_title.yml new file mode 100644 index 0000000..90ab0b0 --- /dev/null +++ b/.github/workflows/check_pr_title.yml @@ -0,0 +1,16 @@ +name: Check PR title +on: + pull_request: + branches: ['master'] + types: ['opened', 'reopened', 'edited', 'synchronize'] + +jobs: + check_pr_title: + name: Check PR title + runs-on: ubuntu-latest + steps: + - name: Checkout source branch + uses: actions/checkout@v3 + + - name: Check PR title + uses: rudderlabs/github-action-check-pr-title@v1.0.7 \ No newline at end of file diff --git a/.github/workflows/draft_new_release.yml b/.github/workflows/draft_new_release.yml new file mode 100644 index 0000000..07d4773 --- /dev/null +++ b/.github/workflows/draft_new_release.yml @@ -0,0 +1,77 @@ +name: Draft new release + +on: + workflow_dispatch + +jobs: + draft-new-release: + name: Draft a new release + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/heads/feat/') || startsWith(github.ref, 'refs/heads/fix/') + steps: + - name: Checkout source branch + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set Node 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + + # In order to make a commit, we need to initialize a user. + # You may choose to write something less generic here if you want, it doesn't matter functionality wise. + - name: Initialize mandatory git config + run: | + git config user.name "GitHub actions" + git config user.email noreply@github.com + + # Calculate the next release version based on conventional semantic release + - name: Create release branch + id: create-release + run: | + source_branch_name=${GITHUB_REF##*/} + release_type=release + + git fetch origin master --depth=1 + git merge origin/master + current_version=$(cat gradle.properties | grep "VERSION_NAME" | cut -d'=' -f2) + + npm ci + npx standard-version --skip.commit --skip.tag --skip.changelog + new_version=$(cat gradle.properties | grep "VERSION_NAME" | cut -d'=' -f2) + git reset --hard + + branch_name="${release_type}/${new_version}" + + echo "Source branch for new release is $source_branch_name" + echo "Current version is $current_version" + echo "Release type is $release_type" + echo "New version is $new_version" + echo "New release branch name is $branch_name" + git checkout -b "$branch_name" + git push --set-upstream origin "$branch_name" + + echo "source_branch_name=$source_branch_name" >> $GITHUB_OUTPUT + echo "branch_name=$branch_name" >> $GITHUB_OUTPUT + echo "new_version=$new_version" >> $GITHUB_OUTPUT + + - name: Update changelog & bump version + id: finish-release + run: | + npm ci + npx standard-version -a --skip.tag + + - name: Push new version in release branch + run: | + git push + + - name: Create pull request into master + uses: repo-sync/pull-request@v2 + with: + source_branch: ${{ steps.create-release.outputs.branch_name }} + destination_branch: 'master' + github_token: ${{ secrets.PAT }} + pr_title: "chore(release): pulling ${{ steps.create-release.outputs.branch_name }} into master" + pr_body: ":crown: *An automated PR*" + pr_reviewer: 'itsdebs' diff --git a/.github/workflows/notion_pr_sync.yml b/.github/workflows/notion_pr_sync.yml new file mode 100644 index 0000000..3d26296 --- /dev/null +++ b/.github/workflows/notion_pr_sync.yml @@ -0,0 +1,55 @@ +name: Notion PR Sync + +on: + issues: + types: + [ + opened, + edited, + deleted, + transferred, + pinned, + unpinned, + closed, + reopened, + assigned, + unassigned, + labeled, + unlabeled, + locked, + unlocked, + milestoned, + demilestoned, + ] + pull_request: + types: + [ + assigned, + unassigned, + labeled, + unlabeled, + opened, + edited, + closed, + reopened, + synchronize, + converted_to_draft, + ready_for_review, + locked, + unlocked, + review_requested, + review_request_removed, + auto_merge_enabled, + auto_merge_disabled, + ] + +jobs: + request: + runs-on: ubuntu-latest + steps: + - name: Sync Github PRs to Notion + uses: sivashanmukh/github-notion-pr-sync@1.0.0 + with: + notionKey: ${{ secrets.NOTION_BOT_KEY }} + notionDatabaseId: ${{ secrets.NOTION_PR_DB_ID }} + githubKey: ${{ secrets.PAT }} diff --git a/.github/workflows/publish-new-github-release.yml b/.github/workflows/publish-new-github-release.yml new file mode 100644 index 0000000..9e1d3a0 --- /dev/null +++ b/.github/workflows/publish-new-github-release.yml @@ -0,0 +1,64 @@ +name: Publish new github release + +on: + pull_request: + branches: + - master + types: + - closed + workflow_dispatch: + inputs: + version: + required: true + +jobs: + release: + name: Publish new release + runs-on: ubuntu-latest + if: ${{ github.event_name == 'workflow_dispatch' }} || (startsWith(github.event.pull_request.head.ref, 'release/') && github.event.pull_request.merged == true) # only merged pull requests must trigger this job + steps: + - name: Extract version from branch name (for release branches) + id: extract-version + run: | + BRANCH_NAME="${{ github.event.pull_request.head.ref }}" + if [ "$BRANCH_NAME" = "" ]; then BRANCH_NAME=${{ github.event.inputs.version }} + fi + echo "BRANCH_NAME considered: ${BRANCH_NAME}" + VERSION=${BRANCH_NAME#release/} + + echo "release_version=$VERSION" >> $GITHUB_OUTPUT + + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 16 + + # In order to make a commit, we need to initialize a user. + # You may choose to write something less generic here if you want, it doesn't matter functionality wise. + - name: Initialize mandatory git config + run: | + git config user.name "GitHub actions" + git config user.email noreply@github.com + + - name: Create Github Release & Tag + id: create_release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CONVENTIONAL_GITHUB_RELEASER_TOKEN: ${{ secrets.PAT }} + run: | + git tag -a v${{ steps.extract-version.outputs.release_version }} -m "chore: release v${{ steps.extract-version.outputs.release_version }}" + git push origin refs/tags/v${{ steps.extract-version.outputs.release_version }} + DEBUG=conventional-github-releaser npx conventional-github-releaser -p angular + + - name: Delete release branch + uses: koj-co/delete-merged-action@master + if: startsWith(github.event.pull_request.head.ref, 'release/') + with: + branches: 'release/*' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7e0e79a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + workflow_dispatch: + release: + types: [ created ] + +jobs: + release: + runs-on: ubuntu-latest + environment: deployment + steps: + - name: Checkout source branch + uses: actions/checkout@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: cache gradle dependencies + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-core-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle-core- + + - name: Publish release to sonatype + run: ./gradlew publishToSonatype -Prelease closeAndReleaseSonatypeStagingRepository + env: + SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} + SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }} + ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.NEXUS_USERNAME }} + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} + + ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.NEXUS_PASSWORD }} + SIGNING_PRIVATE_KEY_BASE64: ${{ secrets.SIGNING_PRIVATE_KEY_BASE64 }} diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml new file mode 100644 index 0000000..55f5d30 --- /dev/null +++ b/.github/workflows/slack-notify.yml @@ -0,0 +1,41 @@ +name: Notify Slack Channel + +on: + release: + types: [created] + +jobs: + deploy-tag: + name: Notify Slack + runs-on: ubuntu-latest + steps: + - name: Send message to Slack channel + id: slack + uses: slackapi/slack-github-action@v1.23.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + PROJECT_NAME: rudder-integration-appsflyer-android + with: + channel-id: "${{ secrets.SLACK_RELEASE_CHANNEL_ID }}" + payload: | + { + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "New release: ${{ env.PROJECT_NAME }}" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*Release: <${{ github.event.release.html_url }}|${{ github.event.release.tag_name }}>*" + } + } + ] + } diff --git a/.github/workflows/snapshot_release.yml b/.github/workflows/snapshot_release.yml new file mode 100644 index 0000000..7392965 --- /dev/null +++ b/.github/workflows/snapshot_release.yml @@ -0,0 +1,40 @@ +name: Snapshot + +on: + pull_request: + branches: [ 'master' ] + types: [ 'opened', 'reopened', 'edited', 'synchronize' ] + +jobs: + snapshot: + runs-on: ubuntu-latest + environment: deployment + steps: + - name: Checkout source branch + uses: actions/checkout@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: cache gradle dependencies + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-core-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle-core- + + - name: Publish snapshot to sonatype + run: ./gradlew publishToSonatype + env: + SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} + SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }} + + ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.NEXUS_USERNAME }} + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.NEXUS_PASSWORD }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + SIGNING_PRIVATE_KEY_BASE64: ${{ secrets.SIGNING_PRIVATE_KEY_BASE64 }} + SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} diff --git a/.gitignore b/.gitignore index 6a59e46..cd813ca 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ local.properties .project /.settings **/.classpath -**/.settings \ No newline at end of file +**/.settings +.DS_Store +node_modules/* \ No newline at end of file diff --git a/.versionrc b/.versionrc new file mode 100644 index 0000000..efd0466 --- /dev/null +++ b/.versionrc @@ -0,0 +1,13 @@ +{ + "bumpFiles": [ + { + "filename": "package.json", + "type": "json" + }, + { + "filename": "gradle.properties", + "updater": "gradle-updater.js" + } + ] +} + diff --git a/appsflyer/build.gradle b/appsflyer/build.gradle index 0b7b56e..7980993 100644 --- a/appsflyer/build.gradle +++ b/appsflyer/build.gradle @@ -2,13 +2,13 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 33 + compileSdkVersion 31 defaultConfig { minSdkVersion 19 - targetSdkVersion 33 - versionCode 1 - versionName "2.2.0" + targetSdkVersion 31 + buildConfigField("String", "VERSION_NAME", "\"${VERSION_NAME}\"") + } buildTypes { @@ -17,6 +17,10 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { @@ -30,12 +34,7 @@ dependencies { implementation 'com.android.installreferrer:installreferrer:2.2' } -ext { - PUBLISH_GROUP_ID = 'com.rudderstack.android.integration' - PUBLISH_VERSION = '2.2.0' - PUBLISH_ARTIFACT_ID = 'appsflyer' -} - -apply from: "${rootProject.projectDir}/scripts/publish-module.gradle" +apply from: rootProject.file('gradle/mvn-publish.gradle') +apply from: rootProject.file('gradle/codecov.gradle') diff --git a/appsflyer/gradle.properties b/appsflyer/gradle.properties new file mode 100644 index 0000000..0a4fac8 --- /dev/null +++ b/appsflyer/gradle.properties @@ -0,0 +1,2 @@ +POM_ARTIFACT_ID=appsflyer +POM_PACKAGING=aar \ No newline at end of file diff --git a/build.gradle b/build.gradle index 62e4d79..a05cc85 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,8 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.1' + classpath 'com.android.tools.build:gradle:7.3.1' + } } @@ -23,4 +24,6 @@ task clean(type: Delete) { delete rootProject.buildDir } -apply from: "${rootDir}/scripts/publish-root.gradle" + +apply from: rootProject.file('gradle/promote.gradle') +apply from: rootProject.file('gradle/codecov.gradle') \ No newline at end of file diff --git a/gradle-updater.js b/gradle-updater.js new file mode 100644 index 0000000..d7966ef --- /dev/null +++ b/gradle-updater.js @@ -0,0 +1,22 @@ +var PropertiesReader = require('properties-reader'); +module.exports.readVersion = function (contents) { + console.log(contents); + var properties = PropertiesReader(); + properties.read(contents); + console.log(properties); + + return properties.get("VERSION_NAME"); + } + + module.exports.writeVersion = function (contents, version) { + const properties = PropertiesReader(); + properties.read(contents); + let versionCode = properties.get("VERSION_CODE"); + properties.set("VERSION_NAME", version); + properties.set("VERSION_CODE", (versionCode + 1)); + let output = ""; + properties.each((key, value) => { + output += `\n${key}=${value}`; + }); + return output; + } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 23339e0..8695bab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,21 +1,19 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. + +VERSION_NAME=2.2.0 +android.enableJetifier=true org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true -# Kotlin code style for this project: "official" or "obsolete": +POM_NAME=Rudder-Integration-AppsFlyer-Android +POM_DESCRIPTION=RudderStack\'s Native SDK Integration support for AppsFlyer. +POM_LICENCE_URL=http://opensource.org/licenses/MIT +POM_DEVELOPER_NAME=Rudderstack, Inc. kotlin.code.style=official +VERSION_CODE=1 +POM_LICENCE_DIST=repo +GROUP=com.rudderstack.android.integration +POM_DEVELOPER_ID=Rudderstack +POM_LICENCE_NAME=The MIT License (MIT) +POM_URL=https://github.com/rudderlabs/rudder-integration-appsflyer-android +POM_SCM_URL=https://github.com/rudderlabs/rudder-integration-appsflyer-android/tree/master +POM_SCM_CONNECTION=scm:git:git://github.com/rudderlabs/rudder-integration-appsflyer-android.git +POM_SCM_DEV_CONNECTION=scm:git:git://github.com:rudderlabs/rudder-integration-appsflyer-android.git diff --git a/gradle/artifacts-android.gradle b/gradle/artifacts-android.gradle new file mode 100644 index 0000000..9ecc8fa --- /dev/null +++ b/gradle/artifacts-android.gradle @@ -0,0 +1,25 @@ +task sourcesJar(type: Jar) { + archiveClassifier.set('sources') + from android.sourceSets.main.java.srcDirs +} + +task javadoc(type: Javadoc) { + configurations.implementation.setCanBeResolved(true) + + failOnError false + source = android.sourceSets.main.java.sourceFiles + classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + classpath += configurations.implementation +} + +// build a jar with javadoc +task javadocJar(type: Jar, dependsOn: javadoc) { + archiveClassifier.set('javadoc') + from javadoc.destinationDir +} + +// Attach Javadocs and Sources jar +artifacts { + archives sourcesJar + archives javadocJar +} \ No newline at end of file diff --git a/gradle/codecov.gradle b/gradle/codecov.gradle new file mode 100644 index 0000000..29fc393 --- /dev/null +++ b/gradle/codecov.gradle @@ -0,0 +1,37 @@ +apply plugin: 'jacoco' + +jacoco { + toolVersion = "0.8.7" +} + +task codeCoverageReport(type: JacocoReport) { + def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', "**/**/*serializer*.*", "**/**/*Companion*.*" ] + def mainSrc = [] + def debugTrees = [] + def execData = [] + if(project.name == rootProject.name) { + subprojects.each { + mainSrc.add("${it.projectDir}/src/main/java") + debugTrees.add(fileTree(dir: "${it.buildDir}/classes", excludes: fileFilter)) + debugTrees.add(fileTree(dir: "${it.buildDir}/tmp/kotlin-classes/debugUnitTest", excludes: fileFilter)) + execData.add(fileTree(dir: "${it.buildDir}/jacoco", includes: ["*.exec"])) + } + } + else { + mainSrc.add("${project.projectDir}/src/main/java") + debugTrees.add(fileTree(dir: "${project.buildDir}/classes", excludes: fileFilter)) + debugTrees.add(fileTree(dir: "${project.buildDir}/tmp/kotlin-classes/debugUnitTest", excludes: fileFilter)) + execData.add(fileTree(dir: "${project.buildDir}/jacoco", includes: ["*.exec"])) + } + + sourceDirectories.setFrom(files(mainSrc)) + classDirectories.setFrom(files(debugTrees)) + executionData.setFrom(execData) + + reports { + xml.enabled true + xml.destination file("${buildDir}/reports/jacoco/report.xml") + html.enabled true + csv.enabled false + } +} \ No newline at end of file diff --git a/gradle/mvn-publish.gradle b/gradle/mvn-publish.gradle new file mode 100644 index 0000000..dd994c0 --- /dev/null +++ b/gradle/mvn-publish.gradle @@ -0,0 +1,87 @@ +apply plugin: 'maven-publish' +apply plugin: 'signing' + +publishing { + publications { + release(MavenPublication) { + // The coordinates of the library, being set from variables that + // we'll set up in a moment + groupId GROUP + artifactId POM_ARTIFACT_ID + version getVersionName() + +// if (project.getName() == "android") { + artifact("$buildDir/outputs/aar/${project.getName()}-release.aar") +// } +// else { +// artifact("$buildDir/libs/${project.getName()}-${version}.jar") +// } +// artifact sourcesJar +// artifact javadocJar + + // Self-explanatory metadata for the most part + pom { + name = POM_NAME + packaging = POM_PACKAGING + description = POM_DESCRIPTION + url = POM_URL + + licenses { + license { + name = POM_LICENCE_NAME + url = POM_LICENCE_URL + distribution = POM_LICENCE_DIST + } + } + + developers { + developer { + id = POM_DEVELOPER_ID + name = POM_DEVELOPER_NAME + } + } + + scm { + url = POM_SCM_URL + connection = POM_SCM_CONNECTION + developerConnection = POM_SCM_DEV_CONNECTION + } + // A slight fix so that the generated POM will include any transitive dependencies + // that the library builds upon + withXml { + def dependenciesNode = asNode().appendNode('dependencies') + ext.addDependency = { Dependency dep, String scope -> + if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified") + return // invalid dependencies should be ignored + + final dependencyNode = dependenciesNode.appendNode('dependency') + dependencyNode.appendNode('artifactId', dep.name) + if (dep.version == 'unspecified') { + dependencyNode.appendNode('groupId', project.ext.pomGroupID) + dependencyNode.appendNode('version', project.ext.pomVersion) + } else { + dependencyNode.appendNode('groupId', dep.group) + dependencyNode.appendNode('version', dep.version) + } + dependencyNode.appendNode('scope', scope) + } + + configurations.api.getDependencies().each { dep -> addDependency(dep, "compile") } + configurations.implementation.getDependencies().each { dep -> addDependency(dep, "runtime") } + } + } + } + } +} + + +signing { + def signingKeyId = System.getenv("SIGNING_KEY_ID") + def signingKey = System.getenv("SIGNING_PRIVATE_KEY_BASE64") + def signingPassword = System.getenv("SIGNING_KEY_PASSWORD") + useInMemoryPgpKeys(signingKeyId,signingKey, signingPassword) + sign publishing.publications +} +publish.dependsOn build +publishToMavenLocal.dependsOn build +publishToSonatype.dependsOn publish \ No newline at end of file diff --git a/gradle/promote.gradle b/gradle/promote.gradle new file mode 100644 index 0000000..e4a009e --- /dev/null +++ b/gradle/promote.gradle @@ -0,0 +1,63 @@ +apply from: rootProject.file('gradle/versioning.gradle') + +group GROUP +version getVersionName() +//project.logger.info("Signing id: ${hasProperty("signing.keyId")}") +// Create variables with empty default values +ext["signing.keyId"] = '' +ext["signing.password"] = '' +ext["signing.key"] = '' +ext["ossrhUsername"] = '' +ext["ossrhPassword"] = '' +ext["sonatypeStagingProfileId"] = '' + +File secretPropsFile = project.rootProject.file('local.properties') +if (secretPropsFile.exists()) { + // Read local.properties file first if it exists + Properties p = new Properties() + new FileInputStream(secretPropsFile).withCloseable { is -> p.load(is) } + p.each { name, value -> ext[name] = value } + println("read from local.props") +} else { + // Use system environment variables + ext["ossrhUsername"] = System.getenv('NEXUS_USERNAME') + ext["ossrhPassword"] = System.getenv('NEXUS_PASSWORD') + ext["sonatypeStagingProfileId"] = System.getenv('SONATYPE_STAGING_PROFILE_ID') +// ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') + ext["signing.password"] = System.getenv('SIGNING_PASSWORD') + ext["signing.key"] = System.getenv('SIGNING_PRIVATE_KEY_BASE64') + println("read from environmenrt: ${ext["sonatypeStagingProfileId"]}") + +} +//println("Signing id: ${hasProperty("signing.keyId")}") +////if (!hasProperty("signing.keyId")) { +// +// def pgpKeyContent = ext["signing.keyId"] +// if (pgpKeyContent != null) { +// def tmpDir = new File("$rootProject.rootDir/tmp") +// logger.warn("temp dir, $tmpDir") +// mkdir tmpDir +// def keyFile = new File("$tmpDir/key.pgp") +// keyFile.createNewFile() +// def os = keyFile.newDataOutputStream() +// os.write(pgpKeyContent.decodeBase64()) +// os.close() +// +// ext['signing.secretKeyRingFile'] = keyFile.absolutePath +// println("secret key file: ${getProperty("signing.secretKeyRingFile")}") +// +// } +//} + +nexusPublishing { + repositories { + sonatype { + stagingProfileId = System.getenv("SONATYPE_STAGING_PROFILE_ID") + username = System.getenv('NEXUS_USERNAME') + password = System.getenv('NEXUS_PASSWORD') + + nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")) + snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) + } + } +} \ No newline at end of file diff --git a/gradle/versioning.gradle b/gradle/versioning.gradle new file mode 100644 index 0000000..8ec34c8 --- /dev/null +++ b/gradle/versioning.gradle @@ -0,0 +1,12 @@ +def isReleaseBuild() { + return hasProperty('release') +} + +def getVersionName() { // If not release build add SNAPSHOT suffix + return isReleaseBuild() ? VERSION_NAME : VERSION_NAME+"-SNAPSHOT" +} + +ext { + isReleaseBuild = this.&isReleaseBuild + getVersionName = this.&getVersionName +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5063a51..7a5fffa 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Mar 02 14:29:20 IST 2020 +#Mon Dec 26 16:26:49 IST 2022 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-all.zip \ No newline at end of file +zipStoreBase=GRADLE_USER_HOME diff --git a/node_modules/.bin/mkdirp b/node_modules/.bin/mkdirp new file mode 120000 index 0000000..017896c --- /dev/null +++ b/node_modules/.bin/mkdirp @@ -0,0 +1 @@ +../mkdirp/bin/cmd.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..ccb5b3a --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,30 @@ +{ + "name": "rudder-integration-appsflyer-android", + "version": "2.2.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/properties-reader": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/properties-reader/-/properties-reader-2.2.0.tgz", + "integrity": "sha512-CgVcr8MwGoBKK24r9TwHfZkLLaNFHQ6y4wgT9w/XzdpacOOi5ciH4hcuLechSDAwXsfrGQtI2JTutY2djOx2Ow==", + "dependencies": { + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=10" + } + } + } +} diff --git a/node_modules/mkdirp/CHANGELOG.md b/node_modules/mkdirp/CHANGELOG.md new file mode 100644 index 0000000..8145838 --- /dev/null +++ b/node_modules/mkdirp/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changers Lorgs! + +## 1.0 + +Full rewrite. Essentially a brand new module. + +- Return a promise instead of taking a callback. +- Use native `fs.mkdir(path, { recursive: true })` when available. +- Drop support for outdated Node.js versions. (Technically still works on + Node.js v8, but only 10 and above are officially supported.) + +## 0.x + +Original and most widely used recursive directory creation implementation +in JavaScript, dating back to 2010. diff --git a/node_modules/mkdirp/LICENSE b/node_modules/mkdirp/LICENSE new file mode 100644 index 0000000..13fcd15 --- /dev/null +++ b/node_modules/mkdirp/LICENSE @@ -0,0 +1,21 @@ +Copyright James Halliday (mail@substack.net) and Isaac Z. Schlueter (i@izs.me) + +This project is free software released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/mkdirp/bin/cmd.js b/node_modules/mkdirp/bin/cmd.js new file mode 100755 index 0000000..6e0aa8d --- /dev/null +++ b/node_modules/mkdirp/bin/cmd.js @@ -0,0 +1,68 @@ +#!/usr/bin/env node + +const usage = () => ` +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories + that don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m If a directory needs to be created, set the mode as an octal + --mode= permission string. + + -v --version Print the mkdirp version number + + -h --help Print this helpful banner + + -p --print Print the first directories created for each path provided + + --manual Use manual implementation, even if native is available +` + +const dirs = [] +const opts = {} +let print = false +let dashdash = false +let manual = false +for (const arg of process.argv.slice(2)) { + if (dashdash) + dirs.push(arg) + else if (arg === '--') + dashdash = true + else if (arg === '--manual') + manual = true + else if (/^-h/.test(arg) || /^--help/.test(arg)) { + console.log(usage()) + process.exit(0) + } else if (arg === '-v' || arg === '--version') { + console.log(require('../package.json').version) + process.exit(0) + } else if (arg === '-p' || arg === '--print') { + print = true + } else if (/^-m/.test(arg) || /^--mode=/.test(arg)) { + const mode = parseInt(arg.replace(/^(-m|--mode=)/, ''), 8) + if (isNaN(mode)) { + console.error(`invalid mode argument: ${arg}\nMust be an octal number.`) + process.exit(1) + } + opts.mode = mode + } else + dirs.push(arg) +} + +const mkdirp = require('../') +const impl = manual ? mkdirp.manual : mkdirp +if (dirs.length === 0) + console.error(usage()) + +Promise.all(dirs.map(dir => impl(dir, opts))) + .then(made => print ? made.forEach(m => m && console.log(m)) : null) + .catch(er => { + console.error(er.message) + if (er.code) + console.error(' code: ' + er.code) + process.exit(1) + }) diff --git a/node_modules/mkdirp/index.js b/node_modules/mkdirp/index.js new file mode 100644 index 0000000..ad7a16c --- /dev/null +++ b/node_modules/mkdirp/index.js @@ -0,0 +1,31 @@ +const optsArg = require('./lib/opts-arg.js') +const pathArg = require('./lib/path-arg.js') + +const {mkdirpNative, mkdirpNativeSync} = require('./lib/mkdirp-native.js') +const {mkdirpManual, mkdirpManualSync} = require('./lib/mkdirp-manual.js') +const {useNative, useNativeSync} = require('./lib/use-native.js') + + +const mkdirp = (path, opts) => { + path = pathArg(path) + opts = optsArg(opts) + return useNative(opts) + ? mkdirpNative(path, opts) + : mkdirpManual(path, opts) +} + +const mkdirpSync = (path, opts) => { + path = pathArg(path) + opts = optsArg(opts) + return useNativeSync(opts) + ? mkdirpNativeSync(path, opts) + : mkdirpManualSync(path, opts) +} + +mkdirp.sync = mkdirpSync +mkdirp.native = (path, opts) => mkdirpNative(pathArg(path), optsArg(opts)) +mkdirp.manual = (path, opts) => mkdirpManual(pathArg(path), optsArg(opts)) +mkdirp.nativeSync = (path, opts) => mkdirpNativeSync(pathArg(path), optsArg(opts)) +mkdirp.manualSync = (path, opts) => mkdirpManualSync(pathArg(path), optsArg(opts)) + +module.exports = mkdirp diff --git a/node_modules/mkdirp/lib/find-made.js b/node_modules/mkdirp/lib/find-made.js new file mode 100644 index 0000000..022e492 --- /dev/null +++ b/node_modules/mkdirp/lib/find-made.js @@ -0,0 +1,29 @@ +const {dirname} = require('path') + +const findMade = (opts, parent, path = undefined) => { + // we never want the 'made' return value to be a root directory + if (path === parent) + return Promise.resolve() + + return opts.statAsync(parent).then( + st => st.isDirectory() ? path : undefined, // will fail later + er => er.code === 'ENOENT' + ? findMade(opts, dirname(parent), parent) + : undefined + ) +} + +const findMadeSync = (opts, parent, path = undefined) => { + if (path === parent) + return undefined + + try { + return opts.statSync(parent).isDirectory() ? path : undefined + } catch (er) { + return er.code === 'ENOENT' + ? findMadeSync(opts, dirname(parent), parent) + : undefined + } +} + +module.exports = {findMade, findMadeSync} diff --git a/node_modules/mkdirp/lib/mkdirp-manual.js b/node_modules/mkdirp/lib/mkdirp-manual.js new file mode 100644 index 0000000..2eb18cd --- /dev/null +++ b/node_modules/mkdirp/lib/mkdirp-manual.js @@ -0,0 +1,64 @@ +const {dirname} = require('path') + +const mkdirpManual = (path, opts, made) => { + opts.recursive = false + const parent = dirname(path) + if (parent === path) { + return opts.mkdirAsync(path, opts).catch(er => { + // swallowed by recursive implementation on posix systems + // any other error is a failure + if (er.code !== 'EISDIR') + throw er + }) + } + + return opts.mkdirAsync(path, opts).then(() => made || path, er => { + if (er.code === 'ENOENT') + return mkdirpManual(parent, opts) + .then(made => mkdirpManual(path, opts, made)) + if (er.code !== 'EEXIST' && er.code !== 'EROFS') + throw er + return opts.statAsync(path).then(st => { + if (st.isDirectory()) + return made + else + throw er + }, () => { throw er }) + }) +} + +const mkdirpManualSync = (path, opts, made) => { + const parent = dirname(path) + opts.recursive = false + + if (parent === path) { + try { + return opts.mkdirSync(path, opts) + } catch (er) { + // swallowed by recursive implementation on posix systems + // any other error is a failure + if (er.code !== 'EISDIR') + throw er + else + return + } + } + + try { + opts.mkdirSync(path, opts) + return made || path + } catch (er) { + if (er.code === 'ENOENT') + return mkdirpManualSync(path, opts, mkdirpManualSync(parent, opts, made)) + if (er.code !== 'EEXIST' && er.code !== 'EROFS') + throw er + try { + if (!opts.statSync(path).isDirectory()) + throw er + } catch (_) { + throw er + } + } +} + +module.exports = {mkdirpManual, mkdirpManualSync} diff --git a/node_modules/mkdirp/lib/mkdirp-native.js b/node_modules/mkdirp/lib/mkdirp-native.js new file mode 100644 index 0000000..c7a6b69 --- /dev/null +++ b/node_modules/mkdirp/lib/mkdirp-native.js @@ -0,0 +1,39 @@ +const {dirname} = require('path') +const {findMade, findMadeSync} = require('./find-made.js') +const {mkdirpManual, mkdirpManualSync} = require('./mkdirp-manual.js') + +const mkdirpNative = (path, opts) => { + opts.recursive = true + const parent = dirname(path) + if (parent === path) + return opts.mkdirAsync(path, opts) + + return findMade(opts, path).then(made => + opts.mkdirAsync(path, opts).then(() => made) + .catch(er => { + if (er.code === 'ENOENT') + return mkdirpManual(path, opts) + else + throw er + })) +} + +const mkdirpNativeSync = (path, opts) => { + opts.recursive = true + const parent = dirname(path) + if (parent === path) + return opts.mkdirSync(path, opts) + + const made = findMadeSync(opts, path) + try { + opts.mkdirSync(path, opts) + return made + } catch (er) { + if (er.code === 'ENOENT') + return mkdirpManualSync(path, opts) + else + throw er + } +} + +module.exports = {mkdirpNative, mkdirpNativeSync} diff --git a/node_modules/mkdirp/lib/opts-arg.js b/node_modules/mkdirp/lib/opts-arg.js new file mode 100644 index 0000000..2fa4833 --- /dev/null +++ b/node_modules/mkdirp/lib/opts-arg.js @@ -0,0 +1,23 @@ +const { promisify } = require('util') +const fs = require('fs') +const optsArg = opts => { + if (!opts) + opts = { mode: 0o777, fs } + else if (typeof opts === 'object') + opts = { mode: 0o777, fs, ...opts } + else if (typeof opts === 'number') + opts = { mode: opts, fs } + else if (typeof opts === 'string') + opts = { mode: parseInt(opts, 8), fs } + else + throw new TypeError('invalid options argument') + + opts.mkdir = opts.mkdir || opts.fs.mkdir || fs.mkdir + opts.mkdirAsync = promisify(opts.mkdir) + opts.stat = opts.stat || opts.fs.stat || fs.stat + opts.statAsync = promisify(opts.stat) + opts.statSync = opts.statSync || opts.fs.statSync || fs.statSync + opts.mkdirSync = opts.mkdirSync || opts.fs.mkdirSync || fs.mkdirSync + return opts +} +module.exports = optsArg diff --git a/node_modules/mkdirp/lib/path-arg.js b/node_modules/mkdirp/lib/path-arg.js new file mode 100644 index 0000000..cc07de5 --- /dev/null +++ b/node_modules/mkdirp/lib/path-arg.js @@ -0,0 +1,29 @@ +const platform = process.env.__TESTING_MKDIRP_PLATFORM__ || process.platform +const { resolve, parse } = require('path') +const pathArg = path => { + if (/\0/.test(path)) { + // simulate same failure that node raises + throw Object.assign( + new TypeError('path must be a string without null bytes'), + { + path, + code: 'ERR_INVALID_ARG_VALUE', + } + ) + } + + path = resolve(path) + if (platform === 'win32') { + const badWinChars = /[*|"<>?:]/ + const {root} = parse(path) + if (badWinChars.test(path.substr(root.length))) { + throw Object.assign(new Error('Illegal characters in path.'), { + path, + code: 'EINVAL', + }) + } + } + + return path +} +module.exports = pathArg diff --git a/node_modules/mkdirp/lib/use-native.js b/node_modules/mkdirp/lib/use-native.js new file mode 100644 index 0000000..079361d --- /dev/null +++ b/node_modules/mkdirp/lib/use-native.js @@ -0,0 +1,10 @@ +const fs = require('fs') + +const version = process.env.__TESTING_MKDIRP_NODE_VERSION__ || process.version +const versArr = version.replace(/^v/, '').split('.') +const hasNative = +versArr[0] > 10 || +versArr[0] === 10 && +versArr[1] >= 12 + +const useNative = !hasNative ? () => false : opts => opts.mkdir === fs.mkdir +const useNativeSync = !hasNative ? () => false : opts => opts.mkdirSync === fs.mkdirSync + +module.exports = {useNative, useNativeSync} diff --git a/node_modules/mkdirp/package.json b/node_modules/mkdirp/package.json new file mode 100644 index 0000000..2913ed0 --- /dev/null +++ b/node_modules/mkdirp/package.json @@ -0,0 +1,44 @@ +{ + "name": "mkdirp", + "description": "Recursively mkdir, like `mkdir -p`", + "version": "1.0.4", + "main": "index.js", + "keywords": [ + "mkdir", + "directory", + "make dir", + "make", + "dir", + "recursive", + "native" + ], + "repository": { + "type": "git", + "url": "https://github.com/isaacs/node-mkdirp.git" + }, + "scripts": { + "test": "tap", + "snap": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --follow-tags" + }, + "tap": { + "check-coverage": true, + "coverage-map": "map.js" + }, + "devDependencies": { + "require-inject": "^1.4.4", + "tap": "^14.10.7" + }, + "bin": "bin/cmd.js", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "files": [ + "bin", + "lib", + "index.js" + ] +} diff --git a/node_modules/mkdirp/readme.markdown b/node_modules/mkdirp/readme.markdown new file mode 100644 index 0000000..827de59 --- /dev/null +++ b/node_modules/mkdirp/readme.markdown @@ -0,0 +1,266 @@ +# mkdirp + +Like `mkdir -p`, but in Node.js! + +Now with a modern API and no\* bugs! + +\* may contain some bugs + +# example + +## pow.js + +```js +const mkdirp = require('mkdirp') + +// return value is a Promise resolving to the first directory created +mkdirp('/tmp/foo/bar/baz').then(made => + console.log(`made directories, starting with ${made}`)) +``` + +Output (where `/tmp/foo` already exists) + +``` +made directories, starting with /tmp/foo/bar +``` + +Or, if you don't have time to wait around for promises: + +```js +const mkdirp = require('mkdirp') + +// return value is the first directory created +const made = mkdirp.sync('/tmp/foo/bar/baz') +console.log(`made directories, starting with ${made}`) +``` + +And now /tmp/foo/bar/baz exists, huzzah! + +# methods + +```js +const mkdirp = require('mkdirp') +``` + +## mkdirp(dir, [opts]) -> Promise + +Create a new directory and any necessary subdirectories at `dir` with octal +permission string `opts.mode`. If `opts` is a string or number, it will be +treated as the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0o777 & +(~process.umask())`. + +Promise resolves to first directory `made` that had to be created, or +`undefined` if everything already exists. Promise rejects if any errors +are encountered. Note that, in the case of promise rejection, some +directories _may_ have been created, as recursive directory creation is not +an atomic operation. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdir(path, opts, cb)` +and `opts.fs.stat(path, cb)`. + +You can also override just one or the other of `mkdir` and `stat` by +passing in `opts.stat` or `opts.mkdir`, or providing an `fs` option that +only overrides one of these. + +## mkdirp.sync(dir, opts) -> String|null + +Synchronously create a new directory and any necessary subdirectories at +`dir` with octal permission string `opts.mode`. If `opts` is a string or +number, it will be treated as the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0o777 & +(~process.umask())`. + +Returns the first directory that had to be created, or undefined if +everything already exists. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` +and `opts.fs.statSync(path)`. + +You can also override just one or the other of `mkdirSync` and `statSync` +by passing in `opts.statSync` or `opts.mkdirSync`, or providing an `fs` +option that only overrides one of these. + +## mkdirp.manual, mkdirp.manualSync + +Use the manual implementation (not the native one). This is the default +when the native implementation is not available or the stat/mkdir +implementation is overridden. + +## mkdirp.native, mkdirp.nativeSync + +Use the native implementation (not the manual one). This is the default +when the native implementation is available and stat/mkdir are not +overridden. + +# implementation + +On Node.js v10.12.0 and above, use the native `fs.mkdir(p, +{recursive:true})` option, unless `fs.mkdir`/`fs.mkdirSync` has been +overridden by an option. + +## native implementation + +- If the path is a root directory, then pass it to the underlying + implementation and return the result/error. (In this case, it'll either + succeed or fail, but we aren't actually creating any dirs.) +- Walk up the path statting each directory, to find the first path that + will be created, `made`. +- Call `fs.mkdir(path, { recursive: true })` (or `fs.mkdirSync`) +- If error, raise it to the caller. +- Return `made`. + +## manual implementation + +- Call underlying `fs.mkdir` implementation, with `recursive: false` +- If error: + - If path is a root directory, raise to the caller and do not handle it + - If ENOENT, mkdirp parent dir, store result as `made` + - stat(path) + - If error, raise original `mkdir` error + - If directory, return `made` + - Else, raise original `mkdir` error +- else + - return `undefined` if a root dir, or `made` if set, or `path` + +## windows vs unix caveat + +On Windows file systems, attempts to create a root directory (ie, a drive +letter or root UNC path) will fail. If the root directory exists, then it +will fail with `EPERM`. If the root directory does not exist, then it will +fail with `ENOENT`. + +On posix file systems, attempts to create a root directory (in recursive +mode) will succeed silently, as it is treated like just another directory +that already exists. (In non-recursive mode, of course, it fails with +`EEXIST`.) + +In order to preserve this system-specific behavior (and because it's not as +if we can create the parent of a root directory anyway), attempts to create +a root directory are passed directly to the `fs` implementation, and any +errors encountered are not handled. + +## native error caveat + +The native implementation (as of at least Node.js v13.4.0) does not provide +appropriate errors in some cases (see +[nodejs/node#31481](https://github.com/nodejs/node/issues/31481) and +[nodejs/node#28015](https://github.com/nodejs/node/issues/28015)). + +In order to work around this issue, the native implementation will fall +back to the manual implementation if an `ENOENT` error is encountered. + +# choosing a recursive mkdir implementation + +There are a few to choose from! Use the one that suits your needs best :D + +## use `fs.mkdir(path, {recursive: true}, cb)` if: + +- You wish to optimize performance even at the expense of other factors. +- You don't need to know the first dir created. +- You are ok with getting `ENOENT` as the error when some other problem is + the actual cause. +- You can limit your platforms to Node.js v10.12 and above. +- You're ok with using callbacks instead of promises. +- You don't need/want a CLI. +- You don't need to override the `fs` methods in use. + +## use this module (mkdirp 1.x) if: + +- You need to know the first directory that was created. +- You wish to use the native implementation if available, but fall back + when it's not. +- You prefer promise-returning APIs to callback-taking APIs. +- You want more useful error messages than the native recursive mkdir + provides (at least as of Node.js v13.4), and are ok with re-trying on + `ENOENT` to achieve this. +- You need (or at least, are ok with) a CLI. +- You need to override the `fs` methods in use. + +## use [`make-dir`](http://npm.im/make-dir) if: + +- You do not need to know the first dir created (and wish to save a few + `stat` calls when using the native implementation for this reason). +- You wish to use the native implementation if available, but fall back + when it's not. +- You prefer promise-returning APIs to callback-taking APIs. +- You are ok with occasionally getting `ENOENT` errors for failures that + are actually related to something other than a missing file system entry. +- You don't need/want a CLI. +- You need to override the `fs` methods in use. + +## use mkdirp 0.x if: + +- You need to know the first directory that was created. +- You need (or at least, are ok with) a CLI. +- You need to override the `fs` methods in use. +- You're ok with using callbacks instead of promises. +- You are not running on Windows, where the root-level ENOENT errors can + lead to infinite regress. +- You think vinyl just sounds warmer and richer for some weird reason. +- You are supporting truly ancient Node.js versions, before even the advent + of a `Promise` language primitive. (Please don't. You deserve better.) + +# cli + +This package also ships with a `mkdirp` command. + +``` +$ mkdirp -h + +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories + that don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m If a directory needs to be created, set the mode as an octal + --mode= permission string. + + -v --version Print the mkdirp version number + + -h --help Print this helpful banner + + -p --print Print the first directories created for each path provided + + --manual Use manual implementation, even if native is available +``` + +# install + +With [npm](http://npmjs.org) do: + +``` +npm install mkdirp +``` + +to get the library locally, or + +``` +npm install -g mkdirp +``` + +to get the command everywhere, or + +``` +npx mkdirp ... +``` + +to run the command without installing it globally. + +# platform support + +This module works on node v8, but only v10 and above are officially +supported, as Node v8 reached its LTS end of life 2020-01-01, which is in +the past, as of this writing. + +# license + +MIT diff --git a/node_modules/properties-reader/LICENSE b/node_modules/properties-reader/LICENSE new file mode 100644 index 0000000..0aa2568 --- /dev/null +++ b/node_modules/properties-reader/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Steve King + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/properties-reader/README.md b/node_modules/properties-reader/README.md new file mode 100644 index 0000000..3d48d3b --- /dev/null +++ b/node_modules/properties-reader/README.md @@ -0,0 +1,129 @@ +Properties-Reader +================= + +An ini file compatible properties reader for [Node.JS](http://nodejs.org) + +Installation +============ + +The easiest installation is through [NPM](http://npmjs.org): + + npm install properties-reader + +API +=== + +Read properties from a file: + + var propertiesReader = require('properties-reader'); + var properties = propertiesReader('/path/to/properties.file'); + +The properties are then accessible either by fully qualified name, or if the property names are in dot-delimited +notation, they can be access as an object: + + // fully qualified name + var property = properties.get('some.property.name'); + + // by object path + var property = properties.path().some.property.name; + +To read more than one file, chain calls to the `.append()` method: + + properties.append('/another.file').append('/yet/another.file'); + +To read properties from a string, use the `.read()` method: + + properties.read('some.property = Value \n another.property = Another Value'); + +To set a single property into the properties object, use `.set()`: + + properties.set('property.name', 'Property Value'); + +When reading a `.ini` file, sections are created by having a line that contains just a section name in square +brackets. The section name is then prefixed to all property names that follow it until another section name is found +to replace the current section. + + # contents of properties file + [main] + some.thing = foo + + [blah] + some.thing = bar + + // reading these back from the properties reader + properties.get('main.some.thing') == 'foo'; + properties.get('blah.some.thing') == 'bar'; + + // looping through the properties reader + properties.each((key, value) => { + // called for each item in the reader, + // first with key=main.some.thing, value=foo + // next with key=blah.some.thing, value=bar + }); + + // get all properties at once + expect(properties.getAllProperties()).toEqual({ + 'main.some.thing': 'foo', + 'blah.some.thing': 'bar', + }) + + +Checking for the current number of properties that have been read into the reader: + + var propertiesCount = properties.length; + +The length is calculated on request, so if accessing this in a loop an efficiency would be achieved by caching the +value. + +When duplicate names are found in the properties, the first one read will be replaced with the later one. + +To get the complete set of properties, either loop through them with the `.each((key, value) => {})` iterator or +use the convenience method `getAllProperties` to return the complete set of flattened properties. + +### Saving changes + +Once a file has been read and changes made, saving those changes to another file is as simple as running: + +```javascript +// async/await ES6 +const propertiesReader = require('properties-reader'); +const props = propertiesReader(filePath, {writer: { saveSections: true }}); +await props.save(filePath); + +// ES5 callback styles +props.save(filePath, function then(err, data) { ... }); + +// ES5 promise style +props.save(filePath).then(onSaved, onSaveError); +``` + +To output the properties without any section headings, set the `saveSections` option to `false` + +Data Types +========== + +Properties will automatically be converted to their regular data types when they represent true/false or numeric +values. To get the original value without any parsing / type coercion applied, use `properties.getRaw('path.to.prop')`. + +FAQ / Breaking Changes +====================== + +## Duplicate Section Headings + +From version `2.0.0` the default behaviour relating to multiple `[section]` blocks with the same name has changed +so combine the items of each same-named section into the one section. This is only visible when saving the items +(via `reader.save()`). + +To restore the previous behaviour which would allow duplicate `[...]` blocks to be created, supply an appender +configuration with the property `allowDuplicateSections` set to `true`. + +```javascript +const propertiesReader = require('properties-reader'); +const props = propertiesReader(filePath, 'utf-8', { allowDuplicateSections: true }); +``` + +Contributions +============= + +If you find bugs or want to change functionality, feel free to fork and pull request. + diff --git a/node_modules/properties-reader/package.json b/node_modules/properties-reader/package.json new file mode 100644 index 0000000..3b68c1a --- /dev/null +++ b/node_modules/properties-reader/package.json @@ -0,0 +1,73 @@ +{ + "name": "properties-reader", + "description": "Properties file reader for Node.js", + "version": "2.2.0", + "author": { + "name": "Steve King", + "email": "steve@mydev.co" + }, + "contributors": [ + { + "name": "Steve King", + "email": "steve@mydev.co" + }, + { + "name": "Aureliano Bergese", + "email": "onailerua@hotmail.coom" + } + ], + "dependencies": { + "mkdirp": "^1.0.4" + }, + "devDependencies": { + "jest": "^26.6.3" + }, + "keywords": [ + "properties", + "ini", + "parser" + ], + "repository": { + "type": "git", + "url": "git://github.com/steveukx/properties" + }, + "main": "src/properties-reader-factory", + "files": [ + "src/**/*.js" + ], + "scripts": { + "preversion": "npm test", + "postversion": "npm publish && git push && git push --tags", + "test": "jest --coverage" + }, + "engines": { + "node": ">=10" + }, + "license": "MIT", + "jest": { + "roots": [ + "/src/", + "/test/" + ], + "coverageThreshold": { + "global": { + "branches": 80, + "functions": 80, + "lines": 80, + "statements": 80 + } + }, + "coveragePathIgnorePatterns": [ + "/test/" + ], + "coverageReporters": [ + "json", + "lcov", + "text", + "clover" + ], + "testMatch": [ + "**/test/**/*.spec.*" + ] + } +} diff --git a/node_modules/properties-reader/src/properties-reader-factory.js b/node_modules/properties-reader/src/properties-reader-factory.js new file mode 100644 index 0000000..0364c27 --- /dev/null +++ b/node_modules/properties-reader/src/properties-reader-factory.js @@ -0,0 +1,9 @@ + +const PropertiesReader = require('./properties-reader'); + +module.exports = function propertiesReaderFactory (sourceFile, encoding, options) { + + return new PropertiesReader(sourceFile, encoding, options); + +}; + diff --git a/node_modules/properties-reader/src/properties-reader.js b/node_modules/properties-reader/src/properties-reader.js new file mode 100644 index 0000000..4a5be60 --- /dev/null +++ b/node_modules/properties-reader/src/properties-reader.js @@ -0,0 +1,353 @@ +const {readFileSync, statSync} = require('fs'); +const propertyAppender = require('./property-appender').propertyAppender; +const propertyWriter = require('./property-writer').propertyWriter; + +const has = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); + +const SECTION = Symbol('SECTION'); + +function PropertiesReader (sourceFile, encoding, options = {}) { + this._encoding = typeof encoding === 'string' && encoding || 'utf-8'; + this._properties = {}; + this._propertiesExpanded = {}; + + this.appender(options.appender || options); + this.writer(options.writer || options); + this.append(sourceFile, encoding); +} + +/** + * @type {String} The name of a section that should be prefixed on an property as it is added + * @ignore + */ +PropertiesReader.prototype[SECTION] = ''; + +/** + * Gets the number of properties that have been read into this PropertiesReader. + * + * @name PropertiesReader#length + * @type {Number} + */ +Object.defineProperty(PropertiesReader.prototype, 'length', { + configurable: false, + enumerable: false, + get () { + return Object.keys(this._properties).length; + } +}); + +/** + * Define the property appending mechanism to be used by the instance. + * + * By default, duplicate sections will be collapsed when saving the properties. To disable this + * feature, set the `allowDuplicateSections` appender configuration to `true`: + * + * ``` +const properties = propertiesReader('file.ini', 'utf-8', { allowDuplicateSections: true }); +const properties = propertiesReader('file.ini').appender({ allowDuplicateSections: true }); +``` + * + * @param appender + * @returns {PropertiesReader} + */ +PropertiesReader.prototype.appender = function (appender) { + if (typeof appender === 'function') { + this._propertyAppender = appender; + } + else if (typeof appender === 'object') { + this._propertyAppender = propertyAppender(appender); + } + + return this; +}; + +/** + * Define the property appending mechanism to be used by the instance. + * + * By default, duplicate sections will be collapsed when saving the properties. To disable this + * feature, set the `allowDuplicateSections` appender configuration to `true`: + * + * ``` +const properties = propertiesReader('file.ini', 'utf-8', { allowDuplicateSections: true }); +const properties = propertiesReader('file.ini').appender({ allowDuplicateSections: true }); +``` + * + * @param writer + * @returns {PropertiesReader} + */ +PropertiesReader.prototype.writer = function (writer) { + if (typeof writer === 'function') { + this._propertyWriter = writer; + } + else if (typeof writer === 'object') { + this._propertyWriter = propertyWriter(writer); + } + + return this; +}; + +/** + * Append a file to the properties into the PropertiesReader + * + * @param {string} sourceFile + * @param {string} [encoding='utf-8'] + * + * @return {PropertiesReader} this instance + */ +PropertiesReader.prototype.append = function (sourceFile, encoding) { + + if (sourceFile) { + this.read(readFileSync(sourceFile, typeof encoding === 'string' && encoding || this._encoding)); + } + + return this; +}; + +/** + * Reads any string input into the PropertiesReader + * + * @param {String} input + * @return {PropertiesReader} this instance + */ +PropertiesReader.prototype.read = function (input) { + delete this[SECTION]; + ('' + input).split('\n').forEach(this._readLine, this); + return this; +}; + +/** + * Used as a processor for the array of input lines when reading from a source file + * @param {String} propertyString + */ +PropertiesReader.prototype._readLine = function (propertyString) { + if (!!(propertyString = propertyString.trim())) { + var section = /^\[([^=]+)]$/.exec(propertyString); + var property = !section && /^([^#=]+)(={0,1})(.*)$/.exec(propertyString); + + if (section) { + this[SECTION] = section[1]; + } + else if (property) { + section = this[SECTION] ? this[SECTION] + '.' : ''; + this.set(section + property[1].trim(), property[3].trim()); + } + } +}; + +/** + * Calls the supplied function for each property + * + * @param {Function} fn + * @param {Object} scope + * @return {PropertiesReader} + */ +PropertiesReader.prototype.each = function (fn, scope) { + for (var key in this._properties) { + if (this._properties.hasOwnProperty(key)) { + fn.call(scope || this, key, this._properties[key]); + } + } + return this; +}; + +/** + * Given the supplied raw value, returns the parsed value + */ +PropertiesReader.prototype._parsed = function (value) { + + if (value !== null && value !== '' && !isNaN(value)) { + return +value; + } + + if (value === 'true' || value === 'false') { + return value === 'true'; + } + + if (typeof value === "string") { + var replacements = {'\\n': '\n', '\\r': '\r', '\\t': '\t'}; + return value.replace(/\\[nrt]/g, function (key) { + return replacements[key]; + }); + } + + return value; +}; + +/** + * Gets a single property value based on the full string key. When the property is not found in the + * PropertiesReader, the return value will be null. + * + * @param {String} key + * @return {*} + */ +PropertiesReader.prototype.get = function (key) { + return this._parsed(this.getRaw(key)); +}; + +/** + * Gets the string representation as it was read from the properties file without coercions for type recognition. + * + * @param {string} key + * @returns {string} + */ +PropertiesReader.prototype.getRaw = function (key) { + return this._properties.hasOwnProperty(key) ? this._properties[key] : null; +}; + +/** + * Sets the supplied key in the properties store with the supplied value, the value can be any string representation + * that would be valid in a properties file (eg: true and false or numbers are converted to their real values). + * + * @param {String} key + * @param {String} value + * @return {PropertiesReader} + */ +PropertiesReader.prototype.set = function (key, value) { + var parsedValue = ('' + value).trim(); + + this._properties = this._propertyAppender(this._properties, key, parsedValue); + + var expanded = key.split('.'); + var source = this._propertiesExpanded; + + while (expanded.length > 1) { + var step = expanded.shift(); + if (expanded.length >= 1 && typeof source[step] === 'string') { + source[step] = {'': source[step]}; + } + + if (!has(source, step)) { + Object.defineProperty(source, step, { value: {} }); + } + + source = source[step] + } + + if (typeof parsedValue === 'string' && typeof source[expanded[0]] === 'object') { + source[expanded[0]][''] = parsedValue; + } + else { + source[expanded[0]] = parsedValue; + } + + return this; +}; + +/** + * Gets the object that represents the exploded properties. + * + * Note that this object is currently mutable without the option to persist or interrogate changes. + * + * @return {*} + */ +PropertiesReader.prototype.path = function () { + return this._propertiesExpanded; +}; + +/** + * Gets the object that represents all properties. + * + * @returns {Object} + */ +PropertiesReader.prototype.getAllProperties = function () { + var properties = {}; + this.each(function (key, value) { + properties[key] = value; + }); + return properties; +}; + +/** + * Creates and returns a new PropertiesReader based on the values in this instance. + * @return {PropertiesReader} + */ +PropertiesReader.prototype.clone = function () { + var propertiesReader = new PropertiesReader(null); + this.each(propertiesReader.set, propertiesReader); + + return propertiesReader; +}; + +/** + * Return a json from a root properties + * @param root + * @returns {{}} + */ +PropertiesReader.prototype.getByRoot = function (root) { + var keys = Object.keys(this._properties); + var outObj = {}; + + for (var i = 0, prefixLength = String(root).length; i < keys.length; i++) { + var key = keys[i]; + + if (key.indexOf(root) === 0 && key.charAt(prefixLength) === '.') { + outObj[key.substr(prefixLength + 1)] = this.get(key); + } + } + + return outObj; +}; + +/** + * Binds the current properties object and all values in it to the supplied express app. + * + * @param {Object} app The express app (or any object that has a `set` function) + * @param {String} [basePath] The absolute prefix to use for all path properties - defaults to the cwd. + * @param {Boolean} [makePaths=false] When true will attempt to create the directory structure to any path property + */ +PropertiesReader.prototype.bindToExpress = function (app, basePath, makePaths) { + var Path = require('path'); + + if (!/\/$/.test(basePath = basePath || process.cwd())) { + basePath += '/'; + } + + this.each(function (key, value) { + if (value && /\.(path|dir)$/.test(key)) { + value = Path.resolve(basePath, value); + this.set(key, value); + + try { + var directoryPath = /dir$/.test(key) ? value : Path.dirname(value); + if (makePaths) { + require('mkdirp').sync(directoryPath); + } + else if (!statSync(directoryPath).isDirectory()) { + throw new Error("Path is not a directory that already exists"); + } + } + catch (e) { + throw new Error("Unable to create directory " + value); + } + } + + app.set(key, this.get(key)); + + if (/^browser\./.test(key)) { + app.locals[key.substr(8)] = this.get(key); + } + }, this); + + app.set('properties', this); + + return this; +}; + +/** + * Stringify properties + * + * @returns {string[]} array of stringified properties + */ + + +/** + * Write properties into the file + * + * @param {String} destFile + * @param {Function} onComplete callback + */ +PropertiesReader.prototype.save = function (destFile, onComplete) { + return this._propertyWriter(this, destFile, onComplete); +}; + +module.exports = PropertiesReader; diff --git a/node_modules/properties-reader/src/property-appender.js b/node_modules/properties-reader/src/property-appender.js new file mode 100644 index 0000000..d8db71d --- /dev/null +++ b/node_modules/properties-reader/src/property-appender.js @@ -0,0 +1,89 @@ +var defaultOptions = { + + allowDuplicateSections: false, + +}; + +function simplePropertyAppender (properties, key, value) { + + properties[key] = value; + + return properties; + +} + +function sectionCollapsePropertyAppender (properties, key, value) { + var output = {}; + var section = sectionFromPropertyName(key); + var existingKeys = Object.keys(properties); + + // no section in property name so just append it to the list + if (!section || !existingKeys.length) { + output[key] = value; + return Object.assign(properties, output); + } + + // has a section in the property name so append it in that section + var BEFORE = 1, DURING = 2, AFTER = 4; + var processing = BEFORE; + + existingKeys.forEach(function (processingKey) { + + var during = processing !== AFTER && processingKey.indexOf(section + '.') === 0; + + if (key === processingKey) { + properties[processingKey] = value; + processing = AFTER; + } + else if (processing === BEFORE && during) { + // starts to be DURING + processing = DURING; + } + else if (processing === DURING && !during) { + // is now after + output[key] = value; + processing = AFTER; + } + + output[processingKey] = properties[processingKey]; + + }); + + if (processing !== AFTER) { + output[key] = value; + } + + return output; + +} + +function sectionFromPropertyName (name) { + var index = String(name).indexOf('.'); + return index > 0 && name.substr(0, index) || ''; +} + + +/** + * Builder method used to create a property appending function configured to the user + * requirements. + */ +function propertyAppender (userOptions) { + + var options = Object.assign({}, defaultOptions, userOptions || {}); + + if (options.allowDuplicateSections) { + return simplePropertyAppender; + } + + return sectionCollapsePropertyAppender; + +} + +module.exports = { + + defaultOptions: defaultOptions, + + propertyAppender: propertyAppender, + +}; + diff --git a/node_modules/properties-reader/src/property-writer.js b/node_modules/properties-reader/src/property-writer.js new file mode 100644 index 0000000..7c75cea --- /dev/null +++ b/node_modules/properties-reader/src/property-writer.js @@ -0,0 +1,60 @@ +const fs = require('fs'); + +const defaultOptions = { + saveSections: true, +}; + +function flat (props) { + const out = []; + props.each((key, value) => out.push(`${key}=${value}`)); + return out; +} + +function section (props) { + var lines = []; + var section = null; + props.each(function (key, value) { + var tokens = key.split('.'); + if (tokens.length > 1) { + if (section !== tokens[0]) { + section = tokens[0]; + lines.push('[' + section + ']'); + } + key = tokens.slice(1).join('.'); + } + else { + section = null; + } + + lines.push(key + '=' + value); + }); + return lines; +} + +module.exports.propertyWriter = function propertyWriter (userOptions) { + const options = Object.assign({}, defaultOptions, userOptions || {}); + + return (props, destFile, onComplete) => { + const onDone = new Promise((done, fail) => { + const content = (options.saveSections ? section(props) : flat(props)).join('\n'); + fs.writeFile(destFile, content, (err) => { + if (err) { + return fail(err); + } + + done(content); + }); + }); + + if (typeof onComplete === 'function') { + if (onComplete.length > 1) { + onDone.then(() => onComplete(null), (e) => onComplete(e)); + } + else { + onDone.then(onComplete) + } + } + + return onDone; + } +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..90deaab --- /dev/null +++ b/package-lock.json @@ -0,0 +1,51 @@ +{ + "name": "rudder-integration-appsflyer-android", + "version": "2.2.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "2.2.0", + "dependencies": { + "properties-reader": "^2.2.0" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/properties-reader": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/properties-reader/-/properties-reader-2.2.0.tgz", + "integrity": "sha512-CgVcr8MwGoBKK24r9TwHfZkLLaNFHQ6y4wgT9w/XzdpacOOi5ciH4hcuLechSDAwXsfrGQtI2JTutY2djOx2Ow==", + "dependencies": { + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=10" + } + } + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "properties-reader": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/properties-reader/-/properties-reader-2.2.0.tgz", + "integrity": "sha512-CgVcr8MwGoBKK24r9TwHfZkLLaNFHQ6y4wgT9w/XzdpacOOi5ciH4hcuLechSDAwXsfrGQtI2JTutY2djOx2Ow==", + "requires": { + "mkdirp": "^1.0.4" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..7c67dcb --- /dev/null +++ b/package.json @@ -0,0 +1 @@ +{"version":"2.2.0","dependencies":{"properties-reader":"^2.2.0"}} \ No newline at end of file diff --git a/sample-kotlin/build.gradle b/sample-kotlin/build.gradle index bad77f0..aed2bfb 100644 --- a/sample-kotlin/build.gradle +++ b/sample-kotlin/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10" } } @@ -45,7 +45,7 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10" implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'