Skip to content

Commit 110f48d

Browse files
Akuukispauloamorimbr
authored andcommitted
refactor(frontend): generate API react-query helpers with Orval DEV-893 (#6083)
### 💭 Notes Generate react-query helpers from API with Orval. By it's own does nothing. See these few refactors, the rest is for now unused generated files: - `jsapp/js/api.ts` - `package.json` - `package-lock.json` Configuration is split across these files: - `orval.config.js` - `jsapp/js/api/orval.mutator.ts` - `jsapp/js/api/orval.operationName.ts` - `scripts/generate_api.sh` - `.github/workflows/openapi.yml` See other refactor PRs that use these helpers to call API: - #6090 ### 👀 Preview steps 1. run kobo-install locally 2. `./run.py -cf run --rm kpi ./scripts/generate_api.sh` to re-generate helpers 3. notice that helpers are regenerated 4. click around so that some APIs are called the old way 5. notice that it still works and the refactors didn't break anything
1 parent d22ee99 commit 110f48d

File tree

461 files changed

+27034
-50
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

461 files changed

+27034
-50
lines changed

.github/workflows/openapi.yml

Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ name: openapi
44

55
on: workflow_call
66
jobs:
7-
build:
7+
8+
9+
drf-spectacular:
810
runs-on: ubuntu-24.04
911
env:
1012
DATABASE_URL: postgis://kobo:kobo@localhost:5432/kpi_test
@@ -40,33 +42,85 @@ jobs:
4042
- 6379:6379
4143
steps:
4244

43-
- uses: actions/checkout@v4
45+
- uses: actions/checkout@v4
46+
47+
- name: Set up Python ${{ matrix.python-version }}
48+
uses: actions/setup-python@v5
49+
with:
50+
python-version: ${{ matrix.python-version }}
51+
52+
- name: Install pip-tools
53+
run: python -m pip install pip-tools==7.\*
54+
55+
- name: Update Debian package lists
56+
run: sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
57+
58+
- name: Install Debian dependencies
59+
# All about YAML line breaks: https://stackoverflow.com/a/21699210
60+
run: >-
61+
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install
62+
gdal-bin gettext libproj-dev postgresql-client ffmpeg
63+
gcc libc-dev build-essential
64+
65+
- name: Install Python dev dependencies
66+
run: pip-sync dependencies/pip/dev_requirements.txt
4467

45-
- name: Set up Python ${{ matrix.python-version }}
46-
uses: actions/setup-python@v5
47-
with:
48-
python-version: ${{ matrix.python-version }}
68+
- name: Generate OpenAPI with drf-spectacular
69+
run: ./scripts/generate_api.sh --skip-orval
4970

50-
- name: Install pip-tools
51-
run: python -m pip install pip-tools==7.\*
71+
- name: Fail on uncommitted OpenAPI changes
72+
run: |
73+
git diff
74+
git diff-index --exit-code HEAD
5275
53-
- name: Update Debian package lists
54-
run: sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
5576
56-
- name: Install Debian dependencies
57-
# All about YAML line breaks: https://stackoverflow.com/a/21699210
58-
run: >-
59-
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install
60-
gdal-bin gettext libproj-dev postgresql-client ffmpeg
61-
gcc libc-dev build-essential
77+
orval:
78+
runs-on: ubuntu-24.04
79+
80+
steps:
81+
- uses: actions/checkout@v4
82+
- uses: actions/setup-node@v4
83+
with:
84+
node-version: 20.18.1 # version that's pinned in Dockerfile for kpi release. FYI v22 doesn't work out of box.
85+
check-latest: true # download newer semver match if available
86+
cache: 'npm'
87+
88+
- name: Identify resolved node version
89+
id: resolved-node-version
90+
run: echo "NODE_VERSION=$(node --version)" >> "$GITHUB_OUTPUT"
91+
- name: Add "Node ${{ steps.resolved-node-version.outputs.NODE_VERSION }}" to summary
92+
run: echo "22 → **${{ steps.resolved-node-version.outputs.NODE_VERSION }}**" >> "$GITHUB_STEP_SUMMARY"
93+
94+
# Cache: Use cache for node_modules
95+
# Keyed on os, node version, package-lock, and patches
96+
- uses: actions/cache@v4
97+
name: Check for cached node_modules
98+
id: cache-nodemodules
99+
env:
100+
cache-name: cache-node-modules
101+
with:
102+
path: node_modules
103+
key: ${{ runner.os }}-build-${{ env.cache-name }}-node-${{ steps.resolved-node-version.outputs.NODE_VERSION }}-${{ hashFiles('**/package-lock.json', 'patches/**/*.patch') }}
104+
105+
# Cache hit: If the cache key matches,
106+
# /node_modules/ will have been copied from a previous run.
107+
# (Run the post-install step, `npm run copy-fonts`)
108+
- name: Run copy-fonts (if using cached node_modules)
109+
if: steps.cache-nodemodules.outputs.cache-hit == 'true'
110+
run: npm run copy-fonts
62111

63-
- name: Install Python dependencies
64-
run: pip-sync dependencies/pip/dev_requirements.txt
112+
# Cache miss: If node_modules has not been cached,
113+
# `npm install`
114+
# (This includes `npm run copy-fonts` as post-install step)
115+
- name: Install JavaScript dependencies (npm install)
116+
if: steps.cache-nodemodules.outputs.cache-hit != 'true'
117+
run: npm install
65118

66-
- name: Generate OpenAPI
67-
run: ./scripts/generate_openapi_schemas.sh
119+
# Check for TypeScript errors
120+
- name: Generate react-query helpers with Orval
121+
run: npm run build:orval
68122

69-
- name: Fail on uncommitted OpenAPI changes
70-
run: |
71-
git diff
72-
git diff-index --exit-code HEAD
123+
- name: Fail on uncommitted react-query helper changes
124+
run: |
125+
git diff
126+
git diff-index --exit-code HEAD

jsapp/js/api.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ export interface FetchDataOptions {
118118
includeHeaders?: boolean
119119
}
120120

121-
const fetchData = async <T>(
121+
export const fetchDataRaw = async <T>(
122122
/**
123123
* If you have full url to be called, remember to use `prependRootUrl` option.
124124
*/
125125
path: string,
126126
method: FetchHttpMethod,
127-
data?: Json,
127+
data?: string,
128128
options?: FetchDataOptions,
129129
) => {
130130
// Prepare options
@@ -158,7 +158,7 @@ const fetchData = async <T>(
158158
}
159159

160160
if (data) {
161-
fetchOptions['body'] = JSON.stringify(data)
161+
fetchOptions['body'] = data
162162
}
163163

164164
const response = await fetch(url, fetchOptions)
@@ -210,9 +210,22 @@ const fetchData = async <T>(
210210
} as { headers: Headers } & T
211211
}
212212

213-
return responseJson as T
213+
return { data: responseJson, status: response.status, headers: response.headers } as T
214214
}
215215

216+
const fetchData = async <T>(
217+
/**
218+
* If you have full url to be called, remember to use `prependRootUrl` option.
219+
*/
220+
path: string,
221+
method: FetchHttpMethod,
222+
data?: Json,
223+
options?: FetchDataOptions,
224+
) => {
225+
const body = data ? JSON.stringify(data) : undefined
226+
const response = await fetchDataRaw<{ data: T; status: number; headers: unknown }>(path, method, body, options)
227+
return response.data
228+
}
216229
/** GET Kobo API at path */
217230
export const fetchGet = async <T>(path: string, options?: FetchDataOptions) =>
218231
fetchData<T>(path, 'GET', undefined, options)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Generated by orval v7.10.0 🍺
3+
* Do not edit manually.
4+
* KoboToolbox API
5+
* Powerful and intuitive data collection tools to make an impact
6+
* OpenAPI spec version: 2.0.0 (api_v2)
7+
*/
8+
9+
export type _DataResponseAttachments = {
10+
download_url?: string
11+
download_large_url?: string
12+
download_medium_url?: string
13+
download_small_url?: string
14+
mimetype?: string
15+
filename?: string
16+
uid?: string
17+
question_xpath?: string
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Generated by orval v7.10.0 🍺
3+
* Do not edit manually.
4+
* KoboToolbox API
5+
* Powerful and intuitive data collection tools to make an impact
6+
* OpenAPI spec version: 2.0.0 (api_v2)
7+
*/
8+
9+
export type _ExportCreatePayloadQueryAndItemSubmissionTime = {
10+
$gte?: string
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Generated by orval v7.10.0 🍺
3+
* Do not edit manually.
4+
* KoboToolbox API
5+
* Powerful and intuitive data collection tools to make an impact
6+
* OpenAPI spec version: 2.0.0 (api_v2)
7+
*/
8+
9+
export type _ExportSettingCreatePayloadExportSettingsQueryAndItemSubmissionTime = {
10+
$gte?: string
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Generated by orval v7.10.0 🍺
3+
* Do not edit manually.
4+
* KoboToolbox API
5+
* Powerful and intuitive data collection tools to make an impact
6+
* OpenAPI spec version: 2.0.0 (api_v2)
7+
*/
8+
9+
export type _PermissionAssignmentCreateRequestOneOfTwoPartialPermissionItemFilterItemSubmittedBy = {
10+
$in?: string[]
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Generated by orval v7.10.0 🍺
3+
* Do not edit manually.
4+
* KoboToolbox API
5+
* Powerful and intuitive data collection tools to make an impact
6+
* OpenAPI spec version: 2.0.0 (api_v2)
7+
*/
8+
9+
export type AccessLogsListParams = {
10+
/**
11+
* Number of results to return per page.
12+
*/
13+
limit?: number
14+
/**
15+
* The initial index from which to return the results.
16+
*/
17+
offset?: number
18+
q?: string
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Generated by orval v7.10.0 🍺
3+
* Do not edit manually.
4+
* KoboToolbox API
5+
* Powerful and intuitive data collection tools to make an impact
6+
* OpenAPI spec version: 2.0.0 (api_v2)
7+
*/
8+
9+
export type AccessLogsMeListParams = {
10+
/**
11+
* Number of results to return per page.
12+
*/
13+
limit?: number
14+
/**
15+
* The initial index from which to return the results.
16+
*/
17+
offset?: number
18+
q?: string
19+
}

jsapp/js/api/models/asset.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import type { AssetAdvancedFeatures } from './assetAdvancedFeatures'
2+
import type { AssetAdvancedSubmissionSchema } from './assetAdvancedSubmissionSchema'
3+
import type { AssetAnalysisFormJson } from './assetAnalysisFormJson'
4+
import type { AssetAssignablePermissionsItem } from './assetAssignablePermissionsItem'
5+
import type { AssetChildren } from './assetChildren'
6+
import type { AssetContent } from './assetContent'
7+
import type { AssetDataSharing } from './assetDataSharing'
8+
import type { AssetDeployedVersions } from './assetDeployedVersions'
9+
import type { AssetDeploymentDataDownloadLinks } from './assetDeploymentDataDownloadLinks'
10+
import type { AssetDeploymentLinks } from './assetDeploymentLinks'
11+
import type { AssetDownloadsItem } from './assetDownloadsItem'
12+
import type { AssetEffectivePermissionsItem } from './assetEffectivePermissionsItem'
13+
import type { AssetEmbedsItem } from './assetEmbedsItem'
14+
import type { AssetExportSettings } from './assetExportSettings'
15+
import type { AssetMapCustom } from './assetMapCustom'
16+
import type { AssetMapStyles } from './assetMapStyles'
17+
import type { AssetProjectOwnership } from './assetProjectOwnership'
18+
import type { AssetReportCustom } from './assetReportCustom'
19+
import type { AssetReportStyles } from './assetReportStyles'
20+
/**
21+
* Generated by orval v7.10.0 🍺
22+
* Do not edit manually.
23+
* KoboToolbox API
24+
* Powerful and intuitive data collection tools to make an impact
25+
* OpenAPI spec version: 2.0.0 (api_v2)
26+
*/
27+
import type { AssetSettings } from './assetSettings'
28+
import type { AssetSummary } from './assetSummary'
29+
import type { AssetTypeEnum } from './assetTypeEnum'
30+
31+
export interface Asset {
32+
readonly url: string
33+
readonly owner: string
34+
/** Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only. */
35+
readonly owner__username: string
36+
/** @nullable */
37+
parent?: string | null
38+
settings?: AssetSettings
39+
asset_type: AssetTypeEnum
40+
readonly files: readonly string[]
41+
readonly summary: AssetSummary
42+
date_created?: string
43+
date_modified?: string
44+
/** @nullable */
45+
date_deployed?: string | null
46+
readonly version_id: string
47+
readonly version__content_hash: string
48+
readonly version_count: number
49+
readonly has_deployment: boolean
50+
readonly deployed_version_id: string
51+
readonly deployed_versions: AssetDeployedVersions
52+
readonly deployment__links: AssetDeploymentLinks
53+
readonly deployment__active: boolean
54+
readonly deployment__data_download_links: AssetDeploymentDataDownloadLinks
55+
readonly deployment__submission_count: number
56+
readonly deployment__last_submission_time: string
57+
readonly deployment__encrypted: boolean
58+
readonly deployment__uuid: string
59+
readonly deployment_status: string
60+
report_styles?: AssetReportStyles
61+
report_custom?: AssetReportCustom
62+
advanced_features?: AssetAdvancedFeatures
63+
readonly advanced_submission_schema: AssetAdvancedSubmissionSchema
64+
readonly analysis_form_json: AssetAnalysisFormJson
65+
map_styles?: AssetMapStyles
66+
map_custom?: AssetMapCustom
67+
content?: AssetContent
68+
readonly downloads: readonly AssetDownloadsItem[]
69+
readonly embeds: readonly AssetEmbedsItem[]
70+
readonly xform_link: string
71+
readonly hooks_link: string
72+
tag_string?: string
73+
readonly uid: string
74+
readonly kind: string
75+
readonly xls_link: string
76+
/** @maxLength 255 */
77+
name?: string
78+
readonly assignable_permissions: readonly AssetAssignablePermissionsItem[]
79+
readonly permissions: readonly string[]
80+
readonly effective_permissions: readonly AssetEffectivePermissionsItem[]
81+
readonly exports: string
82+
readonly export_settings: readonly AssetExportSettings[]
83+
readonly data: string
84+
readonly children: AssetChildren
85+
readonly subscribers_count: number
86+
readonly status: string
87+
readonly access_types: readonly string[]
88+
data_sharing?: AssetDataSharing
89+
readonly paired_data: string
90+
/** @nullable */
91+
readonly project_ownership: AssetProjectOwnership
92+
readonly owner_label: string
93+
/** @nullable */
94+
readonly last_modified_by: string | null
95+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* Generated by orval v7.10.0 🍺
3+
* Do not edit manually.
4+
* KoboToolbox API
5+
* Powerful and intuitive data collection tools to make an impact
6+
* OpenAPI spec version: 2.0.0 (api_v2)
7+
*/
8+
9+
export type AssetAdvancedFeatures = { [key: string]: unknown }

0 commit comments

Comments
 (0)