├── .gitattributes ├── .github └── workflows │ ├── build_deploy_java_language_bindings.yml │ ├── go_pr_check.yml │ ├── issues-to-project.yml │ ├── java_pr_check.yml │ ├── rust_crate_publish.yml │ ├── rust_pr_check.yml │ ├── typescript_package_publish.yml │ ├── typescript_pr_check.yml │ └── validate_json.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── models ├── golang │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── tests │ │ └── gbfsv30_test.go │ └── v3.0 │ │ ├── gbfs │ │ └── gbfs.go │ │ ├── gbfs_versions │ │ └── gbfs_versions.go │ │ ├── geofencing_zones │ │ └── geofencing_zones.go │ │ ├── manifest │ │ └── manifest.go │ │ ├── station_information │ │ └── station_information.go │ │ ├── station_status │ │ └── station_status.go │ │ ├── system_alerts │ │ └── system_alerts.go │ │ ├── system_information │ │ └── system_information.go │ │ ├── system_pricing_plans │ │ └── system_pricing_plans.go │ │ ├── system_regions │ │ └── system_regions.go │ │ ├── vehicle_status │ │ └── vehicle_status.go │ │ └── vehicle_types │ │ └── vehicle_types.go ├── java │ ├── README.md │ ├── gbfs-java-model │ │ ├── bin │ │ │ └── schema-to-subfolders.sh │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── mobilitydata │ │ │ │ └── gbfs │ │ │ │ ├── v2_2 │ │ │ │ └── gbfs │ │ │ │ │ ├── GBFS.java │ │ │ │ │ ├── GBFSFeed.java │ │ │ │ │ ├── GBFSFeedName.java │ │ │ │ │ └── GBFSFeeds.java │ │ │ │ ├── v2_3 │ │ │ │ └── gbfs │ │ │ │ │ ├── GBFS.java │ │ │ │ │ ├── GBFSFeed.java │ │ │ │ │ ├── GBFSFeedName.java │ │ │ │ │ └── GBFSFeeds.java │ │ │ │ └── v3_0 │ │ │ │ └── gbfs │ │ │ │ └── GBFSFeedName.java │ │ │ └── test │ │ │ ├── java │ │ │ └── org │ │ │ │ └── mobilitydata │ │ │ │ └── gbfs │ │ │ │ ├── TestBase.java │ │ │ │ ├── v2_2 │ │ │ │ ├── free_bike_status │ │ │ │ │ └── FreeBikeStatusTest.java │ │ │ │ ├── gbfs │ │ │ │ │ ├── GBFSFeedNameTest.java │ │ │ │ │ └── GBFSTest.java │ │ │ │ ├── gbfs_versions │ │ │ │ │ └── GBFSVersionsTest.java │ │ │ │ ├── geofencing_zones │ │ │ │ │ └── GeofencingZonesTest.java │ │ │ │ ├── station_information │ │ │ │ │ └── StationInformationTest.java │ │ │ │ ├── station_status │ │ │ │ │ └── StationStatusTest.java │ │ │ │ ├── system_alerts │ │ │ │ │ └── SystemAlertsTest.java │ │ │ │ ├── system_calendar │ │ │ │ │ └── SystemCalendarTest.java │ │ │ │ ├── system_hours │ │ │ │ │ └── SystemHoursTest.java │ │ │ │ ├── system_information │ │ │ │ │ └── SystemInformationTest.java │ │ │ │ ├── system_pricing_plans │ │ │ │ │ └── SystemPricingPlansTest.java │ │ │ │ ├── system_regions │ │ │ │ │ └── SystemRegionsTest.java │ │ │ │ └── vehicle_types │ │ │ │ │ └── VehicleTypesTest.java │ │ │ │ ├── v2_3 │ │ │ │ ├── free_bike_status │ │ │ │ │ └── FreeBikeStatusTest.java │ │ │ │ ├── gbfs │ │ │ │ │ ├── GBFSFeedNameTest.java │ │ │ │ │ └── GBFSTest.java │ │ │ │ ├── gbfs_versions │ │ │ │ │ └── GBFSVersionsTest.java │ │ │ │ ├── geofencing_zones │ │ │ │ │ └── GeofencingZonesTest.java │ │ │ │ ├── station_information │ │ │ │ │ └── StationInformationTest.java │ │ │ │ ├── station_status │ │ │ │ │ └── StationStatusTest.java │ │ │ │ ├── system_alerts │ │ │ │ │ └── SystemAlertsTest.java │ │ │ │ ├── system_calendar │ │ │ │ │ └── SystemCalendarTest.java │ │ │ │ ├── system_hours │ │ │ │ │ └── SystemHoursTest.java │ │ │ │ ├── system_information │ │ │ │ │ └── SystemInformationTest.java │ │ │ │ ├── system_pricing_plans │ │ │ │ │ └── SystemPricingPlansTest.java │ │ │ │ ├── system_regions │ │ │ │ │ └── SystemRegionsTest.java │ │ │ │ └── vehicle_types │ │ │ │ │ └── VehicleTypesTest.java │ │ │ │ └── v3_0 │ │ │ │ ├── gbfs │ │ │ │ ├── GBFSFeedNameTest.java │ │ │ │ └── GBFSTest.java │ │ │ │ ├── gbfs_versions │ │ │ │ └── GBFSVersionsTest.java │ │ │ │ ├── geofencing_zones │ │ │ │ └── GeofencingZonesTest.java │ │ │ │ ├── manifest │ │ │ │ └── ManifestTest.java │ │ │ │ ├── station_information │ │ │ │ └── StationInformationTest.java │ │ │ │ ├── station_status │ │ │ │ └── StationStatusTest.java │ │ │ │ ├── system_alerts │ │ │ │ └── SystemAlertsTest.java │ │ │ │ ├── system_information │ │ │ │ └── SystemInformationTest.java │ │ │ │ ├── system_pricing_plans │ │ │ │ └── SystemPricingPlansTest.java │ │ │ │ ├── system_regions │ │ │ │ └── SystemRegionsTest.java │ │ │ │ ├── vehicle_status │ │ │ │ └── VehicleStatusTest.java │ │ │ │ └── vehicle_types │ │ │ │ └── VehicleTypesTest.java │ │ │ └── resources │ │ │ ├── v2_X │ │ │ ├── free_bike_status.json │ │ │ ├── gbfs.json │ │ │ ├── gbfs_versions.json │ │ │ ├── geofencing_zones.json │ │ │ ├── station_information.json │ │ │ ├── station_status.json │ │ │ ├── system_alerts.json │ │ │ ├── system_calendar.json │ │ │ ├── system_hours.json │ │ │ ├── system_information.json │ │ │ ├── system_pricing_plans.json │ │ │ ├── system_regions.json │ │ │ └── vehicle_types.json │ │ │ └── v3_0 │ │ │ ├── gbfs.json │ │ │ ├── gbfs_versions.json │ │ │ ├── geofencing_zones.json │ │ │ ├── manifest.json │ │ │ ├── station_information.json │ │ │ ├── station_status.json │ │ │ ├── system_alerts.json │ │ │ ├── system_information.json │ │ │ ├── system_pricing_plans.json │ │ │ ├── system_regions.json │ │ │ ├── vehicle_status.json │ │ │ └── vehicle_types.json │ ├── pom.xml │ └── rule-factory │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── mobilitydata │ │ └── gbfs │ │ └── GeofencingRuleFactory.java ├── openapi │ ├── README.md │ ├── v2.3 │ │ └── openapi.yaml │ └── v3.0 │ │ └── openapi.yaml ├── rust │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── 3.0 │ │ ├── files │ │ │ ├── examples │ │ │ │ └── specification │ │ │ │ │ ├── gbfs.json │ │ │ │ │ ├── gbfs_versions.json │ │ │ │ │ ├── geofencing_zones.json │ │ │ │ │ ├── manifest.json │ │ │ │ │ ├── station_information-1.json │ │ │ │ │ ├── station_information-2.json │ │ │ │ │ ├── station_information-3.json │ │ │ │ │ ├── station_status.json │ │ │ │ │ ├── system_alerts.json │ │ │ │ │ ├── system_information-1.json │ │ │ │ │ ├── system_information-2.json │ │ │ │ │ ├── system_pricing_plans-1.json │ │ │ │ │ ├── system_pricing_plans-2.json │ │ │ │ │ ├── system_regions.json │ │ │ │ │ ├── vehicle_status-1.json │ │ │ │ │ ├── vehicle_status-2.json │ │ │ │ │ └── vehicle_types.json │ │ │ ├── gbfs.rs │ │ │ ├── gbfs_versions.rs │ │ │ ├── geofencing_zones.rs │ │ │ ├── manifest.rs │ │ │ ├── mod.rs │ │ │ ├── station_information.rs │ │ │ ├── station_status.rs │ │ │ ├── system_alerts.rs │ │ │ ├── system_information.rs │ │ │ ├── system_pricing_plans.rs │ │ │ ├── system_regions.rs │ │ │ ├── vehicle_status.rs │ │ │ └── vehicle_types.rs │ │ ├── mod.rs │ │ ├── types.rs │ │ └── urls.rs │ │ └── lib.rs └── typescript │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── index.d.ts │ ├── jest.config.js │ ├── package.json │ ├── tests │ ├── v2.3.spec.ts │ ├── v3.0.spec.ts │ └── v3.1-RC.spec.ts │ ├── tsconfig.json │ ├── v2.3 │ └── index.d.ts │ ├── v3.0 │ └── index.d.ts │ ├── v3.1-RC │ └── index.d.ts │ └── yarn.lock ├── scripts ├── copyright.txt ├── generate_go_models.sh ├── generate_typescript_models.sh ├── package.json └── yarn.lock ├── testFixtures ├── v2.3 │ ├── free_bike_status.json │ ├── gbfs.json │ ├── gbfs_versions.json │ ├── geofencing_zones.json │ ├── station_information.json │ ├── station_status.json │ ├── system_alerts.json │ ├── system_calendar.json │ ├── system_hours.json │ ├── system_information.json │ ├── system_pricing_plans.json │ ├── system_regions.json │ └── vehicle_types.json ├── v3.0 │ ├── gbfs.json │ ├── gbfs_versions.json │ ├── geofencing_zones.json │ ├── manifest.json │ ├── station_information.json │ ├── station_status.json │ ├── system_alerts.json │ ├── system_information.json │ ├── system_pricing_plans.json │ ├── system_regions.json │ ├── vehicle_status.json │ └── vehicle_types.json └── v3.1-RC │ ├── gbfs.json │ ├── gbfs_versions.json │ ├── geofencing_zones.json │ ├── manifest.json │ ├── station_information.json │ ├── station_status.json │ ├── system_alerts.json │ ├── system_information.json │ ├── system_pricing_plans.json │ ├── system_regions.json │ ├── vehicle_status.json │ └── vehicle_types.json ├── v1.0 ├── free_bike_status.json ├── gbfs.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_calendar.json ├── system_hours.json ├── system_information.json ├── system_pricing_plans.json └── system_regions.json ├── v1.1 ├── free_bike_status.json ├── gbfs.json ├── gbfs_versions.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_calendar.json ├── system_hours.json ├── system_information.json ├── system_pricing_plans.json └── system_regions.json ├── v2.0 ├── free_bike_status.json ├── gbfs.json ├── gbfs_versions.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_calendar.json ├── system_hours.json ├── system_information.json ├── system_pricing_plans.json └── system_regions.json ├── v2.1 ├── free_bike_status.json ├── gbfs.json ├── gbfs_versions.json ├── geofencing_zones.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_calendar.json ├── system_hours.json ├── system_information.json ├── system_pricing_plans.json ├── system_regions.json └── vehicle_types.json ├── v2.2 ├── free_bike_status.json ├── gbfs.json ├── gbfs_versions.json ├── geofencing_zones.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_calendar.json ├── system_hours.json ├── system_information.json ├── system_pricing_plans.json ├── system_regions.json └── vehicle_types.json ├── v2.3 ├── free_bike_status.json ├── gbfs.json ├── gbfs_versions.json ├── geofencing_zones.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_calendar.json ├── system_hours.json ├── system_information.json ├── system_pricing_plans.json ├── system_regions.json └── vehicle_types.json ├── v3.0 ├── gbfs.json ├── gbfs_versions.json ├── geofencing_zones.json ├── manifest.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_information.json ├── system_pricing_plans.json ├── system_regions.json ├── vehicle_status.json └── vehicle_types.json └── v3.1-RC ├── gbfs.json ├── gbfs_versions.json ├── geofencing_zones.json ├── manifest.json ├── station_information.json ├── station_status.json ├── system_alerts.json ├── system_information.json ├── system_pricing_plans.json ├── system_regions.json ├── vehicle_status.json └── vehicle_types.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/build_deploy_java_language_bindings.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy Java Language Bindings 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - "models/java/**" 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | defaults: 14 | run: 15 | working-directory: ./models/java 16 | 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v2 20 | 21 | - name: Load secrets from 1Password 22 | id: onepw_secrets 23 | uses: 1password/load-secrets-action@v2.0.0 24 | with: 25 | export-env: true # Export loaded secrets as environment variables 26 | env: 27 | OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} # This is required to connect to the vault in our 1Password account. 28 | MAVEN_GPG_PRIVATE_KEY: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/dkkfywvsr3xq6eyeubq6cldaxi/Private Key" 29 | MAVEN_GPG_PASSPHRASE: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/dkkfywvsr3xq6eyeubq6cldaxi/password" 30 | MAVEN_USERNAME: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/4o43n5uyr7zjog6u2y5i3fjzye/username" 31 | MAVEN_PASSWORD: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/4o43n5uyr7zjog6u2y5i3fjzye/credential" 32 | 33 | - name: Set up JDK 34 | uses: actions/setup-java@v4 35 | with: 36 | java-version: '17.0.11' 37 | distribution: 'temurin' 38 | server-id: ossrh 39 | server-username: MAVEN_USERNAME 40 | server-password: MAVEN_PASSWORD 41 | gpg-private-key: ${{ env.MAVEN_GPG_PRIVATE_KEY }} 42 | gpg-passphrase: ${{ env.MAVEN_GPG_PASSPHRASE }} 43 | 44 | - name: Build and package 45 | run: | 46 | mvn install -pl rule-factory 47 | 48 | - name: Deploy with Maven 49 | run: mvn -B clean deploy -pl gbfs-java-model -P release 50 | env: 51 | MAVEN_GPG_PASSPHRASE: ${{ env.MAVEN_GPG_PASSPHRASE }} 52 | MAVEN_USERNAME: ${{ env.MAVEN_USERNAME }} 53 | MAVEN_PASSWORD: ${{ env.MAVEN_PASSWORD }} 54 | 55 | -------------------------------------------------------------------------------- /.github/workflows/go_pr_check.yml: -------------------------------------------------------------------------------- 1 | name: GBFS Golang Language Bindings - PR Check 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | paths: 8 | - "models/golang/**" 9 | 10 | jobs: 11 | test: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v2 17 | 18 | - name: Set up Go 19 | uses: actions/setup-go@v2 20 | with: 21 | go-version: 1.22.3 22 | 23 | - name: Run tests 24 | run: | 25 | cd models/golang/tests 26 | go test -v -------------------------------------------------------------------------------- /.github/workflows/issues-to-project.yml: -------------------------------------------------------------------------------- 1 | name: Add issues to project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | add-to-project: 10 | name: Add issue to project 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/add-to-project@v0.4.0 14 | with: 15 | # You can target a repository in a different organization 16 | # to the issue 17 | project-url: https://github.com/orgs/MobilityData/projects/58 18 | github-token: ${{ secrets.GBFS_REPOS_CURRENT_STATUS }} 19 | -------------------------------------------------------------------------------- /.github/workflows/rust_crate_publish.yml: -------------------------------------------------------------------------------- 1 | name: GBFS Rust Language Bindings - Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - "models/rust/**" 9 | jobs: 10 | build-publish: 11 | name: build-publish-job 12 | runs-on: ubuntu-latest 13 | defaults: 14 | run: 15 | working-directory: ./models/rust 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v2 20 | 21 | - name: Load secrets from 1Password 22 | uses: 1password/load-secrets-action@v2.0.0 23 | with: 24 | export-env: true # Export loaded secrets as environment variables 25 | env: 26 | OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} 27 | CARGO_REGISTRY_TOKEN: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/ms6rxv2lhpok44mg32wuihbv7q/credential" 28 | 29 | - name: Publish to crates.io 30 | env: 31 | CARGO_REGISTRY_TOKEN: ${{ env.CARGO_REGISTRY_TOKEN }} 32 | run: cargo publish --token $CARGO_REGISTRY_TOKEN 33 | 34 | -------------------------------------------------------------------------------- /.github/workflows/typescript_package_publish.yml: -------------------------------------------------------------------------------- 1 | name: GBFS Typescript Language Bindings - Publish 2 | 3 | on: 4 | workflow_dispatch: 5 | workflow_call: 6 | push: 7 | branches: 8 | - master 9 | paths: 10 | - "models/typescript/**" 11 | jobs: 12 | build-publish: 13 | name: build-publish-job 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v2 19 | 20 | - name: Setup Node.js 21 | uses: actions/setup-node@v2 22 | with: 23 | node-version: '18' 24 | registry-url: 'https://registry.npmjs.org' 25 | 26 | - name: Install dependencies 27 | run: | 28 | cd ./scripts 29 | yarn 30 | 31 | - name: Load secrets from 1Password 32 | uses: 1password/load-secrets-action@v2.0.0 33 | with: 34 | export-env: true # Export loaded secrets as environment variables 35 | env: 36 | OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} 37 | NODE_AUTH_TOKEN: "op://rbiv7rvkkrsdlpcrz3bmv7nmcu/ppzc4jxrwkf3omdmcs7z2wiwum/credential" 38 | 39 | - name: Publish to npm 40 | run: cd ./models/typescript && npm publish 41 | env: 42 | NODE_AUTH_TOKEN: ${{ env.NODE_AUTH_TOKEN }} 43 | 44 | -------------------------------------------------------------------------------- /.github/workflows/typescript_pr_check.yml: -------------------------------------------------------------------------------- 1 | name: GBFS Typescript Language Bindings - PR Check 2 | on: 3 | pull_request: 4 | branches: 5 | - master 6 | paths: 7 | - "models/typescript/**" 8 | 9 | jobs: 10 | check-versions: 11 | name: check-version-job 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v2 17 | 18 | - name: Get local branch package.json version 19 | id: get_local_version 20 | run: echo "version=$(jq -r '.version' models/typescript/package.json)" >> $GITHUB_OUTPUT 21 | 22 | - name: Get master branch package.json version 23 | id: get_master_version 24 | run: | 25 | git fetch origin master 26 | echo "master_version=$(git show origin/master:models/typescript/package.json | jq -r '.version')" >> $GITHUB_OUTPUT 27 | 28 | - name: Compare versions 29 | env: 30 | local_version: ${{ steps.get_local_version.outputs.version }} 31 | master_version: ${{ steps.get_master_version.outputs.master_version }} 32 | run: | 33 | if [ "$local_version" != "$master_version" ]; then 34 | echo "Local branch version ($local_version) is different from master branch version ($master_version)" 35 | else 36 | echo "Local branch version ($local_version) is the same as master branch version ($master_version)" 37 | echo "Please update the package.json version so that your changes will be published." 38 | exit 1 39 | fi 40 | run-tests: 41 | name: run-tests-job 42 | runs-on: ubuntu-latest 43 | 44 | steps: 45 | - name: Checkout repository 46 | uses: actions/checkout@v2 47 | 48 | - name: Setup Node.js 49 | uses: actions/setup-node@v2 50 | with: 51 | node-version: '18' 52 | 53 | - name: Install dependencies 54 | run: | 55 | cd ./scripts 56 | yarn 57 | cd ../models/typescript 58 | yarn 59 | 60 | - name: Run tests 61 | run: cd ./models/typescript && yarn test 62 | -------------------------------------------------------------------------------- /.github/workflows/validate_json.yml: -------------------------------------------------------------------------------- 1 | name: Validate JSON Schema files 2 | on: [push] 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: Setup python 9 | uses: actions/setup-python@v2 10 | with: 11 | python-version: '3.x' 12 | - name: Install jsonschema 13 | run: pip install jsonschema==3.2.0 14 | - run: | 15 | for i in **/*.json; do 16 | echo "Validating $i" 17 | jsonschema $i 18 | done 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all IDEA files. Comment out the following line if you wish to ignore only particular files (listed below). 2 | .idea/ 3 | 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 5 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 6 | 7 | # User-specific stuff 8 | .idea/**/modules.xml 9 | .idea/**/workspace.xml 10 | .idea/**/tasks.xml 11 | .idea/**/usage.statistics.xml 12 | .idea/**/dictionaries 13 | .idea/**/shelf 14 | 15 | # Generated files 16 | .idea/**/contentModel.xml 17 | 18 | # Sensitive or high-churn files 19 | .idea/**/dataSources/ 20 | .idea/**/dataSources.ids 21 | .idea/**/dataSources.local.xml 22 | .idea/**/sqlDataSources.xml 23 | .idea/**/dynamic.xml 24 | .idea/**/uiDesigner.xml 25 | .idea/**/dbnavigator.xml 26 | 27 | # Gradle 28 | .idea/**/gradle.xml 29 | .idea/**/libraries 30 | 31 | # Gradle and Maven with auto-import 32 | # When using Gradle or Maven with auto-import, you should exclude module files, 33 | # since they will be recreated, and may cause churn. Uncomment if using 34 | # auto-import. 35 | .idea/artifacts 36 | .idea/compiler.xml 37 | .idea/jarRepositories.xml 38 | .idea/modules.xml 39 | .idea/*.iml 40 | .idea/modules 41 | *.iml 42 | *.ipr 43 | 44 | # CMake 45 | cmake-build-*/ 46 | 47 | # Mongo Explorer plugin 48 | .idea/**/mongoSettings.xml 49 | 50 | # File-based project format 51 | *.iws 52 | 53 | # IntelliJ 54 | out/ 55 | 56 | # mpeltonen/sbt-idea plugin 57 | .idea_modules/ 58 | 59 | # JIRA plugin 60 | atlassian-ide-plugin.xml 61 | 62 | # Cursive Clojure plugin 63 | .idea/replstate.xml 64 | 65 | # Crashlytics plugin (for Android Studio and IntelliJ) 66 | com_crashlytics_export_strings.xml 67 | crashlytics.properties 68 | crashlytics-build.properties 69 | fabric.properties 70 | 71 | # Editor-based Rest Client 72 | .idea/httpRequests 73 | 74 | # Android studio 3.1+ serialized cache file 75 | .idea/caches/build_file_checksums.ser 76 | 77 | # Gradle 78 | .gradle 79 | build/ 80 | 81 | # Inputs and outputs 82 | input/ 83 | output/ 84 | 85 | # Mac 86 | */.DS_Store 87 | .DS_Store 88 | 89 | # Node Modules 90 | models/typescript/node_modules/* 91 | scripts/node_modules/* 92 | 93 | models/java/gbfs-java-model/target/* 94 | models/java/gbfs-java-model/resources/* 95 | models/java/rule-factory/target/* 96 | *.iml 97 | /target 98 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Want to contribute? Great! First, read this page (including the small print at the end). 2 | 3 | ### Before you contribute 4 | Before we can use your code, you must sign the 5 | [MobilityData Individual Contributor License Agreement](https://gist.github.com/barbeau/c4c2b76c40d08db13b6a58bf52666e86#file-mobilitydata-contributor-license-agreement-agreement) 6 | (CLA), which you can do online by clicking on a link after you open a pull request. 7 | The CLA is necessary mainly because you own the copyright to your changes, even 8 | after your contribution becomes part of our codebase, so we need your permission 9 | to use and distribute your code. We also need to be sure of various other things— 10 | for instance that you'll tell us if you know that your code infringes on other 11 | people's patents. You don't have to sign the CLA until after you've submitted your 12 | code for review and a member has approved it, but you must do it before we can put 13 | your code into our codebase. Before you start working on a larger contribution, you 14 | should get in touch with us first through the issue tracker with your idea so that we 15 | can help out and possibly guide you. Coordinating up front makes it much easier to avoid 16 | frustration later on. 17 | 18 | ### Code reviews 19 | All submissions, including submissions by project members, require review. We 20 | use Github pull requests for this purpose. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gbfs-json-schema 2 | JSON Schema for [General Bikeshare Feed Specification (GBFS)](https://github.com/MobilityData/gbfs/blob/master/gbfs.md) feeds, managed by MobilityData. The [gbfs-validator](https://github.com/MobilityData/gbfs-validator) links directly to them. 3 | 4 | ## Language Bindings 5 | 6 | * [Golang](models/golang/README.md) 7 | * [Java](models/java/README.md) 8 | * [OpenAPI](models/openapi/README.md) 9 | * [TypeScript](models/typescript/README.md) 10 | * [Rust](models/rust/README.md) 11 | 12 | Are we missing your favorite language? Consider contributing: 13 | 14 | 1. Read [CONTRIBUTING.md](CONTRIBUTING.md). 15 | 2. Open a pull request with your language of choice. Please include update instructions (ideally, scripts). Also, provide packaging suitable for the language ecosystem. 16 | -------------------------------------------------------------------------------- /models/golang/README.md: -------------------------------------------------------------------------------- 1 | # Golang GBFS Language Bindings 2 | 3 | Golang types for parsing and working with General Bikeshare Feed Specification (GBFS) data, ensuring type safety and code consistency in Golang projects. 4 | 5 | ## Add the Dependency 6 | 7 | To use the `gbfs-language-bindings` structs in your own project, you need to 8 | first install this library with: 9 | 10 | ``` 11 | go get github.com/MobilityData/gbfs-json-schema/models/golang 12 | ``` 13 | 14 | ## Versions 15 | Currently only version 3.0 of GBFS is supported 16 | 17 | ## Example Code 18 | Using the pre-build unmarshaller 19 | ```go 20 | import( 21 | "net/http" 22 | "io" 23 | v30systemInformation "github.com/MobilityData/gbfs-json-schema/models/golang/v3.0/system_information" 24 | ) 25 | const url = "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/system-information"; 26 | resp, err := http.Get(url) 27 | defer resp.Body.Close() 28 | body, err := io.ReadAll(resp.Body) 29 | systemInformationData, unmarshalError := v30systemInformation.UnmarshalSystemInformation(body) 30 | if unmarshalError != nil { 31 | // NOTE: If any type mismatch occurs (ex: number instead of string) it will show up as an error 32 | fmt.Println("Error unmarshelling:", err) 33 | } 34 | // systemInformationData is now typed as SystemInformation 35 | ``` 36 | Or you can do it manually 37 | ```go 38 | import( 39 | "net/http" 40 | "encoding/json" 41 | "io" 42 | v30systemInformation "github.com/MobilityData/gbfs-json-schema/models/golang/v3.0/system_information" 43 | ) 44 | const url = "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/system-information"; 45 | resp, errHttp := http.Get(url) 46 | defer resp.Body.Close() 47 | body, errRead := io.ReadAll(resp.Body) 48 | 49 | var systemInformationData v30systemInformation.SystemInformation 50 | errMarshel := json.Unmarshal(body, &systemInformationData) 51 | if errMarshel != nil { 52 | // NOTE: If any type mismatch occurs (ex: number instead of string) it will show up as an error 53 | fmt.Println("Error unmarshaling JSON:", err) 54 | } 55 | 56 | // systemInformationData is now typed as SystemInformation 57 | ``` 58 | 59 | ## Important to Note 60 | When unmarshalling data Golang sets defaults if the required value does not exist 61 | ``` 62 | int, int8, int16, int32, int64: 0 63 | uint, uint8 (byte), uint16, uint32, uint64: 0 64 | float32, float64: 0.0 65 | string: "" (empty string) 66 | bool: false 67 | Pointers, slices, maps, channels, functions, and interfaces: nil 68 | ``` 69 | -------------------------------------------------------------------------------- /models/golang/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/MobilityData/gbfs-json-schema/models/golang 2 | 3 | go 1.22.3 4 | 5 | require ( 6 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect 7 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 8 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect 9 | ) 10 | -------------------------------------------------------------------------------- /models/golang/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Kangaroux/go-map-schema v0.6.1 h1:jXpOzi7kNFC6M8QSvJuI7xeDxObBrVHwA3D6vSrxuG4= 2 | github.com/Kangaroux/go-map-schema v0.6.1/go.mod h1:56jN+6h/N8Pmn5D+JL9gREOvZTlVEAvXtXyLd/NRjh4= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 5 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 9 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 10 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 11 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= 12 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 13 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= 14 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= 15 | github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= 16 | github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 17 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 18 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 19 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/bin/schema-to-subfolders.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script copies the gbfs schemas to subfolders in the resources folder of the gbfs-java-model 4 | # Reason is to create separate packages for each gbfs file 5 | # Runs from models/java folder using 'mvn install' 6 | 7 | # brings the script to the root directory 8 | cd ../../.. 9 | 10 | # clears old resources 11 | rm -rf ./models/java/gbfs-java-model/resources 12 | 13 | output_path="./models/java/gbfs-java-model/resources/" 14 | path_to_schemas="." 15 | 16 | versions=("v3.0" "v2.3" "v2.2" "v2.1" "v2.0" "v1.1" "v1.0") 17 | 18 | echo "Start Schema to Subfolders Script" 19 | 20 | for version in "${versions[@]}"; do 21 | folder_path="$path_to_schemas/$version/" 22 | 23 | # Iterate over all the files in the folder of the gbfs version 24 | for file in "$folder_path"/* 25 | do 26 | # Extract the file name from the path and add it to the array 27 | file_name=$(basename "$file") 28 | file_name_no_extension="${file_name%.*}" 29 | 30 | output_file="$output_path$file_name_no_extension" 31 | 32 | mkdir -p "${output_path}/${version}/${file_name_no_extension}/" 33 | 34 | # Copy the file to the destination directory 35 | cp "$folder_path/$file_name" "${output_path}/${version}/${file_name_no_extension}/${file_name}" 36 | done 37 | done 38 | 39 | echo "End Schema to Subfolders Script" 40 | 41 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/main/java/org/mobilitydata/gbfs/v2_2/gbfs/GBFS.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.gbfs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | 6 | import java.io.Serializable; 7 | import java.util.Map; 8 | 9 | public class GBFS extends GBFSGbfs implements Serializable { 10 | 11 | @JsonProperty("data") 12 | @JsonPropertyDescription("Response data in the form of name:value pairs.") 13 | private Map data; 14 | 15 | 16 | @JsonProperty("data") 17 | public Map getFeedsData() { 18 | return data; 19 | } 20 | 21 | @JsonProperty("data") 22 | public void setFeedsData(Map data) { 23 | this.data = data; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | StringBuilder sb = new StringBuilder(); 29 | sb.append(GBFS.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); 30 | sb.append("lastUpdated"); 31 | sb.append('='); 32 | sb.append(((this.getLastUpdated() == null)?"":this.getLastUpdated())); 33 | sb.append(','); 34 | sb.append("ttl"); 35 | sb.append('='); 36 | sb.append(((this.getTtl() == null)?"":this.getTtl())); 37 | sb.append(','); 38 | sb.append("version"); 39 | sb.append('='); 40 | sb.append(((this.getVersion() == null)?"":this.getVersion())); 41 | sb.append(','); 42 | sb.append("data"); 43 | sb.append('='); 44 | sb.append(((this.data == null)?"":this.data)); 45 | sb.append(','); 46 | sb.append("additionalProperties"); 47 | sb.append('='); 48 | sb.append(((this.getAdditionalProperties() == null)?"":this.getAdditionalProperties())); 49 | sb.append(','); 50 | if (sb.charAt((sb.length()- 1)) == ',') { 51 | sb.setCharAt((sb.length()- 1), ']'); 52 | } else { 53 | sb.append(']'); 54 | } 55 | return sb.toString(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/main/java/org/mobilitydata/gbfs/v2_2/gbfs/GBFSFeed.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.gbfs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | 6 | import java.io.Serializable; 7 | import java.net.URI; 8 | 9 | public class GBFSFeed implements Serializable { 10 | 11 | /** 12 | * Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type. 13 | * (Required) 14 | * 15 | */ 16 | @JsonProperty("name") 17 | @JsonPropertyDescription("Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type.") 18 | private GBFSFeedName name; 19 | 20 | /** 21 | * URL for the feed. 22 | * (Required) 23 | * 24 | */ 25 | @JsonProperty("url") 26 | @JsonPropertyDescription("URL for the feed.") 27 | private URI url; 28 | 29 | /** 30 | * Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type. 31 | * (Required) 32 | * 33 | */ 34 | public GBFSFeedName getName() { 35 | return name; 36 | } 37 | 38 | /** 39 | * Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type. 40 | * (Required) 41 | * 42 | */ 43 | public void setName(GBFSFeedName name) { 44 | this.name = name; 45 | } 46 | 47 | /** 48 | * URL for the feed. 49 | * (Required) 50 | * 51 | */ 52 | public URI getUrl() { 53 | return url; 54 | } 55 | 56 | /** 57 | * URL for the feed. 58 | * (Required) 59 | * 60 | */ 61 | public void setUrl(URI url) { 62 | this.url = url; 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | StringBuilder sb = new StringBuilder(); 68 | sb.append(GBFSFeed.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); 69 | sb.append("name"); 70 | sb.append('='); 71 | sb.append(((this.name == null)?"":this.name)); 72 | sb.append(','); 73 | sb.append("url"); 74 | sb.append('='); 75 | sb.append(((this.url == null)?"":this.url.toString())); 76 | sb.append(','); 77 | if (sb.charAt((sb.length()- 1)) == ',') { 78 | sb.setCharAt((sb.length()- 1), ']'); 79 | } else { 80 | sb.append(']'); 81 | } 82 | return sb.toString(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/main/java/org/mobilitydata/gbfs/v2_2/gbfs/GBFSFeeds.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.gbfs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | public class GBFSFeeds implements Serializable { 10 | @JsonProperty("feeds") 11 | @JsonPropertyDescription("An array of all of the feeds that are published by the auto-discovery file. Each element in the array is an object with the keys below.") 12 | private List feeds; 13 | 14 | public List getFeeds() { 15 | return feeds; 16 | } 17 | 18 | public void setFeeds(List feeds) { 19 | this.feeds = feeds; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return "GBFSFeeds{" + 25 | "feeds=" + feeds + 26 | '}'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/main/java/org/mobilitydata/gbfs/v2_3/gbfs/GBFS.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.gbfs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | 6 | import java.io.Serializable; 7 | import java.util.Map; 8 | 9 | public class GBFS extends GBFSGbfs implements Serializable { 10 | 11 | @JsonProperty("data") 12 | @JsonPropertyDescription("Response data in the form of name:value pairs.") 13 | private Map data; 14 | 15 | 16 | @JsonProperty("data") 17 | public Map getFeedsData() { 18 | return data; 19 | } 20 | 21 | @JsonProperty("data") 22 | public void setFeedsData(Map data) { 23 | this.data = data; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | StringBuilder sb = new StringBuilder(); 29 | sb.append(GBFS.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); 30 | sb.append("lastUpdated"); 31 | sb.append('='); 32 | sb.append(((this.getLastUpdated() == null)?"":this.getLastUpdated())); 33 | sb.append(','); 34 | sb.append("ttl"); 35 | sb.append('='); 36 | sb.append(((this.getTtl() == null)?"":this.getTtl())); 37 | sb.append(','); 38 | sb.append("version"); 39 | sb.append('='); 40 | sb.append(((this.getVersion() == null)?"":this.getVersion())); 41 | sb.append(','); 42 | sb.append("data"); 43 | sb.append('='); 44 | sb.append(((this.data == null)?"":this.data)); 45 | sb.append(','); 46 | sb.append("additionalProperties"); 47 | sb.append('='); 48 | sb.append(((this.getAdditionalProperties() == null)?"":this.getAdditionalProperties())); 49 | sb.append(','); 50 | if (sb.charAt((sb.length()- 1)) == ',') { 51 | sb.setCharAt((sb.length()- 1), ']'); 52 | } else { 53 | sb.append(']'); 54 | } 55 | return sb.toString(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/main/java/org/mobilitydata/gbfs/v2_3/gbfs/GBFSFeed.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.gbfs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | 6 | import java.io.Serializable; 7 | import java.net.URI; 8 | 9 | public class GBFSFeed implements Serializable { 10 | 11 | /** 12 | * Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type. 13 | * (Required) 14 | * 15 | */ 16 | @JsonProperty("name") 17 | @JsonPropertyDescription("Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type.") 18 | private GBFSFeedName name; 19 | 20 | /** 21 | * URL for the feed. 22 | * (Required) 23 | * 24 | */ 25 | @JsonProperty("url") 26 | @JsonPropertyDescription("URL for the feed.") 27 | private URI url; 28 | 29 | /** 30 | * Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type. 31 | * (Required) 32 | * 33 | */ 34 | public GBFSFeedName getName() { 35 | return name; 36 | } 37 | 38 | /** 39 | * Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type. 40 | * (Required) 41 | * 42 | */ 43 | public void setName(GBFSFeedName name) { 44 | this.name = name; 45 | } 46 | 47 | /** 48 | * URL for the feed. 49 | * (Required) 50 | * 51 | */ 52 | public URI getUrl() { 53 | return url; 54 | } 55 | 56 | /** 57 | * URL for the feed. 58 | * (Required) 59 | * 60 | */ 61 | public void setUrl(URI url) { 62 | this.url = url; 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | StringBuilder sb = new StringBuilder(); 68 | sb.append(GBFSFeed.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); 69 | sb.append("name"); 70 | sb.append('='); 71 | sb.append(((this.name == null)?"":this.name)); 72 | sb.append(','); 73 | sb.append("url"); 74 | sb.append('='); 75 | sb.append(((this.url == null)?"":this.url.toString())); 76 | sb.append(','); 77 | if (sb.charAt((sb.length()- 1)) == ',') { 78 | sb.setCharAt((sb.length()- 1), ']'); 79 | } else { 80 | sb.append(']'); 81 | } 82 | return sb.toString(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/main/java/org/mobilitydata/gbfs/v2_3/gbfs/GBFSFeeds.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.gbfs; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.annotation.JsonPropertyDescription; 5 | 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | public class GBFSFeeds implements Serializable { 10 | @JsonProperty("feeds") 11 | @JsonPropertyDescription("An array of all of the feeds that are published by the auto-discovery file. Each element in the array is an object with the keys below.") 12 | private List feeds; 13 | 14 | public List getFeeds() { 15 | return feeds; 16 | } 17 | 18 | public void setFeeds(List feeds) { 19 | this.feeds = feeds; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return "GBFSFeeds{" + 25 | "feeds=" + feeds + 26 | '}'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/main/java/org/mobilitydata/gbfs/v3_0/gbfs/GBFSFeedName.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.gbfs; 2 | 3 | import org.mobilitydata.gbfs.v3_0.gbfs_versions.GBFSGbfsVersions; 4 | import org.mobilitydata.gbfs.v3_0.geofencing_zones.GBFSGeofencingZones; 5 | import org.mobilitydata.gbfs.v3_0.station_information.GBFSStationInformation; 6 | import org.mobilitydata.gbfs.v3_0.station_status.GBFSStationStatus; 7 | import org.mobilitydata.gbfs.v3_0.system_alerts.GBFSSystemAlerts; 8 | import org.mobilitydata.gbfs.v3_0.system_information.GBFSSystemInformation; 9 | import org.mobilitydata.gbfs.v3_0.system_pricing_plans.GBFSSystemPricingPlans; 10 | import org.mobilitydata.gbfs.v3_0.system_regions.GBFSSystemRegions; 11 | import org.mobilitydata.gbfs.v3_0.vehicle_status.GBFSVehicleStatus; 12 | import org.mobilitydata.gbfs.v3_0.vehicle_types.GBFSVehicleTypes; 13 | 14 | import java.util.EnumMap; 15 | import java.util.Map; 16 | import java.util.stream.Collectors; 17 | 18 | public class GBFSFeedName { 19 | private GBFSFeedName() {} 20 | 21 | 22 | private static final Map> feedNameMap = new EnumMap<>(GBFSFeed.Name.class); 23 | 24 | private static final Map, GBFSFeed.Name> classMap; 25 | 26 | static { 27 | feedNameMap.put(GBFSFeed.Name.GBFS, GBFSGbfs.class); 28 | feedNameMap.put(GBFSFeed.Name.GBFS_VERSIONS, GBFSGbfsVersions.class); 29 | feedNameMap.put(GBFSFeed.Name.GEOFENCING_ZONES, GBFSGeofencingZones.class); 30 | feedNameMap.put(GBFSFeed.Name.STATION_INFORMATION, GBFSStationInformation.class); 31 | feedNameMap.put(GBFSFeed.Name.STATION_STATUS, GBFSStationStatus.class); 32 | feedNameMap.put(GBFSFeed.Name.SYSTEM_ALERTS, GBFSSystemAlerts.class); 33 | feedNameMap.put(GBFSFeed.Name.SYSTEM_INFORMATION, GBFSSystemInformation.class); 34 | feedNameMap.put(GBFSFeed.Name.SYSTEM_PRICING_PLANS, GBFSSystemPricingPlans.class); 35 | feedNameMap.put(GBFSFeed.Name.SYSTEM_REGIONS, GBFSSystemRegions.class); 36 | feedNameMap.put(GBFSFeed.Name.VEHICLE_STATUS, GBFSVehicleStatus.class); 37 | feedNameMap.put(GBFSFeed.Name.VEHICLE_TYPES, GBFSVehicleTypes.class); 38 | classMap = feedNameMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 39 | } 40 | 41 | public static Class implementingClass(GBFSFeed.Name feedName) { 42 | return feedNameMap.get(feedName); 43 | } 44 | 45 | public static GBFSFeed.Name fromClass(Class clazz) { 46 | return classMap.get(clazz); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/TestBase.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import java.net.URL; 6 | import java.util.concurrent.atomic.AtomicReference; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 9 | 10 | public abstract class TestBase { 11 | private static final ObjectMapper objectMapper = new ObjectMapper(); 12 | 13 | public T assertUnmarshalDoesNotThrow(String path, Class clazz) { 14 | URL resource = getClass().getClassLoader().getResource(path); 15 | AtomicReference returnValue = new AtomicReference<>(); 16 | assertDoesNotThrow(() -> returnValue.set(objectMapper.readValue(resource, clazz))); 17 | return returnValue.get(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/free_bike_status/FreeBikeStatusTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.free_bike_status; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class FreeBikeStatusTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/free_bike_status.json", GBFSFreeBikeStatus.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/gbfs/GBFSFeedNameTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.gbfs; 2 | 3 | import org.mobilitydata.gbfs.v2_2.station_information.GBFSStationInformation; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | class GBFSFeedNameTest { 9 | 10 | @Test 11 | void value() { 12 | assertEquals("station_information", GBFSFeedName.StationInformation.value()); 13 | } 14 | 15 | @Test 16 | void implementingClass() { 17 | assertEquals(GBFSStationInformation.class, GBFSFeedName.StationInformation.implementingClass()); 18 | } 19 | 20 | @Test 21 | void fromValue() { 22 | assertEquals(GBFSFeedName.StationInformation, GBFSFeedName.fromValue("station_information")); 23 | } 24 | 25 | @Test 26 | void fromClass() { 27 | assertEquals(GBFSFeedName.StationInformation, GBFSFeedName.fromClass(GBFSStationInformation.class)); 28 | } 29 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/gbfs/GBFSTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.gbfs; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class GBFSTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/gbfs.json", GBFS.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/gbfs_versions/GBFSVersionsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.gbfs_versions; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class GBFSVersionsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/gbfs_versions.json", GBFSGbfsVersions.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/geofencing_zones/GeofencingZonesTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.geofencing_zones; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.geojson.LngLatAlt; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class GeofencingZonesTest extends TestBase { 10 | @Test 11 | void testUnmarshal() { 12 | GBFSGeofencingZones zones = assertUnmarshalDoesNotThrow("v2_X/geofencing_zones.json", GBFSGeofencingZones.class); 13 | GBFSFeature feature = zones.getData().getGeofencingZones().getFeatures().get(0); 14 | 15 | LngLatAlt coord = feature.getGeometry().getCoordinates().get(0).get(0).get(0); 16 | 17 | assertEquals(60.137400634341, coord.getLatitude(), 0.01); 18 | assertEquals(11.53037789067, coord.getLongitude()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/station_information/StationInformationTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.station_information; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class StationInformationTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/station_information.json", GBFSStationInformation.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/station_status/StationStatusTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.station_status; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class StationStatusTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/station_status.json", GBFSStationStatus.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/system_alerts/SystemAlertsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.system_alerts; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemAlertsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_alerts.json", GBFSSystemAlerts.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/system_calendar/SystemCalendarTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.system_calendar; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemCalendarTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_calendar.json", GBFSSystemCalendar.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/system_hours/SystemHoursTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.system_hours; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemHoursTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_hours.json", GBFSSystemHours.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/system_information/SystemInformationTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.system_information; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.mobilitydata.gbfs.v2_2.system_pricing_plans.GBFSSystemPricingPlans; 5 | import org.junit.jupiter.api.Test; 6 | 7 | class SystemInformationTest extends TestBase { 8 | @Test 9 | void testUnmarshal() { 10 | assertUnmarshalDoesNotThrow("v2_X/system_information.json", GBFSSystemPricingPlans.class); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/system_pricing_plans/SystemPricingPlansTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.system_pricing_plans; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemPricingPlansTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_pricing_plans.json", GBFSSystemPricingPlans.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/system_regions/SystemRegionsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.system_regions; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemRegionsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_regions.json", GBFSSystemRegions.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_2/vehicle_types/VehicleTypesTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_2.vehicle_types; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class VehicleTypesTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/vehicle_types.json", GBFSVehicleTypes.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/free_bike_status/FreeBikeStatusTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.free_bike_status; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class FreeBikeStatusTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/free_bike_status.json", GBFSFreeBikeStatus.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/gbfs/GBFSFeedNameTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.gbfs; 2 | 3 | import org.mobilitydata.gbfs.v2_3.station_information.GBFSStationInformation; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class GBFSFeedNameTest { 10 | 11 | @Test 12 | void value() { 13 | Assertions.assertEquals("station_information", GBFSFeedName.StationInformation.value()); 14 | } 15 | 16 | @Test 17 | void implementingClass() { 18 | assertEquals(GBFSStationInformation.class, GBFSFeedName.StationInformation.implementingClass()); 19 | } 20 | 21 | @Test 22 | void fromValue() { 23 | assertEquals(GBFSFeedName.StationInformation, GBFSFeedName.fromValue("station_information")); 24 | } 25 | 26 | @Test 27 | void fromClass() { 28 | assertEquals(GBFSFeedName.StationInformation, GBFSFeedName.fromClass(GBFSStationInformation.class)); 29 | } 30 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/gbfs/GBFSTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.gbfs; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class GBFSTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/gbfs.json", GBFS.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/gbfs_versions/GBFSVersionsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.gbfs_versions; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class GBFSVersionsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/gbfs_versions.json", GBFSGbfsVersions.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/geofencing_zones/GeofencingZonesTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.geofencing_zones; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class GeofencingZonesTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/geofencing_zones.json", GBFSGeofencingZones.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/station_information/StationInformationTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.station_information; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class StationInformationTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/station_information.json", GBFSStationInformation.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/station_status/StationStatusTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.station_status; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class StationStatusTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/station_status.json", GBFSStationStatus.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/system_alerts/SystemAlertsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.system_alerts; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemAlertsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_alerts.json", GBFSSystemAlerts.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/system_calendar/SystemCalendarTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.system_calendar; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemCalendarTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_calendar.json", GBFSSystemCalendar.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/system_hours/SystemHoursTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.system_hours; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemHoursTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_hours.json", GBFSSystemHours.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/system_information/SystemInformationTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.system_information; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemInformationTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_information.json", GBFSSystemInformation.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/system_pricing_plans/SystemPricingPlansTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.system_pricing_plans; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemPricingPlansTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_pricing_plans.json", GBFSSystemPricingPlans.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/system_regions/SystemRegionsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.system_regions; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemRegionsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/system_regions.json", GBFSSystemRegions.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v2_3/vehicle_types/VehicleTypesTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v2_3.vehicle_types; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class VehicleTypesTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v2_X/vehicle_types.json", GBFSVehicleTypes.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/gbfs/GBFSFeedNameTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.gbfs; 2 | 3 | import org.mobilitydata.gbfs.v3_0.station_information.GBFSStationInformation; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class GBFSFeedNameTest { 10 | 11 | @Test 12 | void value() { 13 | Assertions.assertEquals("station_information", org.mobilitydata.gbfs.v3_0.gbfs.GBFSFeed.Name.STATION_INFORMATION.value()); 14 | } 15 | 16 | @Test 17 | void implementingClass() { 18 | assertEquals(GBFSStationInformation.class, org.mobilitydata.gbfs.v3_0.gbfs.GBFSFeedName.implementingClass(org.mobilitydata.gbfs.v3_0.gbfs.GBFSFeed.Name.STATION_INFORMATION)); 19 | } 20 | 21 | @Test 22 | void fromValue() { 23 | assertEquals(org.mobilitydata.gbfs.v3_0.gbfs.GBFSFeed.Name.STATION_INFORMATION, org.mobilitydata.gbfs.v3_0.gbfs.GBFSFeed.Name.fromValue("station_information")); 24 | } 25 | 26 | @Test 27 | void fromClass() { 28 | assertEquals(GBFSFeed.Name.STATION_INFORMATION, GBFSFeedName.fromClass(GBFSStationInformation.class)); 29 | } 30 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/gbfs/GBFSTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.gbfs; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class GBFSTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/gbfs.json", GBFSGbfs.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/gbfs_versions/GBFSVersionsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.gbfs_versions; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | class GBFSVersionsTest extends TestBase { 8 | @Test 9 | void testUnmarshal() { 10 | assertUnmarshalDoesNotThrow("v3_0/gbfs_versions.json", GBFSGbfsVersions.class); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/geofencing_zones/GeofencingZonesTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.geofencing_zones; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | 5 | import org.geojson.LngLatAlt; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | 10 | class GeofencingZonesTest extends TestBase { 11 | @Test 12 | void testUnmarshal() { 13 | GBFSGeofencingZones zones = assertUnmarshalDoesNotThrow("v3_0/geofencing_zones.json", GBFSGeofencingZones.class); 14 | GBFSFeature feature = zones.getData().getGeofencingZones().getFeatures().get(0); 15 | LngLatAlt coord = feature.getGeometry().getCoordinates().get(0).get(0).get(0); 16 | assertEquals(45.562982, coord.getLatitude(), 0.01); 17 | assertEquals(-122.578067, coord.getLongitude()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/manifest/ManifestTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.manifest; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | class ManifestTest extends TestBase { 8 | @Test 9 | void testUnmarshal() { 10 | assertUnmarshalDoesNotThrow("v3_0/manifest.json", GBFSManifest.class); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/station_information/StationInformationTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.station_information; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class StationInformationTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/station_information.json", GBFSStationInformation.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/station_status/StationStatusTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.station_status; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class StationStatusTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/station_status.json", GBFSStationStatus.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/system_alerts/SystemAlertsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.system_alerts; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemAlertsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/system_alerts.json", GBFSSystemAlerts.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/system_information/SystemInformationTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.system_information; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemInformationTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/system_information.json", GBFSSystemInformation.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/system_pricing_plans/SystemPricingPlansTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.system_pricing_plans; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemPricingPlansTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/system_pricing_plans.json", GBFSSystemPricingPlans.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/system_regions/SystemRegionsTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.system_regions; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class SystemRegionsTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/system_regions.json", GBFSSystemRegions.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/vehicle_status/VehicleStatusTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.vehicle_status; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class VehicleStatusTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/vehicle_status.json", GBFSVehicleStatus.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/java/org/mobilitydata/gbfs/v3_0/vehicle_types/VehicleTypesTest.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs.v3_0.vehicle_types; 2 | 3 | import org.mobilitydata.gbfs.TestBase; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class VehicleTypesTest extends TestBase { 7 | @Test 8 | void testUnmarshal() { 9 | assertUnmarshalDoesNotThrow("v3_0/vehicle_types.json", GBFSVehicleTypes.class); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/free_bike_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606857968, 3 | "ttl": 300, 4 | "version": "2.2", 5 | "data": { 6 | "bikes": [ 7 | { 8 | "bike_id": "TST:Scooter:1234", 9 | "lat": 59.91465759277344, 10 | "lon": 10.760470390319824, 11 | "is_reserved": false, 12 | "is_disabled": true, 13 | "vehicle_type_id": "TST:VehicleType:Scooter", 14 | "current_range_meters": 1431.2, 15 | "pricing_plan_id": "TST:PricingPlan:Basic", 16 | "rental_uris": { 17 | "android": "test://rentme/TST:Scooter:1234", 18 | "ios": "test://rentme/TST:Scooter:1234", 19 | "web": "https://test.com/rentme/TST:Scooter:1234" 20 | } 21 | } 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606727710, 3 | "ttl": 300, 4 | "version": "2.2", 5 | "data": { 6 | "en": { 7 | "feeds": [ 8 | { 9 | "name": "gbfs_versions", 10 | "url": "https://test.com/gbfs_versions" 11 | }, 12 | { 13 | "name": "system_information", 14 | "url": "https://test.com/system_information" 15 | }, 16 | { 17 | "name": "vehicle_types", 18 | "url": "https://test.com/vehicle_types" 19 | }, 20 | { 21 | "name": "station_information", 22 | "url": "https://test.com/station_information" 23 | }, 24 | { 25 | "name": "station_status", 26 | "url": "https://test.com/station_status" 27 | }, 28 | { 29 | "name": "free_bike_status", 30 | "url": "https://test.com/free_bike_status" 31 | }, 32 | { 33 | "name": "system_regions", 34 | "url": "https://test.com/system_regions" 35 | }, 36 | { 37 | "name": "system_pricing_plans", 38 | "url": "https://test.com/system_pricing_plans" 39 | }, 40 | { 41 | "name": "system_hours", 42 | "url": "https://test.com/system_hours" 43 | }, 44 | { 45 | "name": "system_calendar", 46 | "url": "https://test.com/system_calendar" 47 | }, 48 | { 49 | "name": "system_alerts", 50 | "url": "https://test.com/system_alerts" 51 | }, 52 | { 53 | "name": "geofencing_zones", 54 | "url": "https://test.com/geofencing_zones" 55 | } 56 | ] 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.2", 5 | "data": { 6 | "versions": [ 7 | { 8 | "version":"2.2", 9 | "url":"https://test.com/gbfs.json" 10 | } 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/station_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.2", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "TST:Station:1", 9 | "name": "Cool bikes", 10 | "lat": 12.34, 11 | "lon": 45.67, 12 | "vehicle_type_capacity": { 13 | "TST:VehicleType:CityBike": 7 14 | } 15 | }, 16 | { 17 | "station_id": "TST:Station:2", 18 | "name": "Cooler bikes", 19 | "lat": 11.34, 20 | "lon": 44.67, 21 | "vehicle_type_capacity": { 22 | "TST:VehicleType:CityBike": 12 23 | } 24 | } 25 | ] 26 | } 27 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/station_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.2", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "TST:Station:1", 9 | "is_installed": true, 10 | "is_renting": true, 11 | "is_returning": true, 12 | "last_reported": 1434054678, 13 | "num_docks_available": 3, 14 | "vehicle_docks_available": [{ 15 | "vehicle_type_ids": ["TST:VehicleType:Scooter"], 16 | "count": 2 17 | }, { 18 | "vehicle_type_ids": ["TST:VehicleType:CityBike"], 19 | "count": 1 20 | }], 21 | "num_bikes_available": 1, 22 | "vehicle_types_available": [{ 23 | "vehicle_type_id": "TST:VehicleType:Scooter", 24 | "count": 1 25 | }, { 26 | "vehicle_type_id": "TST:VehicleType:CityBike", 27 | "count": 0 28 | }] 29 | }, { 30 | "station_id": "TST:Station:2", 31 | "is_installed": true, 32 | "is_renting": true, 33 | "is_returning": true, 34 | "last_reported": 1434054678, 35 | "num_docks_available": 8, 36 | "vehicle_docks_available": [{ 37 | "vehicle_type_ids": ["TST:VehicleType:Scooter"], 38 | "count": 6 39 | }, { 40 | "vehicle_type_ids": ["TST:VehicleType:CityBike"], 41 | "count": 2 42 | }], 43 | "num_bikes_available": 6, 44 | "vehicle_types_available": [{ 45 | "vehicle_type_id": "TST:VehicleType:Scooter", 46 | "count": 2 47 | }, { 48 | "vehicle_type_id": "TST:VehicleType:CityBike", 49 | "count": 4 50 | }] 51 | } 52 | ] 53 | } 54 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/system_alerts.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.2", 5 | "data": { 6 | "alerts": [ 7 | { 8 | "alert_id": "TST:Alert:1", 9 | "type": "station_closure", 10 | "times": [ 11 | { 12 | "start": 1434054678, 13 | "end": 1434054987 14 | } 15 | ], 16 | "station_ids": ["TST:Station:1"], 17 | "summary": "Closed for maintenance", 18 | "description": "Station is closed to install more docks.", 19 | "last_updated": 1434054678 20 | } 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/system_calendar.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.2", 5 | "data": { 6 | "calendars": [ 7 | { 8 | "start_month": 1, 9 | "start_day": 1, 10 | "start_year": 2020, 11 | "end_month": 12, 12 | "end_day": 30, 13 | "end_year": 2021 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/system_hours.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.2", 5 | "data": { 6 | "rental_hours": [ 7 | { 8 | "user_types": [ "member" ], 9 | "days": ["sat", "sun"], 10 | "start_time": "00:00:00", 11 | "end_time": "23:59:59" 12 | }, 13 | { 14 | "user_types": [ "nonmember" ], 15 | "days": ["sat", "sun"], 16 | "start_time": "05:00:00", 17 | "end_time": "23:59:59" 18 | }, 19 | { 20 | "user_types": [ "member", "nonmember" ], 21 | "days": ["mon", "tue", "wed", "thu", "fri"], 22 | "start_time": "00:00:00", 23 | "end_time": "23:59:59" 24 | } 25 | ] 26 | } 27 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/system_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606830357, 3 | "ttl": 300, 4 | "version": "2.2", 5 | "data": { 6 | "system_id": "TST:System:Test", 7 | "language": "en", 8 | "name": "Test", 9 | "url": "https://www.test.com/", 10 | "timezone": "Europe/Oslo", 11 | "rental_apps": { 12 | "android": { 13 | "store_uri": "https://play.google.com/store/apps/details?id=com.testrental.android", 14 | "discovery_uri": "com.testrental.android://" 15 | }, 16 | "ios": { 17 | "store_uri": "https://apps.apple.com/app/apple-store/id123456789", 18 | "discovery_uri": "com.testrental.ios://" 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/system_pricing_plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606858558, 3 | "ttl": 300, 4 | "version": "2.2", 5 | "data": { 6 | "plans": [ 7 | { 8 | "plan_id": "TST:PricingPlan:Basic", 9 | "name": "Basic", 10 | "currency": "NOK", 11 | "price": 0.0, 12 | "is_taxable": false, 13 | "description": "Start NOK 0, Per minute 3,50 NOK", 14 | "per_min_pricing": [ 15 | { 16 | "start": 0, 17 | "rate": 3.5, 18 | "interval": 1 19 | } 20 | ] 21 | } 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606858379, 3 | "ttl": 300, 4 | "version": "2.2", 5 | "data": { 6 | "regions": [ 7 | { 8 | "region_id": "TST:Region:Sahara", 9 | "name": "Sahara" 10 | } 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v2_X/vehicle_types.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606830898, 3 | "ttl": 300, 4 | "version": "2.2", 5 | "data": { 6 | "vehicle_types": [ 7 | { 8 | "vehicle_type_id": "TST:VehicleType:Scooter", 9 | "form_factor": "scooter", 10 | "propulsion_type": "electric", 11 | "max_range_meters": 0.0 12 | }, 13 | { 14 | "vehicle_type_id": "TST:VehicleType:CityBike", 15 | "form_factor": "bicycle", 16 | "propulsion_type": "human" 17 | } 18 | ] 19 | } 20 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "feeds": [ 7 | { 8 | "name": "system_information", 9 | "url": "https://www.example.com/gbfs/1/system_information" 10 | }, 11 | { 12 | "name": "station_information", 13 | "url": "https://www.example.com/gbfs/1/station_information" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "versions": [ 7 | { 8 | "version": "2.0", 9 | "url": "https://www.example.com/gbfs/2/gbfs" 10 | }, 11 | { 12 | "version": "3.0", 13 | "url": "https://www.example.com/gbfs/3/gbfs" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/geofencing_zones.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "geofencing_zones": { 7 | "type": "FeatureCollection", 8 | "features": [ 9 | { 10 | "type": "Feature", 11 | "geometry": { 12 | "type": "MultiPolygon", 13 | "coordinates": [ 14 | [ 15 | [ 16 | [ 17 | -122.578067, 18 | 45.562982 19 | ], 20 | [ 21 | -122.661838, 22 | 45.562741 23 | ], 24 | [ 25 | -122.661151, 26 | 45.504542 27 | ], 28 | [ 29 | -122.578926, 30 | 45.5046625 31 | ], 32 | [ 33 | -122.578067, 34 | 45.562982 35 | ] 36 | ] 37 | ], 38 | [ 39 | [ 40 | [ 41 | -122.650680, 42 | 45.548197 43 | ], 44 | [ 45 | -122.650852, 46 | 45.534731 47 | ], 48 | [ 49 | -122.630939, 50 | 45.535212 51 | ], 52 | [ 53 | -122.630424, 54 | 45.548197 55 | ], 56 | [ 57 | -122.650680, 58 | 45.548197 59 | ] 60 | ] 61 | ] 62 | ] 63 | }, 64 | "properties": { 65 | "name": [ 66 | { 67 | "text": "NE 24th/NE Knott", 68 | "language": "en" 69 | } 70 | ], 71 | "start": 1593878400, 72 | "end": 1593907260, 73 | "rules": [ 74 | { 75 | "vehicle_type_id": [ 76 | "moped1", 77 | "car1" 78 | ], 79 | "ride_start_allowed": false, 80 | "ride_end_allowed": false, 81 | "ride_through_allowed": true, 82 | "maximum_speed_kph": 10, 83 | "station_parking": true 84 | } 85 | ] 86 | } 87 | } 88 | ] 89 | }, 90 | "global_rules": [ 91 | { 92 | "ride_start_allowed": false, 93 | "ride_end_allowed": false, 94 | "ride_through_allowed": true 95 | } 96 | ] 97 | } 98 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated":1667004473, 3 | "ttl":0, 4 | "version":"3.0", 5 | "data":{ 6 | "datasets":[ 7 | { 8 | "system_id":"example_berlin", 9 | "versions":[ 10 | { 11 | "version":"2.0", 12 | "url":"https://berlin.example.com/gbfs/2/gbfs" 13 | }, 14 | { 15 | "version":"3.0", 16 | "url":"https://berlin.example.com/gbfs/3/gbfs" 17 | } 18 | ] 19 | }, 20 | { 21 | "system_id":"example_paris", 22 | "versions":[ 23 | { 24 | "version":"2.0", 25 | "url":"https://paris.example.com/gbfs/2/gbfs" 26 | }, 27 | { 28 | "version":"3.0", 29 | "url":"https://paris.example.com/gbfs/3/gbfs" 30 | } 31 | ] 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/station_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "pga", 9 | "name": [ 10 | { 11 | "text": "Parking garage A", 12 | "language": "en" 13 | } 14 | ], 15 | "lat": 12.345678, 16 | "lon": 45.678901, 17 | "station_opening_hours": "Su-Th 05:00-22:00; Fr-Sa 05:00-01:00", 18 | "parking_type": "underground_parking", 19 | "parking_hoop": false, 20 | "contact_phone": "+33109874321", 21 | "is_charging_station": true, 22 | "vehicle_type_dock_capacity": [ 23 | { 24 | "vehicle_type_id": "abc123", 25 | "count": 7 26 | }, 27 | { 28 | "vehicle_type_id": "def456", 29 | "count": 0 30 | } 31 | ] 32 | }, 33 | { 34 | "station_id": "station12", 35 | "name": [ 36 | { 37 | "text": "SE Belmont & SE 10th", 38 | "language": "en" 39 | } 40 | ], 41 | "lat": 45.516445, 42 | "lon": -122.655775, 43 | "is_valet_station": false, 44 | "is_virtual_station": true, 45 | "is_charging_station": false, 46 | "station_area": { 47 | "type": "MultiPolygon", 48 | "coordinates": [ 49 | [ 50 | [ 51 | [ 52 | -122.655775, 53 | 45.516445 54 | ], 55 | [ 56 | -122.655705, 57 | 45.516445 58 | ], 59 | [ 60 | -122.655705, 61 | 45.516495 62 | ], 63 | [ 64 | -122.655775, 65 | 45.516495 66 | ], 67 | [ 68 | -122.655775, 69 | 45.516445 70 | ] 71 | ] 72 | ] 73 | ] 74 | }, 75 | "capacity": 16, 76 | "vehicle_type_area_capacity": [ 77 | { 78 | "vehicle_type_id": "abc123", 79 | "count": 7 80 | }, 81 | { 82 | "vehicle_type_id": "def456", 83 | "count": 8 84 | } 85 | ] 86 | } 87 | ] 88 | } 89 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/station_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "station1", 9 | "is_installed": true, 10 | "is_renting": true, 11 | "is_returning": true, 12 | "last_reported": 1609866125, 13 | "num_docks_available": 3, 14 | "num_docks_disabled" : 1, 15 | "vehicle_docks_available": [ 16 | { 17 | "vehicle_type_ids": [ "abc123", "def456" ], 18 | "count": 2 19 | }, 20 | { 21 | "vehicle_type_ids": [ "def456" ], 22 | "count": 1 23 | } 24 | ], 25 | "num_vehicles_available": 1, 26 | "num_vehicles_disabled": 2, 27 | "vehicle_types_available": [ 28 | { 29 | "vehicle_type_id": "abc123", 30 | "count": 1 31 | }, 32 | { 33 | "vehicle_type_id": "def456", 34 | "count": 0 35 | } 36 | ] 37 | }, 38 | { 39 | "station_id": "station2", 40 | "is_installed": true, 41 | "is_renting": true, 42 | "is_returning": true, 43 | "last_reported": 1609866106, 44 | "num_docks_available": 8, 45 | "num_docks_disabled" : 1, 46 | "vehicle_docks_available": [ 47 | { 48 | "vehicle_type_ids": [ "abc123" ], 49 | "count": 6 50 | }, 51 | { 52 | "vehicle_type_ids": [ "def456" ], 53 | "count": 2 54 | } 55 | ], 56 | "num_vehicles_available": 6, 57 | "num_vehicles_disabled": 1, 58 | "vehicle_types_available": [ 59 | { 60 | "vehicle_type_id": "abc123", 61 | "count": 2 62 | }, 63 | { 64 | "vehicle_type_id": "def456", 65 | "count": 4 66 | } 67 | ] 68 | } 69 | ] 70 | } 71 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/system_alerts.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1604519393, 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "alerts": [ 7 | { 8 | "alert_id": "21", 9 | "type": "station_closure", 10 | "station_ids": [ 11 | "123", 12 | "456", 13 | "789" 14 | ], 15 | "times": [ 16 | { 17 | "start": 1604448000, 18 | "end": 1604674800 19 | } 20 | ], 21 | "url": [ 22 | { 23 | "text": "https://example.com/more-info", 24 | "language": "en" 25 | } 26 | ], 27 | "summary": [ 28 | { 29 | "text": "Disruption of Service", 30 | "language": "en" 31 | } 32 | ], 33 | "description": [ 34 | { 35 | "text": "The three stations on Broadway will be out of service from 12:00am Nov 3 to 3:00pm Nov 6th to accommodate road work", 36 | "language": "en" 37 | } 38 | ], 39 | "last_updated": 1604198100 40 | } 41 | ] 42 | } 43 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/system_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 1800, 4 | "version": "3.0", 5 | "data": { 6 | "system_id": "example_cityname", 7 | "languages": ["en"], 8 | "name": [ 9 | { 10 | "text": "Example Bike Rental", 11 | "language": "en" 12 | } 13 | ], 14 | "short_name": [ 15 | { 16 | "text": "Example Bike", 17 | "language": "en" 18 | } 19 | ], 20 | "operator": [ 21 | { 22 | "text": "Example Sharing, Inc", 23 | "language": "en" 24 | } 25 | ], 26 | "opening_hours": "Apr 1-Nov 3 00:00-24:00", 27 | "start_date": "2010-06-10", 28 | "url": "https://www.example.com", 29 | "purchase_url": "https://www.example.com", 30 | "phone_number": "+18005551234", 31 | "email": "customerservice@example.com", 32 | "feed_contact_email": "datafeed@example.com", 33 | "timezone": "America/Chicago", 34 | "license_url": "https://www.example.com/data-license.html", 35 | "terms_url": [ 36 | { 37 | "text": "https://www.example.com/en/terms", 38 | "language": "en" 39 | } 40 | ], 41 | "terms_last_updated": "2021-06-21", 42 | "privacy_url": [ 43 | { 44 | "text": "https://www.example.com/en/privacy-policy", 45 | "language": "en" 46 | } 47 | ], 48 | "privacy_last_updated": "2019-01-13", 49 | "rental_apps": { 50 | "android": { 51 | "discovery_uri": "com.example.android://", 52 | "store_uri": "https://play.google.com/store/apps/details?id=com.example.android" 53 | }, 54 | "ios": { 55 | "store_uri": "https://apps.apple.com/app/apple-store/id123456789", 56 | "discovery_uri": "com.example.ios://" 57 | } 58 | }, 59 | "brand_assets": { 60 | "brand_last_modified": "2021-06-15", 61 | "brand_image_url": "https://www.example.com/assets/brand_image.svg", 62 | "brand_image_url_dark": "https://www.example.com/assets/brand_image_dark.svg", 63 | "color": "#C2D32C", 64 | "brand_terms_url": "https://www.example.com/assets/brand.pdf" 65 | } 66 | 67 | } 68 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/system_pricing_plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "plans": [ 7 | { 8 | "plan_id": "plan2", 9 | "name": [ 10 | { 11 | "text": "One-Way", 12 | "language": "en" 13 | } 14 | ], 15 | "currency": "USD", 16 | "price": 2.00, 17 | "reservation_price_per_min": 0.15, 18 | "is_taxable": false, 19 | "description": [ 20 | { 21 | "text": "Includes 10km, overage fees apply after 10km.", 22 | "language": "en" 23 | } 24 | ], 25 | "per_km_pricing": [ 26 | { 27 | "start": 10, 28 | "rate": 1.00, 29 | "interval": 1, 30 | "end": 25 31 | }, 32 | { 33 | "start": 25, 34 | "rate": 0.50, 35 | "interval": 1 36 | }, 37 | { 38 | "start": 25, 39 | "rate": 3.00, 40 | "interval": 5 41 | } 42 | ] 43 | }, 44 | { 45 | "plan_id": "plan3", 46 | "name": [ 47 | { 48 | "text": "Simple Rate", 49 | "language": "en" 50 | } 51 | ], 52 | "currency": "CAD", 53 | "price": 3.00, 54 | "is_taxable": true, 55 | "description": [ 56 | { 57 | "text": "$3 unlock fee, $0.25 per kilometer and 0.50 per minute.", 58 | "language": "en" 59 | } 60 | ], 61 | "per_km_pricing": [ 62 | { 63 | "start": 0, 64 | "rate": 0.25, 65 | "interval": 1 66 | } 67 | ], 68 | "per_min_pricing": [ 69 | { 70 | "start": 0, 71 | "rate": 0.50, 72 | "interval": 1 73 | } 74 | ] 75 | } 76 | ] 77 | } 78 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1640887163, 3 | "ttl": 86400, 4 | "version": "3.0", 5 | "data": { 6 | "regions": [ 7 | { 8 | "name": [ 9 | { 10 | "text": "North", 11 | "language": "en" 12 | } 13 | ], 14 | "region_id": "3" 15 | }, 16 | { 17 | "name": [ 18 | { 19 | "text": "East", 20 | "language": "en" 21 | } 22 | ], 23 | "region_id": "4" 24 | }, 25 | { 26 | "name": [ 27 | { 28 | "text": "South", 29 | "language": "en" 30 | } 31 | ], 32 | "region_id": "5" 33 | }, 34 | { 35 | "name": [ 36 | { 37 | "text": "West", 38 | "language": "en" 39 | } 40 | ], 41 | "region_id": "6" 42 | } 43 | ] 44 | } 45 | } -------------------------------------------------------------------------------- /models/java/gbfs-java-model/src/test/resources/v3_0/vehicle_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated":1640887163, 3 | "ttl":0, 4 | "version":"3.0", 5 | "data":{ 6 | "vehicles":[ 7 | { 8 | "vehicle_id":"973a5c94-c288-4a2b-afa6-de8aeb6ae2e5", 9 | "last_reported":1609866109, 10 | "lat":12.345678, 11 | "lon":56.789012, 12 | "is_reserved":false, 13 | "is_disabled":false, 14 | "vehicle_type_id":"abc123", 15 | "rental_uris": { 16 | "android": "https://www.example.com/app?vehicle_id=973a5c94-c288-4a2b-afa6-de8aeb6ae2e5&platform=android&", 17 | "ios": "https://www.example.com/app?vehicle_id=973a5c94-c288-4a2b-afa6-de8aeb6ae2e5&platform=ios" 18 | } 19 | }, 20 | { 21 | "vehicle_id":"987fd100-b822-4347-86a4-b3eef8ca8b53", 22 | "last_reported":1609866204, 23 | "is_reserved":false, 24 | "is_disabled":false, 25 | "vehicle_type_id":"def456", 26 | "current_range_meters":6543.0, 27 | "station_id":"86", 28 | "pricing_plan_id":"plan3" 29 | }, 30 | { 31 | "vehicle_id":"45bd3fb7-a2d5-4def-9de1-c645844ba962", 32 | "last_reported":1609866109, 33 | "lat":12.345678, 34 | "lon":56.789012, 35 | "is_reserved":false, 36 | "is_disabled":false, 37 | "vehicle_type_id":"abc123", 38 | "current_range_meters":400000.0, 39 | "available_until":"2021-05-17T15:00:00Z", 40 | "home_station_id":"station1", 41 | "vehicle_equipment":[ 42 | "child_seat_a", 43 | "winter_tires" 44 | ] 45 | }, 46 | { 47 | "vehicle_id":"d4521def-7922-4e46-8e1d-8ac397239bd0", 48 | "last_reported":1609866204, 49 | "is_reserved":false, 50 | "is_disabled":false, 51 | "vehicle_type_id":"def456", 52 | "current_fuel_percent":0.7, 53 | "current_range_meters":6543.0, 54 | "station_id":"86", 55 | "pricing_plan_id":"plan3", 56 | "home_station_id":"146", 57 | "vehicle_equipment":[ 58 | "child_seat_a" 59 | ] 60 | } 61 | ] 62 | } 63 | } -------------------------------------------------------------------------------- /models/java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.mobilitydata.gbfs 8 | gbfs-java-model-parent 9 | 1.0.0 10 | 11 | gbfs-java-model-parent 12 | pom 13 | 14 | 15 | rule-factory 16 | gbfs-java-model 17 | 18 | 19 | 20 | 21 | sonar 22 | 23 | false 24 | 25 | 26 | 27 | 3.7.0.1746 28 | 29 | 30 | 31 | 32 | 33 | org.sonarsource.scanner.maven 34 | sonar-maven-plugin 35 | ${sonar-maven-plugin.version} 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /models/java/rule-factory/src/main/java/org/mobilitydata/gbfs/GeofencingRuleFactory.java: -------------------------------------------------------------------------------- 1 | package org.mobilitydata.gbfs; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.node.ObjectNode; 5 | import com.fasterxml.jackson.databind.node.TextNode; 6 | import com.sun.codemodel.JPackage; 7 | import com.sun.codemodel.JType; 8 | import org.jsonschema2pojo.Schema; 9 | import org.jsonschema2pojo.rules.ObjectRule; 10 | import org.jsonschema2pojo.rules.Rule; 11 | import org.jsonschema2pojo.rules.RuleFactory; 12 | import org.jsonschema2pojo.util.ParcelableHelper; 13 | import org.jsonschema2pojo.util.ReflectionHelper; 14 | 15 | public class GeofencingRuleFactory extends RuleFactory { 16 | 17 | @Override 18 | public Rule getObjectRule() { 19 | return new GeofencingObjectRule(this, new ParcelableHelper(), new ReflectionHelper(this)); 20 | } 21 | 22 | static class GeofencingObjectRule extends ObjectRule { 23 | 24 | protected GeofencingObjectRule( 25 | RuleFactory ruleFactory, 26 | ParcelableHelper parcelableHelper, 27 | ReflectionHelper reflectionHelper 28 | ) { 29 | super(ruleFactory, parcelableHelper, reflectionHelper); 30 | } 31 | 32 | @Override 33 | public JType apply( 34 | String nodeName, 35 | JsonNode node, 36 | JsonNode parent, 37 | JPackage _package, 38 | Schema schema 39 | ) { 40 | if ((nodeName.equals("geometry") || nodeName.equals("station_area")) && node instanceof ObjectNode) { 41 | ObjectNode on = (ObjectNode) node; 42 | on.set("existingJavaType", new TextNode("org.geojson.MultiPolygon")); 43 | } 44 | return super.apply(nodeName, node, parent, _package, schema); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /models/openapi/README.md: -------------------------------------------------------------------------------- 1 | # GBFS OpenAPI Specification 2 | 3 | OpenAPI specifications for the General Bikeshare Feed Specification (GBFS) to easily create models and client code for existing GBFS systems or server code for your own implementation. 4 | 5 | ## Usage 6 | 7 | ### Code generation 8 | 9 | Many tools will let you generate models or client and server code direcly from the openapi file, e.g. 10 | 11 | * [OpenAPI Generator](https://openapi-generator.tech) 12 | * [Swagger Codegen](https://swagger.io/tools/swagger-codegen/) 13 | 14 | or one of [https://tools.openapis.org/categories/code-generators.html](these generators). 15 | 16 | ### Customization 17 | 18 | The `openapi.yaml` can be extended with individual details within the `ìnfo` block. It's also recommended to add a `servers` block with your base root url, e.g. 19 | 20 | ``` 21 | servers: 22 | - url: https://my.gbfs.org/v1 23 | ``` 24 | If needed, this can be overriden for a specific path. 25 | 26 | ## Versions 27 | - v2.3 28 | - v3.0 29 | -------------------------------------------------------------------------------- /models/rust/.gitignore: -------------------------------------------------------------------------------- 1 | /target -------------------------------------------------------------------------------- /models/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gbfs_types" 3 | version = "0.1.2" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "Types for GBFS" 7 | authors = ["MobilityData ", "Tom Delmas "] 8 | repository = "https://github.com/MobilityData/gbfs-json-schema" 9 | homepage = "https://github.com/MobilityData/gbfs-json-schema/tree/master/models/rust" 10 | keywords = ["gbfs", "types"] 11 | categories = ["transit", "mobility"] 12 | readme = "README.md" 13 | 14 | [features] 15 | default = ["reqwest_blocking", "pyo3", "napi"] 16 | reqwest_blocking = ["reqwest/blocking"] 17 | pyo3 = ["dep:pyo3"] 18 | napi = ["dep:napi", "dep:napi-derive"] 19 | 20 | [dev-dependencies] 21 | pretty_assertions = "1.4" 22 | 23 | [dependencies] 24 | futures = "0.3" 25 | http = "1.0" 26 | serde_json = "1.0" 27 | serde_with = "3.6" 28 | url = "2.5" 29 | url_serde = "0.2" 30 | 31 | [dependencies.geo-types] 32 | version = "0.7" 33 | features = ["serde"] 34 | 35 | [dependencies.serde] 36 | version = "1.0" 37 | features = ["derive"] 38 | 39 | [dependencies.reqwest] 40 | version = "0.11" 41 | features = ["json"] 42 | 43 | [dependencies.napi] 44 | version = "2.15" 45 | default-features = false 46 | features = ["napi6"] 47 | optional = true 48 | 49 | [dependencies.napi-derive] 50 | version = "2.15" 51 | optional = true 52 | 53 | [dependencies.pyo3] 54 | version = "0.20" 55 | features = ["serde"] 56 | optional = true -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "feeds": [ 7 | { 8 | "name": "system_information", 9 | "url": "https://www.example.com/gbfs/1/system_information" 10 | }, 11 | { 12 | "name": "station_information", 13 | "url": "https://www.example.com/gbfs/1/station_information" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "versions": [ 7 | { 8 | "version": "2.0", 9 | "url": "https://www.example.com/gbfs/2/gbfs" 10 | }, 11 | { 12 | "version": "3.0", 13 | "url": "https://www.example.com/gbfs/3/gbfs" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "datasets": [ 7 | { 8 | "system_id": "example_berlin", 9 | "versions": [ 10 | { 11 | "version": "2.0", 12 | "url": "https://berlin.example.com/gbfs/2/gbfs" 13 | }, 14 | { 15 | "version": "3.0", 16 | "url": "https://berlin.example.com/gbfs/3/gbfs" 17 | } 18 | ] 19 | }, 20 | { 21 | "system_id": "example_paris", 22 | "versions": [ 23 | { 24 | "version": "2.0", 25 | "url": "https://paris.example.com/gbfs/2/gbfs" 26 | }, 27 | { 28 | "version": "3.0", 29 | "url": "https://paris.example.com/gbfs/3/gbfs" 30 | } 31 | ] 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/station_information-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "pga", 9 | "name": [ 10 | { 11 | "text": "Parking garage A", 12 | "language": "en" 13 | } 14 | ], 15 | "lat": 12.345678, 16 | "lon": 45.678901, 17 | "station_opening_hours": "Su-Th 05:00-22:00; Fr-Sa 05:00-01:00", 18 | "parking_type": "underground_parking", 19 | "parking_hoop": false, 20 | "contact_phone": "+33109874321", 21 | "is_charging_station": true, 22 | "vehicle_docks_capacity": [ 23 | { 24 | "vehicle_type_ids": [ 25 | "abc123" 26 | ], 27 | "count": 7 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/station_information-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "station12", 9 | "name": [ 10 | { 11 | "text": "SE Belmont & SE 10th", 12 | "language": "en" 13 | } 14 | ], 15 | "lat": 45.516445, 16 | "lon": -122.655775, 17 | "is_valet_station": false, 18 | "is_virtual_station": true, 19 | "is_charging_station": false, 20 | "station_area": { 21 | "type": "MultiPolygon", 22 | "coordinates": [ 23 | [ 24 | [ 25 | [ 26 | -122.655775, 27 | 45.516445 28 | ], 29 | [ 30 | -122.655705, 31 | 45.516445 32 | ], 33 | [ 34 | -122.655705, 35 | 45.516495 36 | ], 37 | [ 38 | -122.655775, 39 | 45.516495 40 | ], 41 | [ 42 | -122.655775, 43 | 45.516445 44 | ] 45 | ] 46 | ] 47 | ] 48 | }, 49 | "capacity": 16, 50 | "vehicle_types_capacity": [ 51 | { 52 | "vehicle_type_ids": [ 53 | "abc123", 54 | "def456" 55 | ], 56 | "count": 15 57 | }, 58 | { 59 | "vehicle_type_ids": [ 60 | "def456" 61 | ], 62 | "count": 1 63 | } 64 | ] 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/station_information-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "425", 9 | "name": [ 10 | { 11 | "text": "Coppertail", 12 | "language": "en" 13 | } 14 | ], 15 | "lat": 27.956333, 16 | "lon": -82.430436, 17 | "rental_uris": { 18 | "android": "https://www.example.com/app?sid=1234567890&platform=android", 19 | "ios": "https://www.example.com/app?sid=1234567890&platform=ios" 20 | } 21 | } 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/system_alerts.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "alerts": [ 7 | { 8 | "alert_id": "21", 9 | "type": "station_closure", 10 | "station_ids": [ 11 | "123", 12 | "456", 13 | "789" 14 | ], 15 | "times": [ 16 | { 17 | "start": "2023-07-17T13:34:13+02:00", 18 | "end": "2023-07-18T13:34:13+02:00" 19 | } 20 | ], 21 | "url": [ 22 | { 23 | "text": "https://example.com/more-info", 24 | "language": "en" 25 | } 26 | ], 27 | "summary": [ 28 | { 29 | "text": "Disruption of Service", 30 | "language": "en" 31 | } 32 | ], 33 | "description": [ 34 | { 35 | "text": "The three stations on Broadway will be out of service from 12:00am Nov 3 to 3:00pm Nov 6th to accommodate road work", 36 | "language": "en" 37 | } 38 | ], 39 | "last_updated": "2023-07-17T13:34:13+02:00" 40 | } 41 | ] 42 | } 43 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/system_information-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 1800, 4 | "version": "3.0", 5 | "data": { 6 | "system_id": "example_cityname", 7 | "languages": [ 8 | "en" 9 | ], 10 | "name": [ 11 | { 12 | "text": "Example Bike Rental", 13 | "language": "en" 14 | } 15 | ], 16 | "short_name": [ 17 | { 18 | "text": "Example Bike", 19 | "language": "en" 20 | } 21 | ], 22 | "operator": [ 23 | { 24 | "text": "Example Sharing, Inc", 25 | "language": "en" 26 | } 27 | ], 28 | "opening_hours": "Apr 1-Nov 3 00:00-24:00", 29 | "start_date": "2010-06-10", 30 | "url": "https://www.example.com", 31 | "purchase_url": "https://www.example.com", 32 | "phone_number": "+18005551234", 33 | "email": "customerservice@example.com", 34 | "feed_contact_email": "datafeed@example.com", 35 | "timezone": "America/Chicago", 36 | "license_url": "https://www.example.com/data-license.html", 37 | "terms_url": [ 38 | { 39 | "text": "https://www.example.com/en/terms", 40 | "language": "en" 41 | } 42 | ], 43 | "terms_last_updated": "2021-06-21", 44 | "privacy_url": [ 45 | { 46 | "text": "https://www.example.com/en/privacy-policy", 47 | "language": "en" 48 | } 49 | ], 50 | "privacy_last_updated": "2019-01-13", 51 | "rental_apps": { 52 | "android": { 53 | "discovery_uri": "com.example.android://", 54 | "store_uri": "https://play.google.com/store/apps/details?id=com.example.android" 55 | }, 56 | "ios": { 57 | "store_uri": "https://apps.apple.com/app/apple-store/id123456789", 58 | "discovery_uri": "com.example.ios://" 59 | } 60 | }, 61 | "brand_assets": { 62 | "brand_last_modified": "2021-06-15", 63 | "brand_image_url": "https://www.example.com/assets/brand_image.svg", 64 | "brand_image_url_dark": "https://www.example.com/assets/brand_image_dark.svg", 65 | "color": "#C2D32C", 66 | "brand_terms_url": "https://www.example.com/assets/brand.pdf" 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/system_information-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "name": [ 7 | { 8 | "text": "Example Bike Rental", 9 | "language": "en" 10 | } 11 | ], 12 | "system_id": "example_cityname", 13 | "timezone": "America/Chicago", 14 | "languages": [ 15 | "en" 16 | ], 17 | "rental_apps": { 18 | "android": { 19 | "store_uri": "https://play.google.com/store/apps/details?id=com.example.android", 20 | "discovery_uri": "com.example.android://" 21 | }, 22 | "ios": { 23 | "store_uri": "https://apps.apple.com/app/apple-store/id123456789", 24 | "discovery_uri": "com.example.ios://" 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/system_pricing_plans-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "plans": [ 7 | { 8 | "plan_id": "plan2", 9 | "name": [ 10 | { 11 | "text": "One-Way", 12 | "language": "en" 13 | } 14 | ], 15 | "currency": "USD", 16 | "price": 2.00, 17 | "is_taxable": false, 18 | "description": [ 19 | { 20 | "text": "Includes 10km, overage fees apply after 10km.", 21 | "language": "en" 22 | } 23 | ], 24 | "per_km_pricing": [ 25 | { 26 | "start": 10, 27 | "rate": 1.00, 28 | "interval": 1.0, 29 | "end": 25 30 | }, 31 | { 32 | "start": 25, 33 | "rate": 0.50, 34 | "interval": 1.0 35 | }, 36 | { 37 | "start": 25, 38 | "rate": 3.00, 39 | "interval": 5.0 40 | } 41 | ] 42 | } 43 | ] 44 | } 45 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/system_pricing_plans-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "plans": [ 7 | { 8 | "plan_id": "plan3", 9 | "name": [ 10 | { 11 | "text": "Simple Rate", 12 | "language": "en" 13 | } 14 | ], 15 | "currency": "CAD", 16 | "price": 3.00, 17 | "is_taxable": true, 18 | "description": [ 19 | { 20 | "text": "$3 unlock fee, $0.25 per kilometer and 0.50 per minute.", 21 | "language": "en" 22 | } 23 | ], 24 | "per_km_pricing": [ 25 | { 26 | "start": 0, 27 | "rate": 0.25, 28 | "interval": 1.0 29 | } 30 | ], 31 | "per_min_pricing": [ 32 | { 33 | "start": 0, 34 | "rate": 0.50, 35 | "interval": 1.0 36 | } 37 | ] 38 | } 39 | ] 40 | } 41 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 86400, 4 | "version": "3.0", 5 | "data": { 6 | "regions": [ 7 | { 8 | "name": [ 9 | { 10 | "text": "North", 11 | "language": "en" 12 | } 13 | ], 14 | "region_id": "3" 15 | }, 16 | { 17 | "name": [ 18 | { 19 | "text": "East", 20 | "language": "en" 21 | } 22 | ], 23 | "region_id": "4" 24 | }, 25 | { 26 | "name": [ 27 | { 28 | "text": "South", 29 | "language": "en" 30 | } 31 | ], 32 | "region_id": "5" 33 | }, 34 | { 35 | "name": [ 36 | { 37 | "text": "West", 38 | "language": "en" 39 | } 40 | ], 41 | "region_id": "6" 42 | } 43 | ] 44 | } 45 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/vehicle_status-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "vehicles": [ 7 | { 8 | "vehicle_id": "973a5c94-c288-4a2b-afa6-de8aeb6ae2e5", 9 | "last_reported": "2023-07-17T13:34:13+02:00", 10 | "lat": 12.345678, 11 | "lon": 56.789012, 12 | "is_reserved": false, 13 | "is_disabled": false, 14 | "vehicle_type_id": "abc123", 15 | "rental_uris": { 16 | "android": "https://www.example.com/app?vehicle_id=973a5c94-c288-4a2b-afa6-de8aeb6ae2e5&platform=android&", 17 | "ios": "https://www.example.com/app?vehicle_id=973a5c94-c288-4a2b-afa6-de8aeb6ae2e5&platform=ios" 18 | } 19 | }, 20 | { 21 | "vehicle_id": "987fd100-b822-4347-86a4-b3eef8ca8b53", 22 | "last_reported": "2023-07-17T13:34:13+02:00", 23 | "is_reserved": false, 24 | "is_disabled": false, 25 | "vehicle_type_id": "def456", 26 | "current_range_meters": 6543.0, 27 | "station_id": "86", 28 | "pricing_plan_id": "plan3" 29 | } 30 | ] 31 | } 32 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/examples/specification/vehicle_status-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.0", 5 | "data": { 6 | "vehicles": [ 7 | { 8 | "vehicle_id": "45bd3fb7-a2d5-4def-9de1-c645844ba962", 9 | "last_reported": "2023-07-17T13:34:13+02:00", 10 | "lat": 12.345678, 11 | "lon": 56.789012, 12 | "is_reserved": false, 13 | "is_disabled": false, 14 | "vehicle_type_id": "abc123", 15 | "current_range_meters": 400000.0, 16 | "available_until": "2021-05-17T15:00:00Z", 17 | "home_station_id": "station1", 18 | "vehicle_equipment": [ 19 | "child_seat_a", 20 | "winter_tires" 21 | ] 22 | }, 23 | { 24 | "vehicle_id": "d4521def-7922-4e46-8e1d-8ac397239bd0", 25 | "last_reported": "2023-07-17T13:34:13+02:00", 26 | "is_reserved": false, 27 | "is_disabled": false, 28 | "vehicle_type_id": "def456", 29 | "current_fuel_percent": 0.7, 30 | "current_range_meters": 6543.0, 31 | "station_id": "86", 32 | "pricing_plan_id": "plan3", 33 | "home_station_id": "146", 34 | "vehicle_equipment": [ 35 | "child_seat_a" 36 | ] 37 | } 38 | ] 39 | } 40 | } -------------------------------------------------------------------------------- /models/rust/src/3.0/files/gbfs_versions.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "pyo3")] 2 | use pyo3::prelude::*; 3 | 4 | #[cfg(feature = "napi")] 5 | use napi_derive::napi; 6 | 7 | use serde::{Deserialize, Serialize}; 8 | 9 | use crate::v3_0::types::*; 10 | use crate::v3_0::urls::*; 11 | 12 | file_struct!(GbfsVersionsFile, GbfsVersionsData); 13 | 14 | #[cfg_attr(feature = "napi", napi(object))] 15 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 16 | #[serde_with::skip_serializing_none] 17 | #[derive(Serialize, Deserialize, Debug, Clone)] 18 | pub struct GbfsVersionsData { 19 | /// Contains one object, as defined below, for each of the available versions of a feed. 20 | /// The array MUST be sorted by increasing MAJOR and MINOR version number. 21 | pub versions: Vec, 22 | } 23 | 24 | #[cfg_attr(feature = "napi", napi(object))] 25 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 26 | #[serde_with::skip_serializing_none] 27 | #[derive(Serialize, Deserialize, Debug, Clone)] 28 | pub struct GbfsVersion { 29 | /// The semantic version of the feed in the form `X.Y`. 30 | pub version: String, 31 | /// URL of the corresponding `gbfs.json` endpoint. 32 | pub url: GbfsFileUrl, 33 | } 34 | -------------------------------------------------------------------------------- /models/rust/src/3.0/files/manifest.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "pyo3")] 2 | use pyo3::prelude::*; 3 | 4 | #[cfg(feature = "napi")] 5 | use napi_derive::napi; 6 | 7 | use crate::v3_0::types::*; 8 | 9 | use serde::{Deserialize, Serialize}; 10 | 11 | use crate::v3_0::files::gbfs_versions::GbfsVersion; 12 | 13 | file_struct!(ManifestFile, ManifestData); 14 | 15 | #[cfg_attr(feature = "napi", napi(object))] 16 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 17 | #[serde_with::skip_serializing_none] 18 | #[derive(Serialize, Deserialize, Debug, Clone)] 19 | pub struct ManifestData { 20 | pub datasets: Vec, 21 | } 22 | 23 | #[cfg_attr(feature = "napi", napi(object))] 24 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 25 | #[serde_with::skip_serializing_none] 26 | #[derive(Serialize, Deserialize, Debug, Clone)] 27 | pub struct System { 28 | /// The `system_id` from `system_information.json` for the corresponding data set(s). 29 | pub system_id: SystemID, 30 | /// Contains one object, as defined below, for each of the available versions of a feed. 31 | /// The array MUST be sorted by increasing MAJOR and MINOR version number. 32 | pub versions: Vec, 33 | } 34 | -------------------------------------------------------------------------------- /models/rust/src/3.0/files/system_alerts.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "pyo3")] 2 | use pyo3::prelude::*; 3 | 4 | #[cfg(feature = "napi")] 5 | use napi_derive::napi; 6 | 7 | use serde::{Deserialize, Serialize}; 8 | 9 | use crate::v3_0::types::*; 10 | 11 | file_struct!(SystemAlertsFile, SystemAlertsData); 12 | 13 | #[cfg_attr(feature = "napi", napi(object))] 14 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 15 | #[serde_with::skip_serializing_none] 16 | #[derive(Serialize, Deserialize, Debug, Clone)] 17 | pub struct SystemAlertsData { 18 | pub alerts: Vec, 19 | } 20 | 21 | #[cfg_attr(feature = "napi", napi(object))] 22 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 23 | #[serde_with::skip_serializing_none] 24 | #[derive(Serialize, Deserialize, Debug, Clone)] 25 | pub struct SystemAlert { 26 | /// Identifier for this alert. 27 | pub alert_id: AlertID, 28 | pub r#type: String, 29 | /// Indicating when the alert is in effect (for example, when the system or station is actually closed, or when a station is scheduled to be moved). 30 | pub times: Vec, 31 | /// If this is an alert that affects one or more stations, include their ID(s). Otherwise omit this field. 32 | /// If both [station_ids][SystemAlert::station_ids] and [region_ids][SystemAlert::region_ids] are omitted, this alert affects the entire system. 33 | pub station_ids: Option>, 34 | /// If this system has regions, and if this alert only affects certain regions, include their ID(s). 35 | pub region_ids: Option>, 36 | /// URL where the customer can learn more information about this alert. 37 | pub url: Option>, 38 | /// A short summary of this alert to be displayed to the customer. 39 | pub summary: Option>, 40 | /// Detailed description of the alert. 41 | pub description: Option>, 42 | /// Indicates the last time the info for the alert was updated. 43 | pub last_updated: Option, 44 | } 45 | 46 | #[cfg_attr(feature = "napi", napi(object))] 47 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 48 | #[serde_with::skip_serializing_none] 49 | #[derive(Serialize, Deserialize, Debug, Clone)] 50 | pub struct AlertTime { 51 | /// Start time of the alert. 52 | pub start: Timestamp, 53 | /// End time of the alert. If there is currently no end time planned for the alert, this can be omitted. 54 | pub end: Option, 55 | } 56 | -------------------------------------------------------------------------------- /models/rust/src/3.0/files/system_regions.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "pyo3")] 2 | use pyo3::prelude::*; 3 | 4 | #[cfg(feature = "napi")] 5 | use napi_derive::napi; 6 | 7 | use serde::{Deserialize, Serialize}; 8 | 9 | use crate::v3_0::types::*; 10 | 11 | file_struct!(SystemRegionsFile, SystemRegionsData); 12 | 13 | #[cfg_attr(feature = "napi", napi(object))] 14 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 15 | #[serde_with::skip_serializing_none] 16 | #[derive(Serialize, Deserialize, Debug, Clone)] 17 | pub struct SystemRegionsData { 18 | pub regions: Vec, 19 | } 20 | 21 | #[cfg_attr(feature = "napi", napi(object))] 22 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 23 | #[serde_with::skip_serializing_none] 24 | #[derive(Serialize, Deserialize, Debug, Clone)] 25 | pub struct Region { 26 | /// Identifier for the region. 27 | pub region_id: RegionID, 28 | /// Public name for this region. 29 | pub name: Vec, 30 | } 31 | -------------------------------------------------------------------------------- /models/rust/src/3.0/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod files; 2 | pub mod types; 3 | pub mod urls; 4 | 5 | #[cfg(feature = "pyo3")] 6 | use pyo3::prelude::*; 7 | 8 | #[cfg(feature = "napi")] 9 | use napi_derive::napi; 10 | 11 | use serde::{Deserialize, Serialize}; 12 | 13 | #[cfg_attr(feature = "napi", napi(object))] 14 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 15 | #[serde_with::skip_serializing_none] 16 | #[derive(Serialize, Deserialize, Debug, Clone)] 17 | pub struct GbfsObjects { 18 | pub vehicle_status: Option, 19 | pub station_status: Option, 20 | pub station_information: Option, 21 | pub vehicle_types: Option, 22 | pub system_pricing_plans: Option, 23 | } 24 | -------------------------------------------------------------------------------- /models/rust/src/3.0/urls.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "pyo3")] 2 | use pyo3::prelude::*; 3 | 4 | #[cfg(feature = "napi")] 5 | use napi_derive::napi; 6 | 7 | use serde::{Deserialize, Serialize}; 8 | use url; 9 | 10 | use super::files::*; 11 | 12 | macro_rules! file_url { 13 | ( $ty: ident, $body: ident ) => { 14 | #[cfg_attr(feature = "napi", napi(object))] 15 | #[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))] 16 | #[derive(Debug, Clone)] 17 | pub struct $ty { 18 | pub value: String, 19 | } 20 | 21 | impl $ty { 22 | pub fn new(value: &str) -> Self { 23 | Self { 24 | value: value.to_string(), 25 | } 26 | } 27 | 28 | pub fn get(&self) -> url::Url { 29 | self.value.parse().unwrap() 30 | } 31 | 32 | #[cfg(feature = "reqwest_blocking")] 33 | pub fn fetch(&self) -> Result<$body, reqwest::Error> { 34 | reqwest::blocking::get(self.get())?.json() 35 | } 36 | 37 | pub async fn fetch_async(&self) -> Result<$body, reqwest::Error> { 38 | reqwest::get(self.get()).await?.json().await 39 | } 40 | } 41 | 42 | impl From for $ty { 43 | fn from(value: String) -> Self { 44 | $ty { value } 45 | } 46 | } 47 | 48 | impl<'de> Deserialize<'de> for $ty { 49 | fn deserialize(deserializer: D) -> Result 50 | where 51 | D: serde::Deserializer<'de>, 52 | { 53 | let val: String = Deserialize::deserialize(deserializer)?; 54 | 55 | val.try_into().map_err(serde::de::Error::custom) 56 | } 57 | } 58 | 59 | impl Serialize for $ty { 60 | fn serialize(&self, serializer: S) -> Result 61 | where 62 | S: serde::Serializer, 63 | { 64 | self.value.serialize(serializer) 65 | } 66 | } 67 | }; 68 | } 69 | 70 | file_url!(ManifestFileUrl, ManifestFile); 71 | file_url!(GbfsFileUrl, GbfsFile); 72 | 73 | file_url!(GbfsVersionsFileUrl, GbfsVersionsFile); 74 | file_url!(GeofencingZonesFileUrl, GeofencingZonesFile); 75 | file_url!(StationInformationFileUrl, StationInformationFile); 76 | file_url!(StationStatusFileUrl, StationStatusFile); 77 | file_url!(SystemAlertsFileUrl, SystemAlertsFile); 78 | file_url!(SystemInformationFileUrl, SystemInformationFile); 79 | file_url!(SystemPricingPlansFileUrl, SystemPricingPlansFile); 80 | file_url!(SystemRegionsFileUrl, SystemRegionsFile); 81 | file_url!(VehicleStatusFileUrl, VehicleStatusFile); 82 | file_url!(VehicleTypesFileUrl, VehicleTypesFile); 83 | -------------------------------------------------------------------------------- /models/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[path = "3.0/mod.rs"] 2 | pub mod v3_0; 3 | -------------------------------------------------------------------------------- /models/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | v2.3/* 2 | !v2.3/index.d.ts 3 | v3.0/* 4 | !v3.0/index.d.ts 5 | v3.1-RC/* 6 | !v3.1-RC/index.d.ts 7 | -------------------------------------------------------------------------------- /models/typescript/.npmignore: -------------------------------------------------------------------------------- 1 | # overrides .gitignore to include all files in the root directory 2 | 3 | !v3.0/* 4 | !v3.0/index.d.ts 5 | !v3.1-RC/* 6 | !v3.1-RC/index.d.ts -------------------------------------------------------------------------------- /models/typescript/README.md: -------------------------------------------------------------------------------- 1 | # Typescript GBFS Language Bindings 2 | 3 | [![npm version](https://badge.fury.io/js/gbfs-typescript-types.svg)](http://badge.fury.io/js/gbfs-typescript-types) 4 | 5 | TypeScript types for parsing and working with General Bikeshare Feed Specification (GBFS) data, ensuring type safety and code consistency in TypeScript projects. 6 | 7 | ## Add the Dependency 8 | 9 | To use `gbfs-typescript-types` in your own project, you need to 10 | first install our [Node.js npm package](https://www.npmjs.com/package/gbfs-typescript-types): 11 | 12 | ``` 13 | npm install gbfs-typescript-types --save-dev 14 | ``` 15 | 16 | ## Versions 17 | - v2.3 18 | - v3.0 19 | - v3.1-RC 20 | 21 | ## Example Code 22 | ```typescript 23 | // top level import 24 | import { v3 } from 'gbfs-typescript-types'; 25 | 26 | // high level types 27 | import { SystemInformation } from 'gbfs-typescript-types/v3.0'; 28 | 29 | // lower level properties need to have path specified 30 | import { Data as SystemInformationData } from 'gbfs-typescript-types/v3.0/system_information'; 31 | import { Data as VehicleStatusData } from 'gbfs-typescript-types/v3.0/vehicle_status'; 32 | 33 | let vehicleStatus: v3.VehicleStatus; 34 | let systemInformationData: SystemInformationData; 35 | const url = "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/system-information"; 36 | fetch(url).then((systemInformationResponse) => { 37 | systemInformationResponse.json().then((systemInformationJson: SystemInformation) => { 38 | systemInformationJson // will have access to types 39 | systemInformationData = systemInformationJson.data; 40 | }) 41 | }) 42 | ``` 43 | -------------------------------------------------------------------------------- /models/typescript/index.d.ts: -------------------------------------------------------------------------------- 1 | export * as v23 from "./v2.3"; 2 | export * as v3 from "./v3.0"; 3 | export * as v31rc from "./v3.1-RC"; 4 | -------------------------------------------------------------------------------- /models/typescript/jest.config.js: -------------------------------------------------------------------------------- 1 | // jest.config.js 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | moduleNameMapper: { 6 | '^@/(.*)$': '/$1', 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /models/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gbfs-typescript-types", 3 | "version": "1.0.11", 4 | "description": "Language Bindings for GBFS in Typescript.", 5 | "keywords": [ 6 | "gbfs", 7 | "general-bikeshare-feed-specification", 8 | "typescript", 9 | "types", 10 | "type-definitions", 11 | "bikeshare", 12 | "bike-sharing", 13 | "mobility", 14 | "shared-mobility", 15 | "transportation", 16 | "feed-specification", 17 | "open-data", 18 | "npm-package", 19 | "javascript", 20 | "data-standard", 21 | "schema", 22 | "json-schema", 23 | "typescript-support", 24 | "npm", 25 | "types-for-gbfs" 26 | ], 27 | "license": "Apache-2.0", 28 | "types": "index.d.ts", 29 | "author": "MobilityData", 30 | "scripts": { 31 | "prepare": "cd ../../scripts && ./generate_typescript_models.sh", 32 | "test": "jest" 33 | }, 34 | "files": [ 35 | "index.d.ts", 36 | "v2.3", 37 | "v3.0", 38 | "v3.1-RC" 39 | ], 40 | "devDependencies": { 41 | "@types/jest": "^29.5.12", 42 | "jest": "^29.7.0", 43 | "ts-jest": "^29.1.2", 44 | "typescript": "^5.4.5" 45 | }, 46 | "dependencies": { 47 | "ts-interface-checker": "^1.0.2" 48 | }, 49 | "repository": { 50 | "type": "git", 51 | "url": "https://github.com/MobilityData/gbfs-json-schema.git" 52 | }, 53 | "bugs": { 54 | "url": "https://github.com/MobilityData/gbfs-json-schema/issues" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /models/typescript/v2.3/index.d.ts: -------------------------------------------------------------------------------- 1 | // Exports auto generated files 2 | 3 | export { FreeBikeStatus } from "./free_bike_status"; 4 | export { GbfsVersions } from "./gbfs_versions"; 5 | export { Gbfs } from "./gbfs"; 6 | export { GeofencingZones } from "./geofencing_zones"; 7 | export { StationInformation } from "./station_information"; 8 | export { StationStatus } from "./station_status"; 9 | export { SystemAlerts } from "./system_alerts"; 10 | export { SystemCalendar } from "./system_calendar"; 11 | export { SystemHours } from "./system_hours"; 12 | export { SystemInformation } from "./system_information"; 13 | export { SystemPricingPlans } from "./system_pricing_plans"; 14 | export { SystemRegions } from "./system_regions"; 15 | export { VehicleTypes } from "./vehicle_types"; 16 | -------------------------------------------------------------------------------- /models/typescript/v3.0/index.d.ts: -------------------------------------------------------------------------------- 1 | // Exports auto generated files 2 | 3 | export { GbfsVersions } from './gbfs_versions'; 4 | export { Gbfs } from './gbfs'; 5 | export { GeofencingZones } from './geofencing_zones'; 6 | export { Manifest } from './manifest'; 7 | export { StationInformation } from './station_information'; 8 | export { StationStatus } from './station_status'; 9 | export { SystemAlerts } from './system_alerts'; 10 | export { SystemInformation } from './system_information'; 11 | export { SystemPricingPlans } from './system_pricing_plans'; 12 | export { SystemRegions } from './system_regions'; 13 | export { VehicleStatus } from './vehicle_status'; 14 | export { VehicleTypes } from './vehicle_types'; 15 | -------------------------------------------------------------------------------- /models/typescript/v3.1-RC/index.d.ts: -------------------------------------------------------------------------------- 1 | // Exports auto generated files 2 | 3 | export { GbfsVersions } from './gbfs_versions'; 4 | export { Gbfs } from './gbfs'; 5 | export { GeofencingZones } from './geofencing_zones'; 6 | export { Manifest } from './manifest'; 7 | export { StationInformation } from './station_information'; 8 | export { StationStatus } from './station_status'; 9 | export { SystemAlerts } from './system_alerts'; 10 | export { SystemInformation } from './system_information'; 11 | export { SystemPricingPlans } from './system_pricing_plans'; 12 | export { SystemRegions } from './system_regions'; 13 | export { VehicleStatus } from './vehicle_status'; 14 | export { VehicleTypes } from './vehicle_types'; 15 | -------------------------------------------------------------------------------- /scripts/copyright.txt: -------------------------------------------------------------------------------- 1 | // Copyright 2024 MobilityData 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | -------------------------------------------------------------------------------- /scripts/generate_go_models.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script generates golang interfaces from the gbfs schemas (npx quicktype) 4 | # It takes the gbfs version number as an argument 5 | # Using this script can be done as follows: ./scripts/generate_go_models.sh 3.0 6 | # Just make sure to have the gbfs schemas in the correct folder ./vX.X 7 | 8 | gbfs_version="v$1" #$1 is the first argument passed to the script (the version number) 9 | gbfs_version_no_decimal=$(echo "$1" | tr -d '.' | tr -d -) 10 | parent_dir="$(dirname "$(dirname "$0")")" 11 | folder_path="../$parent_dir/$gbfs_version/" 12 | go_folder="../models/golang/" 13 | output_path="$go_folder/$gbfs_version/" 14 | test_path="$parent_dir/$gbfs_version/tests/ti/" 15 | copyright_file="$parent_dir/copyright.txt" 16 | 17 | # Iterate over all the files in the folder of the gbfs version 18 | for file in "$folder_path"/* 19 | do 20 | # Extract the file name from the path and add it to the array 21 | file_name=$(basename "$file") 22 | file_name_no_extension="${file_name%.*}" 23 | echo $file_name_no_extension 24 | 25 | output_path_directory="$output_path/$file_name_no_extension/" 26 | output_file="$output_path_directory/$file_name_no_extension.go" 27 | 28 | # # generates model files from schema files 29 | # npx quicktype -s schema "$folder_path$file_name" -o "$output_file.go" --prefer-unions --just-types 30 | mkdir -p $output_path_directory 31 | npx quicktype -s schema "$folder_path/$file_name" -o "$output_file" --package $file_name_no_extension 32 | 33 | # JSON cannot represent time.Time objects, so manually change time.Time to string and removes the import "time" 34 | # perl over sed because of compatibility issues with MacOS 35 | perl -pi -e "s/time\.Time/string/g" "$output_file" 36 | perl -pi -e "s/import \"time\"//g" "$output_file" 37 | 38 | # Inject copyright text at the top of the file 39 | temp_file=$(mktemp) 40 | cat "$copyright_file" "$output_file" > "$temp_file" 41 | mv "$temp_file" "$output_file" 42 | done 43 | -------------------------------------------------------------------------------- /scripts/generate_typescript_models.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script generates typescript interfaces from the gbfs schemas (npx quicktype) 4 | # It also generates files that help with testing the generated interfaces (npx ts-interface-builder) 5 | # This script should be executed from the scripts folder 6 | 7 | echo "Generating typescript models" 8 | 9 | gbfs_version="v$1" #$1 is the first argument passed to the script (the version number) 10 | parent_dir="$(dirname "$(dirname "$0")")" 11 | copyright_file="$parent_dir/copyright.txt" 12 | 13 | gbfs_versions=("v2.3" "v3.0" "v3.1-RC") 14 | 15 | for gbfs_version in "${gbfs_versions[@]}"; do 16 | echo "gbfs_version: $gbfs_version" 17 | folder_path="../$parent_dir/$gbfs_version/" 18 | typescript_folder="../models/typescript/" 19 | output_path="$typescript_folder/$gbfs_version/" 20 | test_path="$typescript_folder/$gbfs_version/test-type-checkers/" 21 | 22 | # Iterate over all the files in the folder of the gbfs version 23 | for file in "$folder_path"/* 24 | do 25 | mkdir -p $output_path 26 | mkdir -p $test_path 27 | # Extract the file name from the path and add it to the array 28 | file_name=$(basename "$file") 29 | file_name_no_extension="${file_name%.*}" 30 | echo $file_name_no_extension 31 | 32 | output_file="$output_path$file_name_no_extension" 33 | 34 | # generates model files from schema files 35 | npx quicktype -s schema "$folder_path$file_name" -o "$output_file.ts" --prefer-unions --just-types 36 | 37 | # JSON cannot represent Date objects, so manually change Date to string 38 | # perl over sed because of compatibility issues with MacOS 39 | perl -pi -e "s/Date;/string;/g" "$output_file.ts" 40 | 41 | # generates files for typescript testing 42 | npx ts-interface-builder "$output_file.ts" -o $test_path 43 | 44 | # renames the generated file to .d.ts as it's a declaration file 45 | # cannot be done right away to .d.ts as it messes up the name of the interfaces 46 | mv "$output_file.ts" "$output_file.d.ts" 47 | 48 | # Inject copyright text at the top of the file 49 | temp_file=$(mktemp) 50 | cat "$copyright_file" "$output_file.d.ts" > "$temp_file" 51 | mv "$temp_file" "$output_file.d.ts" 52 | done 53 | done 54 | 55 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gbfs-json-schema-scripts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "MobilityData", 9 | "devDependencies": { 10 | "quicktype": "^23.0.145", 11 | "ts-interface-builder": "^0.3.3" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /testFixtures/v2.3/free_bike_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606857968, 3 | "ttl": 300, 4 | "version": "2.3", 5 | "data": { 6 | "bikes": [ 7 | { 8 | "bike_id": "TST:Scooter:1234", 9 | "lat": 59.91465759277344, 10 | "lon": 10.760470390319824, 11 | "is_reserved": false, 12 | "is_disabled": true, 13 | "vehicle_type_id": "TST:VehicleType:Scooter", 14 | "current_range_meters": 1431.2, 15 | "pricing_plan_id": "TST:PricingPlan:Basic", 16 | "rental_uris": { 17 | "android": "test://rentme/TST:Scooter:1234", 18 | "ios": "test://rentme/TST:Scooter:1234", 19 | "web": "https://test.com/rentme/TST:Scooter:1234" 20 | } 21 | } 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testFixtures/v2.3/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606727710, 3 | "ttl": 300, 4 | "version": "2.3", 5 | "data": { 6 | "en": { 7 | "feeds": [ 8 | { 9 | "name": "gbfs_versions", 10 | "url": "https://test.com/gbfs_versions" 11 | }, 12 | { 13 | "name": "system_information", 14 | "url": "https://test.com/system_information" 15 | }, 16 | { 17 | "name": "vehicle_types", 18 | "url": "https://test.com/vehicle_types" 19 | }, 20 | { 21 | "name": "station_information", 22 | "url": "https://test.com/station_information" 23 | }, 24 | { 25 | "name": "station_status", 26 | "url": "https://test.com/station_status" 27 | }, 28 | { 29 | "name": "free_bike_status", 30 | "url": "https://test.com/free_bike_status" 31 | }, 32 | { 33 | "name": "system_regions", 34 | "url": "https://test.com/system_regions" 35 | }, 36 | { 37 | "name": "system_pricing_plans", 38 | "url": "https://test.com/system_pricing_plans" 39 | }, 40 | { 41 | "name": "system_hours", 42 | "url": "https://test.com/system_hours" 43 | }, 44 | { 45 | "name": "system_calendar", 46 | "url": "https://test.com/system_calendar" 47 | }, 48 | { 49 | "name": "system_alerts", 50 | "url": "https://test.com/system_alerts" 51 | }, 52 | { 53 | "name": "geofencing_zones", 54 | "url": "https://test.com/geofencing_zones" 55 | } 56 | ] 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /testFixtures/v2.3/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.3", 5 | "data": { 6 | "versions": [ 7 | { 8 | "version": "2.2", 9 | "url": "https://test.com/gbfs.json" 10 | } 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /testFixtures/v2.3/station_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.3", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "TST:Station:1", 9 | "name": "Cool bikes", 10 | "lat": 12.34, 11 | "lon": 45.67, 12 | "vehicle_type_capacity": { 13 | "TST:VehicleType:CityBike": 7 14 | } 15 | }, 16 | { 17 | "station_id": "TST:Station:2", 18 | "name": "Cooler bikes", 19 | "lat": 11.34, 20 | "lon": 44.67, 21 | "vehicle_type_capacity": { 22 | "TST:VehicleType:CityBike": 12 23 | } 24 | } 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /testFixtures/v2.3/station_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.3", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "TST:Station:1", 9 | "is_installed": true, 10 | "is_renting": true, 11 | "is_returning": true, 12 | "last_reported": 1434054678, 13 | "num_docks_available": 3, 14 | "vehicle_docks_available": [ 15 | { 16 | "vehicle_type_ids": ["TST:VehicleType:Scooter"], 17 | "count": 2 18 | }, 19 | { 20 | "vehicle_type_ids": ["TST:VehicleType:CityBike"], 21 | "count": 1 22 | } 23 | ], 24 | "num_bikes_available": 1, 25 | "vehicle_types_available": [ 26 | { 27 | "vehicle_type_id": "TST:VehicleType:Scooter", 28 | "count": 1 29 | }, 30 | { 31 | "vehicle_type_id": "TST:VehicleType:CityBike", 32 | "count": 0 33 | } 34 | ] 35 | }, 36 | { 37 | "station_id": "TST:Station:2", 38 | "is_installed": true, 39 | "is_renting": true, 40 | "is_returning": true, 41 | "last_reported": 1434054678, 42 | "num_docks_available": 8, 43 | "vehicle_docks_available": [ 44 | { 45 | "vehicle_type_ids": ["TST:VehicleType:Scooter"], 46 | "count": 6 47 | }, 48 | { 49 | "vehicle_type_ids": ["TST:VehicleType:CityBike"], 50 | "count": 2 51 | } 52 | ], 53 | "num_bikes_available": 6, 54 | "vehicle_types_available": [ 55 | { 56 | "vehicle_type_id": "TST:VehicleType:Scooter", 57 | "count": 2 58 | }, 59 | { 60 | "vehicle_type_id": "TST:VehicleType:CityBike", 61 | "count": 4 62 | } 63 | ] 64 | } 65 | ] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /testFixtures/v2.3/system_alerts.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.3", 5 | "data": { 6 | "alerts": [ 7 | { 8 | "alert_id": "TST:Alert:1", 9 | "type": "station_closure", 10 | "times": [ 11 | { 12 | "start": 1434054678, 13 | "end": 1434054987 14 | } 15 | ], 16 | "station_ids": ["TST:Station:1"], 17 | "summary": "Closed for maintenance", 18 | "description": "Station is closed to install more docks.", 19 | "last_updated": 1434054678 20 | } 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testFixtures/v2.3/system_calendar.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.3", 5 | "data": { 6 | "calendars": [ 7 | { 8 | "start_month": 1, 9 | "start_day": 1, 10 | "start_year": 2020, 11 | "end_month": 12, 12 | "end_day": 30, 13 | "end_year": 2021 14 | } 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /testFixtures/v2.3/system_hours.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1434054678, 3 | "ttl": 0, 4 | "version": "2.3", 5 | "data": { 6 | "rental_hours": [ 7 | { 8 | "user_types": ["member"], 9 | "days": ["sat", "sun"], 10 | "start_time": "00:00:00", 11 | "end_time": "23:59:59" 12 | }, 13 | { 14 | "user_types": ["nonmember"], 15 | "days": ["sat", "sun"], 16 | "start_time": "05:00:00", 17 | "end_time": "23:59:59" 18 | }, 19 | { 20 | "user_types": ["member", "nonmember"], 21 | "days": ["mon", "tue", "wed", "thu", "fri"], 22 | "start_time": "00:00:00", 23 | "end_time": "23:59:59" 24 | } 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /testFixtures/v2.3/system_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606830357, 3 | "ttl": 300, 4 | "version": "2.3", 5 | "data": { 6 | "system_id": "TST:System:Test", 7 | "language": "en", 8 | "name": "Test", 9 | "url": "https://www.test.com/", 10 | "timezone": "Europe/Oslo", 11 | "rental_apps": { 12 | "android": { 13 | "store_uri": "https://play.google.com/store/apps/details?id=com.testrental.android", 14 | "discovery_uri": "com.testrental.android://" 15 | }, 16 | "ios": { 17 | "store_uri": "https://apps.apple.com/app/apple-store/id123456789", 18 | "discovery_uri": "com.testrental.ios://" 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /testFixtures/v2.3/system_pricing_plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606858558, 3 | "ttl": 300, 4 | "version": "2.3", 5 | "data": { 6 | "plans": [ 7 | { 8 | "plan_id": "TST:PricingPlan:Basic", 9 | "name": "Basic", 10 | "currency": "NOK", 11 | "price": 0.0, 12 | "is_taxable": false, 13 | "description": "Start NOK 0, Per minute 3,50 NOK", 14 | "per_min_pricing": [ 15 | { 16 | "start": 0, 17 | "rate": 3.5, 18 | "interval": 1 19 | } 20 | ] 21 | } 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /testFixtures/v2.3/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606858379, 3 | "ttl": 300, 4 | "version": "2.3", 5 | "data": { 6 | "regions": [ 7 | { 8 | "region_id": "TST:Region:Sahara", 9 | "name": "Sahara" 10 | } 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /testFixtures/v2.3/vehicle_types.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": 1606830898, 3 | "ttl": 300, 4 | "version": "2.3", 5 | "data": { 6 | "vehicle_types": [ 7 | { 8 | "vehicle_type_id": "TST:VehicleType:Scooter", 9 | "form_factor": "scooter", 10 | "propulsion_type": "electric", 11 | "max_range_meters": 0.0 12 | }, 13 | { 14 | "vehicle_type_id": "TST:VehicleType:CityBike", 15 | "form_factor": "bicycle", 16 | "propulsion_type": "human" 17 | } 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testFixtures/v3.0/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2019-07-04T13:33:03.969Z", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "feeds": [ 7 | { 8 | "name": "system_information", 9 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/system-information" 10 | }, 11 | { 12 | "name": "vehicle_status", 13 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/vehicle-status" 14 | }, 15 | { 16 | "name": "vehicle_types", 17 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/vehicle-types" 18 | }, 19 | { 20 | "name": "system_pricing_plans", 21 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/system-pricing-plans" 22 | }, 23 | { 24 | "name": "station_information", 25 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/station-information" 26 | }, 27 | { 28 | "name": "station_status", 29 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/station-status" 30 | }, 31 | { 32 | "name": "geofencing_zones", 33 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/geofencing-zones" 34 | }, 35 | { 36 | "name": "gbfs_versions", 37 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0/versions" 38 | } 39 | ] 40 | } 41 | } -------------------------------------------------------------------------------- /testFixtures/v3.0/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2019-07-04T13:33:03.969Z", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "versions": [ 7 | { 8 | "version": "2.1", 9 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/2.1" 10 | }, 11 | { 12 | "version": "2.2", 13 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/2.2" 14 | }, 15 | { 16 | "version": "2.3", 17 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/2.3" 18 | }, 19 | { 20 | "version": "3.0", 21 | "url": "https://berlin.example.tier-services.io/tier_paris/gbfs/3.0" 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /testFixtures/v3.0/station_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2019-07-04T13:33:03.969Z", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "6efbec5a-6b8c-455b-bed2-8d66be6d6a4b", 9 | "is_installed": true, 10 | "is_renting": true, 11 | "is_returning": true, 12 | "last_reported": "2019-07-04T13:33:03.969Z", 13 | "vehicle_types_available": [ 14 | { 15 | "vehicle_type_id": "ebicycle_paris", 16 | "count": 0 17 | }, 18 | { 19 | "vehicle_type_id": "escooter_paris", 20 | "count": 0 21 | } 22 | ], 23 | "num_vehicles_available": 0 24 | } 25 | ] 26 | } 27 | } -------------------------------------------------------------------------------- /testFixtures/v3.0/system_alerts.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2019-07-04T13:33:03.969Z", 3 | "ttl": 3600, 4 | "version": "3.0", 5 | "data": { 6 | "alerts": [ 7 | { 8 | "alert_id": "1", 9 | "summary": [ 10 | { 11 | "language": "en", 12 | "text": "High Wind Warning" 13 | } 14 | ], 15 | "type": "station_closure" 16 | } 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /testFixtures/v3.0/system_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "feed_contact_email": "emailaddress@email.app", 4 | "languages": [ 5 | "en" 6 | ], 7 | "manifest_url": "https://api.berlin.example.app/gbfs/v3/manifest.json", 8 | "name": [ 9 | { 10 | "language": "en", 11 | "text": "Check Technologies" 12 | } 13 | ], 14 | "opening_hours": "Mo,Tu,We,Th,Fr,Sa,Su 00:00-23:59", 15 | "system_id": "example_london", 16 | "terms_last_updated": "2012-04-23", 17 | "terms_url": [ 18 | { 19 | "language": "en", 20 | "text": "https://berlin.example.app" 21 | } 22 | ], 23 | "timezone": "Europe/Amsterdam" 24 | }, 25 | "last_updated": "2019-07-04T13:33:03.969Z", 26 | "ttl": 3600, 27 | "version": "3.0" 28 | } -------------------------------------------------------------------------------- /testFixtures/v3.0/system_pricing_plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2019-07-04T13:33:03.969Z", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "plans": [ 7 | { 8 | "plan_id": "87c7ed6e-aecf-4900-9a85-2a78efbba65b", 9 | "name": [ 10 | { 11 | "text": "bike-standard-pricing-paris", 12 | "language": "en" 13 | } 14 | ], 15 | "currency": "EUR", 16 | "price": 1, 17 | "is_taxable": false, 18 | "description": [ 19 | { 20 | "text": "Standard pricing for bikes, 1.00 EUR to unlock, 0.28 EUR per minute to rent", 21 | "language": "en" 22 | } 23 | ], 24 | "per_min_pricing": [ 25 | { 26 | "start": 0, 27 | "rate": 0.28, 28 | "interval": 1 29 | } 30 | ] 31 | }, 32 | { 33 | "plan_id": "e1df7c5c-3232-422f-bf38-94cabb55fb99", 34 | "name": [ 35 | { 36 | "text": "scooter-standard-pricing-paris", 37 | "language": "en" 38 | } 39 | ], 40 | "currency": "EUR", 41 | "price": 1.2, 42 | "is_taxable": false, 43 | "description": [ 44 | { 45 | "text": "Standard pricing for scooters, 1.20 EUR to unlock, 0.28 EUR per minute to rent", 46 | "language": "en" 47 | } 48 | ], 49 | "per_min_pricing": [ 50 | { 51 | "start": 0, 52 | "rate": 0.28, 53 | "interval": 1 54 | } 55 | ] 56 | } 57 | ] 58 | } 59 | } -------------------------------------------------------------------------------- /testFixtures/v3.0/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2024-04-18T09:37:59.000+00:00", 3 | "ttl": 21600, 4 | "version": "3.0", 5 | "data": { 6 | "regions": [ 7 | { 8 | "region_id": "YVO:Region:5", 9 | "name": [ 10 | { 11 | "text": "Gothenburg", 12 | "language": "en" 13 | } 14 | ] 15 | } 16 | ] 17 | } 18 | } -------------------------------------------------------------------------------- /testFixtures/v3.0/vehicle_types.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2019-07-04T13:33:03.969Z", 3 | "ttl": 60, 4 | "version": "3.0", 5 | "data": { 6 | "vehicle_types": [ 7 | { 8 | "vehicle_type_id": "ebicycle_paris", 9 | "form_factor": "bicycle", 10 | "propulsion_type": "electric_assist", 11 | "max_range_meters": 90000, 12 | "name": [ 13 | { 14 | "text": "Electric Bicycle", 15 | "language": "en" 16 | } 17 | ], 18 | "default_pricing_plan_id": "87c7ed6e-aecf-4900-9a85-2a78efbba65b" 19 | } 20 | ] 21 | } 22 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.1-RC", 5 | "data": { 6 | "feeds": [ 7 | { 8 | "name": "system_information", 9 | "url": "https://www.example.com/gbfs/1/system_information" 10 | }, 11 | { 12 | "name": "station_information", 13 | "url": "https://www.example.com/gbfs/1/station_information" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.1-RC", 5 | "data": { 6 | "versions": [ 7 | { 8 | "version": "2.0", 9 | "url": "https://www.example.com/gbfs/2/gbfs" 10 | }, 11 | { 12 | "version": "3.1-RC", 13 | "url": "https://www.example.com/gbfs/3.1-RC/gbfs" 14 | } 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/geofencing_zones.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 60, 4 | "version": "3.1-RC", 5 | "data": { 6 | "geofencing_zones": { 7 | "type": "FeatureCollection", 8 | "features": [ 9 | { 10 | "type": "Feature", 11 | "geometry": { 12 | "type": "MultiPolygon", 13 | "coordinates": [ 14 | [ 15 | [ 16 | [ 17 | -122.578067, 18 | 45.562982 19 | ], 20 | [ 21 | -122.661838, 22 | 45.562741 23 | ], 24 | [ 25 | -122.661151, 26 | 45.504542 27 | ], 28 | [ 29 | -122.578926, 30 | 45.5046625 31 | ], 32 | [ 33 | -122.578067, 34 | 45.562982 35 | ] 36 | ] 37 | ] 38 | ] 39 | }, 40 | "properties": { 41 | "name": [ 42 | { 43 | "text": "NE 24th/NE Knott", 44 | "language": "en" 45 | } 46 | ], 47 | "start": "2023-07-17T13:34:13+02:00", 48 | "end": "2024-07-18T13:34:13+02:00", 49 | "rules": [ 50 | { 51 | "vehicle_type_ids": [ 52 | "moped1", 53 | "car1" 54 | ], 55 | "ride_start_allowed": true, 56 | "ride_end_allowed": true, 57 | "maximum_speed_kph": 10, 58 | "station_parking": true, 59 | "ride_through_allowed": false 60 | } 61 | ] 62 | } 63 | } 64 | ] 65 | }, 66 | "global_rules": [ 67 | { 68 | "ride_start_allowed": false, 69 | "ride_end_allowed": false, 70 | "ride_through_allowed": true 71 | } 72 | ] 73 | } 74 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/station_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.1-RC", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "pga", 9 | "name": [ 10 | { 11 | "text": "Parking garage A", 12 | "language": "en" 13 | } 14 | ], 15 | "lat": 12.345678, 16 | "lon": 45.678901, 17 | "station_opening_hours": "Su-Th 05:00-22:00; Fr-Sa 05:00-01:00", 18 | "parking_type": "underground_parking", 19 | "parking_hoop": false, 20 | "contact_phone": "+33109874321", 21 | "is_charging_station": true, 22 | "vehicle_docks_capacity": [ 23 | { 24 | "vehicle_type_ids": ["abc123"], 25 | "count": 7 26 | } 27 | ] 28 | } 29 | ] 30 | } 31 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/station_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.1-RC", 5 | "data": { 6 | "stations": [ 7 | { 8 | "station_id": "station1", 9 | "is_installed": true, 10 | "is_renting": true, 11 | "is_returning": true, 12 | "last_reported": "2023-07-17T13:34:13+02:00", 13 | "num_docks_available": 3, 14 | "num_docks_disabled" : 1, 15 | "vehicle_docks_available": [ 16 | { 17 | "vehicle_type_ids": [ "abc123", "def456" ], 18 | "count": 2 19 | }, 20 | { 21 | "vehicle_type_ids": [ "def456" ], 22 | "count": 1 23 | } 24 | ], 25 | "num_vehicles_available": 1, 26 | "num_vehicles_disabled": 2, 27 | "vehicle_types_available": [ 28 | { 29 | "vehicle_type_id": "abc123", 30 | "count": 1 31 | }, 32 | { 33 | "vehicle_type_id": "def456", 34 | "count": 0 35 | } 36 | ] 37 | }, 38 | { 39 | "station_id": "station2", 40 | "is_installed": true, 41 | "is_renting": true, 42 | "is_returning": true, 43 | "last_reported": "2023-07-17T13:34:13+02:00", 44 | "num_docks_available": 8, 45 | "num_docks_disabled" : 1, 46 | "vehicle_docks_available": [ 47 | { 48 | "vehicle_type_ids": [ "abc123" ], 49 | "count": 6 50 | }, 51 | { 52 | "vehicle_type_ids": [ "def456" ], 53 | "count": 2 54 | } 55 | ], 56 | "num_vehicles_available": 6, 57 | "num_vehicles_disabled": 1, 58 | "vehicle_types_available": [ 59 | { 60 | "vehicle_type_id": "abc123", 61 | "count": 2 62 | }, 63 | { 64 | "vehicle_type_id": "def456", 65 | "count": 4 66 | } 67 | ] 68 | } 69 | ] 70 | } 71 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/system_alerts.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 60, 4 | "version": "3.1-RC", 5 | "data": { 6 | "alerts": [ 7 | { 8 | "alert_id": "21", 9 | "type": "station_closure", 10 | "station_ids": [ 11 | "123", 12 | "456", 13 | "789" 14 | ], 15 | "times": [ 16 | { 17 | "start": "2023-07-17T13:34:13+02:00", 18 | "end": "2023-07-18T13:34:13+02:00" 19 | } 20 | ], 21 | "url": [ 22 | { 23 | "text": "https://example.com/more-info", 24 | "language": "en" 25 | } 26 | ], 27 | "summary": [ 28 | { 29 | "text": "Disruption of Service", 30 | "language": "en" 31 | } 32 | ], 33 | "description": [ 34 | { 35 | "text": "The three stations on Broadway will be out of service from 12:00am Nov 3 to 3:00pm Nov 6th to accommodate road work", 36 | "language": "en" 37 | } 38 | ], 39 | "last_updated": "2023-07-17T13:34:13+02:00" 40 | } 41 | ] 42 | } 43 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/system_information.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 1800, 4 | "version": "3.1-RC", 5 | "data": { 6 | "system_id": "example_cityname", 7 | "languages": ["en"], 8 | "name": [ 9 | { 10 | "text": "Example Bike Rental", 11 | "language": "en" 12 | } 13 | ], 14 | "short_name": [ 15 | { 16 | "text": "Example Bike", 17 | "language": "en" 18 | } 19 | ], 20 | "operator": [ 21 | { 22 | "text": "Example Sharing, Inc", 23 | "language": "en" 24 | } 25 | ], 26 | "opening_hours": "Apr 1-Nov 3 00:00-24:00", 27 | "start_date": "2010-06-10", 28 | "url": "https://www.example.com", 29 | "purchase_url": "https://www.example.com", 30 | "phone_number": "+18005551234", 31 | "email": "customerservice@example.com", 32 | "feed_contact_email": "datafeed@example.com", 33 | "timezone": "America/Chicago", 34 | "license_url": "https://www.example.com/data-license.html", 35 | "terms_url": [ 36 | { 37 | "text": "https://www.example.com/en/terms", 38 | "language": "en" 39 | } 40 | ], 41 | "terms_last_updated": "2021-06-21", 42 | "privacy_url": [ 43 | { 44 | "text": "https://www.example.com/en/privacy-policy", 45 | "language": "en" 46 | } 47 | ], 48 | "privacy_last_updated": "2019-01-13", 49 | "rental_apps": { 50 | "android": { 51 | "discovery_uri": "com.example.android://", 52 | "store_uri": "https://play.google.com/store/apps/details?id=com.example.android" 53 | }, 54 | "ios": { 55 | "store_uri": "https://apps.apple.com/app/apple-store/id123456789", 56 | "discovery_uri": "com.example.ios://" 57 | } 58 | }, 59 | "brand_assets": { 60 | "brand_last_modified": "2021-06-15", 61 | "brand_image_url": "https://www.example.com/assets/brand_image.svg", 62 | "brand_image_url_dark": "https://www.example.com/assets/brand_image_dark.svg", 63 | "color": "#C2D32C", 64 | "brand_terms_url": "https://www.example.com/assets/brand.pdf" 65 | } 66 | 67 | } 68 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/system_pricing_plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 0, 4 | "version": "3.1-RC", 5 | "data": { 6 | "plans": [ 7 | { 8 | "plan_id": "plan2", 9 | "name": [ 10 | { 11 | "text": "One-Way", 12 | "language": "en" 13 | } 14 | ], 15 | "currency": "USD", 16 | "price": 2.00, 17 | "reservation_price_per_min": 0.15, 18 | "is_taxable": false, 19 | "description": [ 20 | { 21 | "text": "Includes 10km, overage fees apply after 10km.", 22 | "language": "en" 23 | } 24 | ], 25 | "per_km_pricing": [ 26 | { 27 | "start": 10, 28 | "rate": 1.00, 29 | "interval": 1, 30 | "end": 25 31 | }, 32 | { 33 | "start": 25, 34 | "rate": 0.50, 35 | "interval": 1 36 | }, 37 | { 38 | "start": 25, 39 | "rate": 3.00, 40 | "interval": 5 41 | } 42 | ] 43 | } 44 | ] 45 | } 46 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl": 86400, 4 | "version": "3.1-RC", 5 | "data": { 6 | "regions": [ 7 | { 8 | "name": [ 9 | { 10 | "text": "North", 11 | "language": "en" 12 | } 13 | ], 14 | "region_id": "3" 15 | }, 16 | { 17 | "name": [ 18 | { 19 | "text": "East", 20 | "language": "en" 21 | } 22 | ], 23 | "region_id": "4" 24 | }, 25 | { 26 | "name": [ 27 | { 28 | "text": "South", 29 | "language": "en" 30 | } 31 | ], 32 | "region_id": "5" 33 | }, 34 | { 35 | "name": [ 36 | { 37 | "text": "West", 38 | "language": "en" 39 | } 40 | ], 41 | "region_id": "6" 42 | } 43 | ] 44 | } 45 | } -------------------------------------------------------------------------------- /testFixtures/v3.1-RC/vehicle_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_updated": "2023-07-17T13:34:13+02:00", 3 | "ttl":0, 4 | "version": "3.1-RC", 5 | "data":{ 6 | "vehicles":[ 7 | { 8 | "vehicle_id":"973a5c94-c288-4a2b-afa6-de8aeb6ae2e5", 9 | "last_reported": "2023-07-17T13:34:13+02:00", 10 | "lat":12.345678, 11 | "lon":56.789012, 12 | "is_reserved":false, 13 | "is_disabled":false, 14 | "vehicle_type_id":"abc123", 15 | "rental_uris": { 16 | "android": "https://www.example.com/app?vehicle_id=973a5c94-c288-4a2b-afa6-de8aeb6ae2e5&platform=android&", 17 | "ios": "https://www.example.com/app?vehicle_id=973a5c94-c288-4a2b-afa6-de8aeb6ae2e5&platform=ios" 18 | } 19 | }, 20 | { 21 | "vehicle_id":"987fd100-b822-4347-86a4-b3eef8ca8b53", 22 | "last_reported": "2023-07-17T13:34:13+02:00", 23 | "is_reserved":false, 24 | "is_disabled":false, 25 | "vehicle_type_id":"def456", 26 | "current_range_meters":6543.0, 27 | "station_id":"86", 28 | "pricing_plan_id":"plan3" 29 | } 30 | ] 31 | } 32 | } -------------------------------------------------------------------------------- /v1.0/free_bike_status.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v1.0/gbfs.md#free_bike_statusjson", 4 | "description": "Describes the vehicles that are available for rent (as of v2.1-RC2).", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in POSIX time.", 9 | "type": "integer", 10 | "minimum": 0, 11 | "maximum": 1924988399 12 | }, 13 | "ttl": { 14 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 15 | "type": "integer", 16 | "minimum": 0 17 | }, 18 | "data": { 19 | "description": "Array that contains one object per bike as defined below.", 20 | "type": "object", 21 | "properties": { 22 | "bikes": { 23 | "type": "array", 24 | "items": { 25 | "type": "object", 26 | "properties": { 27 | "bike_id": { 28 | "description": "Rotating (as of v2.0) identifier of a vehicle.", 29 | "type": "string" 30 | }, 31 | "lat": { 32 | "description": "The latitude of the vehicle.", 33 | "type": "number", 34 | "minimum": -90, 35 | "maximum": 90 36 | }, 37 | "lon": { 38 | "description": "The longitude of the vehicle.", 39 | "type": "number", 40 | "minimum": -180, 41 | "maximum": 180 42 | }, 43 | "is_reserved": { 44 | "description": "Is the vehicle currently reserved?", 45 | "oneOf": [{ "type": "boolean" }, { "type": "number" }] 46 | }, 47 | "is_disabled": { 48 | "description": "Is the vehicle currently disabled (broken)?", 49 | "oneOf": [{ "type": "boolean" }, { "type": "number" }] 50 | } 51 | }, 52 | "required": ["bike_id", "lat", "lon", "is_reserved", "is_disabled"] 53 | } 54 | } 55 | }, 56 | "required": ["bikes"] 57 | } 58 | }, 59 | "required": ["last_updated", "ttl", "data"] 60 | } 61 | -------------------------------------------------------------------------------- /v1.0/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v1.0/gbfs.md#gbfsjson", 4 | "description": "Auto-discovery file that links to all of the other files published by the system.", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in POSIX time.", 9 | "type": "integer", 10 | "minimum": 0, 11 | "maximum": 1924988399 12 | }, 13 | "ttl": { 14 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 15 | "type": "integer", 16 | "minimum": 0 17 | }, 18 | "data": { 19 | "description": "Response data in the form of name:value pairs.", 20 | "type": "object", 21 | "patternProperties": { 22 | "^[a-zA-Z]{2}$": { 23 | "type": "object", 24 | "properties": { 25 | "feeds": { 26 | "description": "An array of all of the feeds that are published by the auto-discovery file. Each element in the array is an object with the keys below.", 27 | "type": "array", 28 | "items": { 29 | "type": "object", 30 | "properties": { 31 | "name": { 32 | "type": "string" 33 | }, 34 | "url": { 35 | "type": "string" 36 | } 37 | }, 38 | "required": ["name", "url"] 39 | }, 40 | "minItems": 1, 41 | "contains": { 42 | "properties": { 43 | "name": { "const": "system_information" } 44 | } 45 | } 46 | } 47 | }, 48 | "required": ["feeds"] 49 | } 50 | }, 51 | "minProperties": 1, 52 | "additionalProperties": false 53 | } 54 | }, 55 | "required": ["last_updated", "ttl", "data"] 56 | } 57 | -------------------------------------------------------------------------------- /v1.0/system_calendar.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v1.0/gbfs.md#system_calendarjson", 4 | "description": "Describes the operating calendar for a system.", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in POSIX time.", 9 | "type": "integer", 10 | "minimum": 0, 11 | "maximum": 1924988399 12 | }, 13 | "ttl": { 14 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 15 | "type": "integer", 16 | "minimum": 0 17 | }, 18 | "data": { 19 | "description": "Array that contains operations calendar for the system.", 20 | "type": "object", 21 | "properties": { 22 | "calendars": { 23 | "type": "array", 24 | "items": { 25 | "type": "object", 26 | "properties": { 27 | "start_month": { 28 | "description": "Starting month for the system operations.", 29 | "type": "integer", 30 | "minimum": 1, 31 | "maximum": 12 32 | }, 33 | "start_day": { 34 | "description": "Starting day for the system operations.", 35 | "type": "integer", 36 | "minimum": 1, 37 | "maximum": 31 38 | }, 39 | "start_year": { 40 | "description": "Starting year for the system operations.", 41 | "type": "integer" 42 | }, 43 | "end_month": { 44 | "description": "End month for the system operations.", 45 | "type": "integer", 46 | "minimum": 1, 47 | "maximum": 12 48 | }, 49 | "end_day": { 50 | "description": "End day for the system operations.", 51 | "type": "integer", 52 | "minimum": 1, 53 | "maximum": 31 54 | }, 55 | "end_year": { 56 | "description": "End year for the system operations.", 57 | "type": "integer" 58 | } 59 | }, 60 | "required": ["start_month", "start_day", "end_month", "end_day"] 61 | }, 62 | "minItems": 1 63 | } 64 | }, 65 | "required": ["calendars"] 66 | } 67 | }, 68 | "required": ["last_updated", "ttl", "data"] 69 | } 70 | -------------------------------------------------------------------------------- /v1.0/system_hours.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v1.0/gbfs.md#system_hoursjson", 4 | "description": "Describes the system hours of operation.", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in POSIX time.", 9 | "type": "integer", 10 | "minimum": 0, 11 | "maximum": 1924988399 12 | }, 13 | "ttl": { 14 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 15 | "type": "integer", 16 | "minimum": 0 17 | }, 18 | "data": { 19 | "description": "Array that contains system hours of operations.", 20 | "type": "object", 21 | "properties": { 22 | "rental_hours": { 23 | "type": "array", 24 | "items": { 25 | "type": "object", 26 | "properties": { 27 | "user_type": { 28 | "description": "Array of member and nonmember value(s) indicating that this set of rental hours applies to either members or non-members only.", 29 | "type": "array", 30 | "items": { 31 | "type": "string", 32 | "enum": ["member", "nonmember"] 33 | } 34 | }, 35 | "days": { 36 | "description": "An array of abbreviations (first 3 letters) of English names of the days of the week for which this object applies.", 37 | "type": "array", 38 | "items": { 39 | "type": "string", 40 | "enum": ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] 41 | } 42 | }, 43 | "start_time": { 44 | "description": "Start time for the hours of operation of the system.", 45 | "type": "string", 46 | "pattern": "^[0-9]{2}:[0-9]{2}:[0-9]{2}$" 47 | }, 48 | "end_time": { 49 | "description": "End time for the hours of operation of the system.", 50 | "type": "string", 51 | "pattern": "^[0-9]{2}:[0-9]{2}:[0-9]{2}$" 52 | } 53 | }, 54 | "required": ["user_types", "days", "start_time", "end_time"] 55 | } 56 | } 57 | }, 58 | "required": ["rental_hours"] 59 | } 60 | }, 61 | "required": ["last_updated", "ttl", "data"] 62 | } 63 | -------------------------------------------------------------------------------- /v1.0/system_pricing_plans.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v1.0/gbfs.md#system_pricing_plansjson", 4 | "description": "Describes the pricing schemes of the system.", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in POSIX time.", 9 | "type": "integer", 10 | "minimum": 0, 11 | "maximum": 1924988399 12 | }, 13 | "ttl": { 14 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 15 | "type": "integer", 16 | "minimum": 0 17 | }, 18 | "data": { 19 | "description": "Array that contains one object per plan as defined below.", 20 | "type": "object", 21 | "properties": { 22 | "plans": { 23 | "type": "array", 24 | "items": { 25 | "type": "object", 26 | "properties": { 27 | "plan_id": { 28 | "description": "Identifier of a pricing plan in the system.", 29 | "type": "string" 30 | }, 31 | "url": { 32 | "description": "URL where the customer c…bout this pricing plan.", 33 | "type": "string" 34 | }, 35 | "name": { 36 | "description": "Name of this pricing plan.", 37 | "type": "string" 38 | }, 39 | "currency": { 40 | "description": "Currency used to pay the fare in ISO 4217 code.", 41 | "type": "string", 42 | "minLength": 3, 43 | "maxLength": 3 44 | }, 45 | "price": { 46 | "description": "Fare price.", 47 | "type": "number" 48 | }, 49 | "is_taxable": { 50 | "description": "Will additional tax be added to the base price?", 51 | "type": ["number"] 52 | }, 53 | "description": { 54 | "description": "Customer-readable description of the pricing plan.", 55 | "type": "string" 56 | } 57 | }, 58 | "required": [ 59 | "plan_id", 60 | "name", 61 | "currency", 62 | "price", 63 | "is_taxable", 64 | "description" 65 | ] 66 | } 67 | } 68 | }, 69 | "required": ["plans"] 70 | } 71 | }, 72 | "required": ["last_updated", "ttl", "data"] 73 | } 74 | -------------------------------------------------------------------------------- /v1.0/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v1.0/gbfs.md#system_regionsjson", 4 | "description": "Describes regions for a system that is broken up by geographic or political region.", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in POSIX time.", 9 | "type": "integer", 10 | "minimum": 0, 11 | "maximum": 1924988399 12 | }, 13 | "ttl": { 14 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 15 | "type": "integer", 16 | "minimum": 0 17 | }, 18 | "data": { 19 | "description": "Describe regions for a system that is broken up by geographic or political region.", 20 | "type": "object", 21 | "properties": { 22 | "regions": { 23 | "description": "Array of regions.", 24 | "type": "array", 25 | "items": { 26 | "type": "object", 27 | "properties": { 28 | "region_id": { 29 | "description": "identifier of the region.", 30 | "type": "string" 31 | }, 32 | "name": { 33 | "description": "Public name for this region.", 34 | "type": "string" 35 | } 36 | }, 37 | "required": ["region_id", "name"] 38 | } 39 | } 40 | }, 41 | "required": ["regions"] 42 | } 43 | }, 44 | "required": ["last_updated", "ttl", "data"] 45 | } 46 | -------------------------------------------------------------------------------- /v1.1/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": 4 | "https://github.com/MobilityData/gbfs/blob/v1.1/gbfs.md#gbfs_versionsjson-added-in-v11", 5 | "description": 6 | "Lists all feed endpoints published according to version sof the GBFS documentation. (added in v1.1)", 7 | "type": "object", 8 | "properties": { 9 | "last_updated": { 10 | "description": 11 | "Last time the data in the feed was updated in POSIX time.", 12 | "type": "integer", 13 | "minimum": 1450155600 14 | }, 15 | "ttl": { 16 | "description": 17 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 18 | "type": "integer", 19 | "minimum": 0 20 | }, 21 | "version": { 22 | "description": 23 | "GBFS version number to which the feed conforms, according to the versioning framework.", 24 | "type": "string", 25 | "const": "1.1" 26 | }, 27 | "data": { 28 | "description": "Response data in the form of name:value pairs.", 29 | "type": "object", 30 | "properties": { 31 | "versions": { 32 | "description": 33 | "Contains one object, as defined below, for each of the available versions of a feed. The array must be sorted by increasing MAJOR and MINOR version number.", 34 | "type": "array", 35 | "items": { 36 | "type": "object", 37 | "properties": { 38 | "version": { 39 | "description": 40 | "The semantic version of the feed in the form X.Y", 41 | "type": "string", 42 | "enum": [ 43 | "1.0", 44 | "1.1", 45 | "2.0", 46 | "2.1", 47 | "2.2", 48 | "2.3", 49 | "3.0" 50 | ] 51 | }, 52 | "url": { 53 | "description": "URL of the corresponding gbfs.json endpoint", 54 | "type": "string", 55 | "format": "uri" 56 | } 57 | }, 58 | "required": ["version", "url"] 59 | } 60 | } 61 | }, 62 | "required": ["versions"], 63 | "additionalProperties": false 64 | } 65 | }, 66 | "required": ["last_updated", "ttl", "version", "data"] 67 | } 68 | -------------------------------------------------------------------------------- /v1.1/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v1.1/gbfs.md#system_regionsjson", 4 | "description": 5 | "Describes regions for a system that is broken up by geographic or political region.", 6 | "type": "object", 7 | "properties": { 8 | "last_updated": { 9 | "description": 10 | "Last time the data in the feed was updated in POSIX time.", 11 | "type": "integer", 12 | "minimum": 1450155600 13 | }, 14 | "ttl": { 15 | "description": 16 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 17 | "type": "integer", 18 | "minimum": 0 19 | }, 20 | "version": { 21 | "description": 22 | "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 23 | "type": "string", 24 | "const": "1.1" 25 | }, 26 | "data": { 27 | "description": "Describe regions for a system that is broken up by geographic or political region.", 28 | "type": "object", 29 | "properties": { 30 | "regions": { 31 | "description": "Array of regions.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "properties": { 36 | "region_id": { 37 | "description": "identifier of the region.", 38 | "type": "string" 39 | }, 40 | "name": { 41 | "description": "Public name for this region.", 42 | "type": "string" 43 | } 44 | }, 45 | "required": ["region_id", "name"] 46 | } 47 | } 48 | }, 49 | "required": ["regions"] 50 | } 51 | }, 52 | "required": ["last_updated", "ttl", "version", "data"] 53 | } 54 | -------------------------------------------------------------------------------- /v2.0/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": 4 | "https://github.com/MobilityData/gbfs/blob/v2.0/gbfs.md#gbfs_versionsjson-added-in-v11", 5 | "description": 6 | "Lists all feed endpoints published according to version sof the GBFS documentation. (added in v1.1)", 7 | "type": "object", 8 | "properties": { 9 | "last_updated": { 10 | "description": 11 | "Last time the data in the feed was updated in POSIX time.", 12 | "type": "integer", 13 | "minimum": 1450155600 14 | }, 15 | "ttl": { 16 | "description": 17 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 18 | "type": "integer", 19 | "minimum": 0 20 | }, 21 | "version": { 22 | "description": 23 | "GBFS version number to which the feed conforms, according to the versioning framework.", 24 | "type": "string", 25 | "const": "2.0" 26 | }, 27 | "data": { 28 | "description": "Response data in the form of name:value pairs.", 29 | "type": "object", 30 | "properties": { 31 | "versions": { 32 | "description": 33 | "Contains one object, as defined below, for each of the available versions of a feed. The array must be sorted by increasing MAJOR and MINOR version number.", 34 | "type": "array", 35 | "items": { 36 | "type": "object", 37 | "properties": { 38 | "version": { 39 | "description": 40 | "The semantic version of the feed in the form X.Y", 41 | "type": "string", 42 | "enum": [ 43 | "1.0", 44 | "1.1", 45 | "2.0", 46 | "2.1", 47 | "2.2", 48 | "2.3", 49 | "3.0" 50 | ] 51 | }, 52 | "url": { 53 | "description": "URL of the corresponding gbfs.json endpoint", 54 | "type": "string", 55 | "format": "uri" 56 | } 57 | }, 58 | "required": ["version", "url"] 59 | } 60 | } 61 | }, 62 | "required": ["versions"], 63 | "additionalProperties": false 64 | } 65 | }, 66 | "required": ["last_updated", "ttl", "version", "data"] 67 | } 68 | -------------------------------------------------------------------------------- /v2.0/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v2.0/gbfs.md#system_regionsjson", 4 | "description": 5 | "Describes regions for a system that is broken up by geographic or political region.", 6 | "type": "object", 7 | "properties": { 8 | "last_updated": { 9 | "description": 10 | "Last time the data in the feed was updated in POSIX time.", 11 | "type": "integer", 12 | "minimum": 1450155600 13 | }, 14 | "ttl": { 15 | "description": 16 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 17 | "type": "integer", 18 | "minimum": 0 19 | }, 20 | "version": { 21 | "description": 22 | "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 23 | "type": "string", 24 | "const": "2.0" 25 | }, 26 | "data": { 27 | "description": "Describe regions for a system that is broken up by geographic or political region.", 28 | "type": "object", 29 | "properties": { 30 | "regions": { 31 | "description": "Array of regions.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "properties": { 36 | "region_id": { 37 | "description": "identifier of the region.", 38 | "type": "string" 39 | }, 40 | "name": { 41 | "description": "Public name for this region.", 42 | "type": "string" 43 | } 44 | }, 45 | "required": ["region_id", "name"] 46 | } 47 | } 48 | }, 49 | "required": ["regions"] 50 | } 51 | }, 52 | "required": ["last_updated", "ttl", "version", "data"] 53 | } 54 | -------------------------------------------------------------------------------- /v2.1/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": 4 | "https://github.com/MobilityData/gbfs/blob/v2.1/gbfs.md#gbfs_versionsjson-added-in-v11", 5 | "description": 6 | "Lists all feed endpoints published according to version sof the GBFS documentation. (added in v1.1)", 7 | "type": "object", 8 | "properties": { 9 | "last_updated": { 10 | "description": 11 | "Last time the data in the feed was updated in POSIX time.", 12 | "type": "integer", 13 | "minimum": 1450155600 14 | }, 15 | "ttl": { 16 | "description": 17 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 18 | "type": "integer", 19 | "minimum": 0 20 | }, 21 | "version": { 22 | "description": 23 | "GBFS version number to which the feed conforms, according to the versioning framework.", 24 | "type": "string", 25 | "const": "2.1" 26 | }, 27 | "data": { 28 | "description": "Response data in the form of name:value pairs.", 29 | "type": "object", 30 | "properties": { 31 | "versions": { 32 | "description": 33 | "Contains one object, as defined below, for each of the available versions of a feed. The array must be sorted by increasing MAJOR and MINOR version number.", 34 | "type": "array", 35 | "items": { 36 | "type": "object", 37 | "properties": { 38 | "version": { 39 | "description": 40 | "The semantic version of the feed in the form X.Y", 41 | "type": "string", 42 | "enum": [ 43 | "1.0", 44 | "1.1", 45 | "2.0", 46 | "2.1", 47 | "2.2", 48 | "2.3", 49 | "3.0" 50 | ] 51 | }, 52 | "url": { 53 | "description": "URL of the corresponding gbfs.json endpoint", 54 | "type": "string", 55 | "format": "uri" 56 | } 57 | }, 58 | "required": ["version", "url"] 59 | } 60 | } 61 | }, 62 | "required": ["versions"], 63 | "additionalProperties": false 64 | } 65 | }, 66 | "required": ["last_updated", "ttl", "version", "data"] 67 | } 68 | -------------------------------------------------------------------------------- /v2.1/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v2.1/gbfs.md#system_regionsjson", 4 | "description": 5 | "Describes regions for a system that is broken up by geographic or political region.", 6 | "type": "object", 7 | "properties": { 8 | "last_updated": { 9 | "description": 10 | "Last time the data in the feed was updated in POSIX time.", 11 | "type": "integer", 12 | "minimum": 1450155600 13 | }, 14 | "ttl": { 15 | "description": 16 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 17 | "type": "integer", 18 | "minimum": 0 19 | }, 20 | "version": { 21 | "description": 22 | "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 23 | "type": "string", 24 | "const": "2.1" 25 | }, 26 | "data": { 27 | "description": "Describe regions for a system that is broken up by geographic or political region.", 28 | "type": "object", 29 | "properties": { 30 | "regions": { 31 | "description": "Array of regions.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "properties": { 36 | "region_id": { 37 | "description": "identifier of the region.", 38 | "type": "string" 39 | }, 40 | "name": { 41 | "description": "Public name for this region.", 42 | "type": "string" 43 | } 44 | }, 45 | "required": ["region_id", "name"] 46 | } 47 | } 48 | }, 49 | "required": ["regions"] 50 | } 51 | }, 52 | "required": ["last_updated", "ttl", "version", "data"] 53 | } 54 | -------------------------------------------------------------------------------- /v2.2/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": 4 | "https://github.com/MobilityData/gbfs/blob/v2.2/gbfs.md#gbfs_versionsjson-added-in-v11", 5 | "description": 6 | "Lists all feed endpoints published according to version sof the GBFS documentation. (added in v1.1)", 7 | "type": "object", 8 | "properties": { 9 | "last_updated": { 10 | "description": 11 | "Last time the data in the feed was updated in POSIX time.", 12 | "type": "integer", 13 | "minimum": 1450155600 14 | }, 15 | "ttl": { 16 | "description": 17 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 18 | "type": "integer", 19 | "minimum": 0 20 | }, 21 | "version": { 22 | "description": 23 | "GBFS version number to which the feed conforms, according to the versioning framework.", 24 | "type": "string", 25 | "const": "2.2" 26 | }, 27 | "data": { 28 | "description": "Response data in the form of name:value pairs.", 29 | "type": "object", 30 | "properties": { 31 | "versions": { 32 | "description": 33 | "Contains one object, as defined below, for each of the available versions of a feed. The array must be sorted by increasing MAJOR and MINOR version number.", 34 | "type": "array", 35 | "items": { 36 | "type": "object", 37 | "properties": { 38 | "version": { 39 | "description": 40 | "The semantic version of the feed in the form X.Y", 41 | "type": "string", 42 | "enum": [ 43 | "1.0", 44 | "1.1", 45 | "2.0", 46 | "2.1", 47 | "2.2", 48 | "2.3", 49 | "3.0" 50 | ] 51 | }, 52 | "url": { 53 | "description": "URL of the corresponding gbfs.json endpoint", 54 | "type": "string", 55 | "format": "uri" 56 | } 57 | }, 58 | "required": ["version", "url"] 59 | } 60 | } 61 | }, 62 | "required": ["versions"], 63 | "additionalProperties": false 64 | } 65 | }, 66 | "required": ["last_updated", "ttl", "version", "data"] 67 | } 68 | -------------------------------------------------------------------------------- /v2.2/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v2.2/gbfs.md#system_regionsjson", 4 | "description": 5 | "Describes regions for a system that is broken up by geographic or political region.", 6 | "type": "object", 7 | "properties": { 8 | "last_updated": { 9 | "description": 10 | "Last time the data in the feed was updated in POSIX time.", 11 | "type": "integer", 12 | "minimum": 1450155600 13 | }, 14 | "ttl": { 15 | "description": 16 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 17 | "type": "integer", 18 | "minimum": 0 19 | }, 20 | "version": { 21 | "description": 22 | "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 23 | "type": "string", 24 | "const": "2.2" 25 | }, 26 | "data": { 27 | "description": "Describe regions for a system that is broken up by geographic or political region.", 28 | "type": "object", 29 | "properties": { 30 | "regions": { 31 | "description": "Array of regions.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "properties": { 36 | "region_id": { 37 | "description": "identifier of the region.", 38 | "type": "string" 39 | }, 40 | "name": { 41 | "description": "Public name for this region.", 42 | "type": "string" 43 | } 44 | }, 45 | "required": ["region_id", "name"] 46 | } 47 | } 48 | }, 49 | "required": ["regions"] 50 | } 51 | }, 52 | "required": ["last_updated", "ttl", "version", "data"] 53 | } 54 | -------------------------------------------------------------------------------- /v2.3/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": 4 | "https://github.com/MobilityData/gbfs/blob/v2.3/gbfs.md#gbfs_versionsjson", 5 | "description": 6 | "Lists all feed endpoints published according to version sof the GBFS documentation. (added in v1.1)", 7 | "type": "object", 8 | "properties": { 9 | "last_updated": { 10 | "description": 11 | "Last time the data in the feed was updated in POSIX time.", 12 | "type": "integer", 13 | "minimum": 1450155600 14 | }, 15 | "ttl": { 16 | "description": 17 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 18 | "type": "integer", 19 | "minimum": 0 20 | }, 21 | "version": { 22 | "description": 23 | "GBFS version number to which the feed conforms, according to the versioning framework.", 24 | "type": "string", 25 | "const": "2.3" 26 | }, 27 | "data": { 28 | "description": "Response data in the form of name:value pairs.", 29 | "type": "object", 30 | "properties": { 31 | "versions": { 32 | "description": 33 | "Contains one object, as defined below, for each of the available versions of a feed. The array must be sorted by increasing MAJOR and MINOR version number.", 34 | "type": "array", 35 | "items": { 36 | "type": "object", 37 | "properties": { 38 | "version": { 39 | "description": 40 | "The semantic version of the feed in the form X.Y", 41 | "type": "string", 42 | "enum": [ 43 | "1.0", 44 | "1.1", 45 | "2.0", 46 | "2.1", 47 | "2.2", 48 | "2.3", 49 | "3.0" 50 | ] 51 | }, 52 | "url": { 53 | "description": "URL of the corresponding gbfs.json endpoint", 54 | "type": "string", 55 | "format": "uri" 56 | } 57 | }, 58 | "required": ["version", "url"] 59 | } 60 | } 61 | }, 62 | "required": ["versions"], 63 | "additionalProperties": false 64 | } 65 | }, 66 | "required": ["last_updated", "ttl", "version", "data"] 67 | } 68 | -------------------------------------------------------------------------------- /v2.3/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v2.3/gbfs.md#system_regionsjson", 4 | "description": 5 | "Describes regions for a system that is broken up by geographic or political region.", 6 | "type": "object", 7 | "properties": { 8 | "last_updated": { 9 | "description": 10 | "Last time the data in the feed was updated in POSIX time.", 11 | "type": "integer", 12 | "minimum": 1450155600 13 | }, 14 | "ttl": { 15 | "description": 16 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 17 | "type": "integer", 18 | "minimum": 0 19 | }, 20 | "version": { 21 | "description": 22 | "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 23 | "type": "string", 24 | "const": "2.3" 25 | }, 26 | "data": { 27 | "description": "Describe regions for a system that is broken up by geographic or political region.", 28 | "type": "object", 29 | "properties": { 30 | "regions": { 31 | "description": "Array of regions.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "properties": { 36 | "region_id": { 37 | "description": "identifier of the region.", 38 | "type": "string" 39 | }, 40 | "name": { 41 | "description": "Public name for this region.", 42 | "type": "string" 43 | } 44 | }, 45 | "required": ["region_id", "name"] 46 | } 47 | } 48 | }, 49 | "required": ["regions"] 50 | } 51 | }, 52 | "required": ["last_updated", "ttl", "version", "data"] 53 | } 54 | -------------------------------------------------------------------------------- /v3.0/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v3.0/gbfs.md#gbfsjson", 4 | "description": "Auto-discovery file that links to all of the other files published by the system.", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in RFC3339 format.", 9 | "type": "string", 10 | "format": "date-time" 11 | }, 12 | "ttl": { 13 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 14 | "type": "integer", 15 | "minimum": 0 16 | }, 17 | "version": { 18 | "description": "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 19 | "type": "string", 20 | "const": "3.0" 21 | }, 22 | "data": { 23 | "type": "object", 24 | "properties": { 25 | "feeds": { 26 | "description": "An array of all of the feeds that are published by the auto-discovery file. Each element in the array is an object with the keys below.", 27 | "type": "array", 28 | "items": { 29 | "type": "object", 30 | "properties": { 31 | "name": { 32 | "description": "Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type.", 33 | "type": "string", 34 | "enum": [ 35 | "gbfs", 36 | "gbfs_versions", 37 | "system_information", 38 | "vehicle_types", 39 | "station_information", 40 | "station_status", 41 | "vehicle_status", 42 | "system_alerts", 43 | "system_regions", 44 | "system_pricing_plans", 45 | "geofencing_zones" 46 | ] 47 | }, 48 | "url": { 49 | "description": "URL for the feed.", 50 | "type": "string", 51 | "format": "uri" 52 | } 53 | }, 54 | "required": ["name", "url"] 55 | }, 56 | "minItems": 1, 57 | "contains": { 58 | "properties": { 59 | "name": { "const": "system_information" } 60 | } 61 | } 62 | } 63 | }, 64 | "required": ["feeds"] 65 | } 66 | }, 67 | "additionalProperties": false, 68 | "required": ["last_updated", "ttl", "version", "data"] 69 | } 70 | -------------------------------------------------------------------------------- /v3.0/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v3.0/gbfs.md#gbfs_versionsjson", 4 | "description": "Lists all feed endpoints published according to version sof the GBFS documentation. (added in v1.1)", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in RFC3339 format.", 9 | "type": "string", 10 | "format": "date-time" 11 | }, 12 | "ttl": { 13 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 14 | "type": "integer", 15 | "minimum": 0 16 | }, 17 | "version": { 18 | "description": "GBFS version number to which the feed conforms, according to the versioning framework.", 19 | "type": "string", 20 | "const": "3.0" 21 | }, 22 | "data": { 23 | "description": "Response data in the form of name:value pairs.", 24 | "type": "object", 25 | "properties": { 26 | "versions": { 27 | "description": "Contains one object, as defined below, for each of the available versions of a feed. The array must be sorted by increasing MAJOR and MINOR version number.", 28 | "type": "array", 29 | "items": { 30 | "type": "object", 31 | "properties": { 32 | "version": { 33 | "description": "The semantic version of the feed in the form X.Y", 34 | "type": "string", 35 | "enum": [ 36 | "1.0", 37 | "1.1", 38 | "2.0", 39 | "2.1", 40 | "2.2", 41 | "2.3", 42 | "3.0" 43 | ] 44 | }, 45 | "url": { 46 | "description": "URL of the corresponding gbfs.json endpoint", 47 | "type": "string", 48 | "format": "uri" 49 | } 50 | }, 51 | "required": ["version", "url"] 52 | } 53 | } 54 | }, 55 | "required": ["versions"], 56 | "additionalProperties": false 57 | } 58 | }, 59 | "required": ["last_updated", "ttl", "version", "data"] 60 | } 61 | -------------------------------------------------------------------------------- /v3.0/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v3.0/gbfs.md#system_regionsjson", 4 | "description": 5 | "Describes regions for a system that is broken up by geographic or political region.", 6 | "type": "object", 7 | "properties": { 8 | "last_updated": { 9 | "description": 10 | "Last time the data in the feed was updated in RFC3339 format.", 11 | "type": "string", 12 | "format": "date-time" 13 | }, 14 | "ttl": { 15 | "description": 16 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 17 | "type": "integer", 18 | "minimum": 0 19 | }, 20 | "version": { 21 | "description": 22 | "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 23 | "type": "string", 24 | "const": "3.0" 25 | }, 26 | "data": { 27 | "description": "Describe regions for a system that is broken up by geographic or political region.", 28 | "type": "object", 29 | "properties": { 30 | "regions": { 31 | "description": "Array of regions.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "properties": { 36 | "region_id": { 37 | "description": "identifier of the region.", 38 | "type": "string" 39 | }, 40 | "name": { 41 | "description": "Public name for this region.", 42 | "type": "array", 43 | "items": { 44 | "type": "object", 45 | "properties": { 46 | "text": { 47 | "description": "The translated text.", 48 | "type": "string" 49 | }, 50 | "language": { 51 | "description": "IETF BCP 47 language code.", 52 | "type": "string", 53 | "pattern": "^[a-z]{2,3}(-[A-Z]{2})?$" 54 | } 55 | }, 56 | "required": ["text", "language"] 57 | } 58 | } 59 | }, 60 | "required": ["region_id", "name"] 61 | } 62 | } 63 | }, 64 | "required": ["regions"] 65 | } 66 | }, 67 | "required": ["last_updated", "ttl", "version", "data"] 68 | } 69 | -------------------------------------------------------------------------------- /v3.1-RC/gbfs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v3.1-RC/gbfs.md#gbfsjson", 4 | "description": "Auto-discovery file that links to all of the other files published by the system.", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in RFC3339 format.", 9 | "type": "string", 10 | "format": "date-time" 11 | }, 12 | "ttl": { 13 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 14 | "type": "integer", 15 | "minimum": 0 16 | }, 17 | "version": { 18 | "description": "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 19 | "type": "string", 20 | "const": "3.1-RC" 21 | }, 22 | "data": { 23 | "type": "object", 24 | "properties": { 25 | "feeds": { 26 | "description": "An array of all of the feeds that are published by the auto-discovery file. Each element in the array is an object with the keys below.", 27 | "type": "array", 28 | "items": { 29 | "type": "object", 30 | "properties": { 31 | "name": { 32 | "description": "Key identifying the type of feed this is. The key must be the base file name defined in the spec for the corresponding feed type.", 33 | "type": "string", 34 | "enum": [ 35 | "gbfs", 36 | "gbfs_versions", 37 | "system_information", 38 | "vehicle_types", 39 | "station_information", 40 | "station_status", 41 | "vehicle_status", 42 | "system_alerts", 43 | "system_regions", 44 | "system_pricing_plans", 45 | "geofencing_zones" 46 | ] 47 | }, 48 | "url": { 49 | "description": "URL for the feed.", 50 | "type": "string", 51 | "format": "uri" 52 | } 53 | }, 54 | "required": ["name", "url"] 55 | }, 56 | "minItems": 1, 57 | "contains": { 58 | "properties": { 59 | "name": { "const": "system_information" } 60 | } 61 | } 62 | } 63 | }, 64 | "required": ["feeds"] 65 | } 66 | }, 67 | "additionalProperties": false, 68 | "required": ["last_updated", "ttl", "version", "data"] 69 | } 70 | -------------------------------------------------------------------------------- /v3.1-RC/gbfs_versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v3.1-RC/gbfs.md#gbfs_versionsjson", 4 | "description": "Lists all feed endpoints published according to version sof the GBFS documentation. (added in v1.1)", 5 | "type": "object", 6 | "properties": { 7 | "last_updated": { 8 | "description": "Last time the data in the feed was updated in RFC3339 format.", 9 | "type": "string", 10 | "format": "date-time" 11 | }, 12 | "ttl": { 13 | "description": "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 14 | "type": "integer", 15 | "minimum": 0 16 | }, 17 | "version": { 18 | "description": "GBFS version number to which the feed conforms, according to the versioning framework.", 19 | "type": "string", 20 | "const": "3.1-RC" 21 | }, 22 | "data": { 23 | "description": "Response data in the form of name:value pairs.", 24 | "type": "object", 25 | "properties": { 26 | "versions": { 27 | "description": "Contains one object, as defined below, for each of the available versions of a feed. The array must be sorted by increasing MAJOR and MINOR version number.", 28 | "type": "array", 29 | "items": { 30 | "type": "object", 31 | "properties": { 32 | "version": { 33 | "description": "The semantic version of the feed in the form X.Y", 34 | "type": "string", 35 | "enum": [ 36 | "1.0", 37 | "1.1", 38 | "2.0", 39 | "2.1", 40 | "2.2", 41 | "2.3", 42 | "3.0", 43 | "3.1-RC" 44 | ] 45 | }, 46 | "url": { 47 | "description": "URL of the corresponding gbfs.json endpoint", 48 | "type": "string", 49 | "format": "uri" 50 | } 51 | }, 52 | "required": ["version", "url"] 53 | } 54 | } 55 | }, 56 | "required": ["versions"], 57 | "additionalProperties": false 58 | } 59 | }, 60 | "required": ["last_updated", "ttl", "version", "data"] 61 | } 62 | -------------------------------------------------------------------------------- /v3.1-RC/system_regions.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "$id": "https://github.com/MobilityData/gbfs/blob/v3.1-RC/gbfs.md#system_regionsjson", 4 | "description": 5 | "Describes regions for a system that is broken up by geographic or political region.", 6 | "type": "object", 7 | "properties": { 8 | "last_updated": { 9 | "description": 10 | "Last time the data in the feed was updated in RFC3339 format.", 11 | "type": "string", 12 | "format": "date-time" 13 | }, 14 | "ttl": { 15 | "description": 16 | "Number of seconds before the data in the feed will be updated again (0 if the data should always be refreshed).", 17 | "type": "integer", 18 | "minimum": 0 19 | }, 20 | "version": { 21 | "description": 22 | "GBFS version number to which the feed conforms, according to the versioning framework (added in v1.1).", 23 | "type": "string", 24 | "const": "3.1-RC" 25 | }, 26 | "data": { 27 | "description": "Describe regions for a system that is broken up by geographic or political region.", 28 | "type": "object", 29 | "properties": { 30 | "regions": { 31 | "description": "Array of regions.", 32 | "type": "array", 33 | "items": { 34 | "type": "object", 35 | "properties": { 36 | "region_id": { 37 | "description": "identifier of the region.", 38 | "type": "string" 39 | }, 40 | "name": { 41 | "description": "Public name for this region.", 42 | "type": "array", 43 | "items": { 44 | "type": "object", 45 | "properties": { 46 | "text": { 47 | "description": "The translated text.", 48 | "type": "string" 49 | }, 50 | "language": { 51 | "description": "IETF BCP 47 language code.", 52 | "type": "string", 53 | "pattern": "^[a-z]{2,3}(-[A-Z]{2})?$" 54 | } 55 | }, 56 | "required": ["text", "language"] 57 | } 58 | } 59 | }, 60 | "required": ["region_id", "name"] 61 | } 62 | } 63 | }, 64 | "required": ["regions"] 65 | } 66 | }, 67 | "required": ["last_updated", "ttl", "version", "data"] 68 | } 69 | --------------------------------------------------------------------------------