@team-supercharge/oasg 17.1.0 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +260 -47
- package/bin/oasg +23 -4
- package/bin/save-lock.js +101 -0
- package/bin/target-version.js +84 -0
- package/config.schema.yml +15 -0
- package/package.json +1 -1
- package/targets/android/generate.sh +2 -2
- package/targets/android/generator-config.json +2 -1
- package/targets/android/publish.sh +1 -1
- package/targets/android/templates/build.gradle.mustache +63 -46
- package/targets/angular/generate.sh +35 -9
- package/targets/angular/publish.sh +1 -1
- package/targets/apple-swift/generate.sh +1 -1
- package/targets/apple-swift/publish.sh +1 -1
- package/targets/common.sh +3 -1
- package/targets/contract-testing/generate.sh +1 -1
- package/targets/contract-testing/publish.sh +1 -1
- package/targets/dependency-lock-utils.sh +290 -0
- package/targets/feign/generate.sh +1 -1
- package/targets/feign/publish.sh +1 -1
- package/targets/feign-kotlin/generate.sh +1 -1
- package/targets/feign-kotlin/publish.sh +1 -1
- package/targets/flutter/generate.sh +1 -1
- package/targets/flutter/publish.sh +1 -1
- package/targets/ios/generate.sh +1 -1
- package/targets/ios/publish.sh +1 -1
- package/targets/kmp/generate.sh +1 -1
- package/targets/kmp/publish.sh +1 -1
- package/targets/kmp/templates/build.gradle.kts.mustache +17 -13
- package/targets/kmp/templates/libraries/multiplatform/api.mustache +2 -0
- package/targets/msw/generate.sh +25 -0
- package/targets/msw/generator-config.json +28 -0
- package/targets/msw/templates/apis.index.mustache +9 -0
- package/targets/msw/templates/apis.mustache +178 -0
- package/targets/msw/templates/config.mustache +23 -0
- package/targets/msw/templates/index.mustache +11 -0
- package/targets/msw/templates/modelEnum.mustache +1 -0
- package/targets/msw/templates/modelGeneric.mustache +7 -0
- package/targets/msw/templates/package.mustache +35 -0
- package/targets/msw/templates/prettierrc.mustache +6 -0
- package/targets/msw/templates/tsconfig.mustache +18 -0
- package/targets/msw/templates/utils.mustache +15 -0
- package/targets/nestjs/generate.sh +36 -4
- package/targets/nestjs/publish.sh +1 -1
- package/targets/nestjs/templates/api.service.mustache +8 -14
- package/targets/plain-java/generate.sh +1 -1
- package/targets/plain-java/publish.sh +1 -1
- package/targets/python/generate.sh +1 -1
- package/targets/python/publish.sh +1 -1
- package/targets/python-fastapi/generate.sh +1 -1
- package/targets/python-fastapi/publish.sh +1 -1
- package/targets/python-fastapi-raw-request/generate.sh +1 -1
- package/targets/python-fastapi-raw-request/publish.sh +1 -1
- package/targets/python-legacy/generate.sh +1 -1
- package/targets/python-legacy/publish.sh +1 -1
- package/targets/react/generate.sh +17 -5
- package/targets/react/publish.sh +1 -1
- package/targets/react/templates/hook.mustache +172 -51
- package/targets/react/templates/package.mustache +1 -1
- package/targets/react/templates/use-api.hook.mustache +2 -0
- package/targets/spring/generate.sh +1 -1
- package/targets/spring/publish.sh +1 -1
- package/targets/spring-kotlin/generate.sh +1 -1
- package/targets/spring-kotlin/publish.sh +1 -1
- package/targets/stubby/generate.sh +1 -1
- package/targets/stubby/publish.sh +1 -1
- package/targets/typescript-axios/generate.sh +16 -5
- package/targets/typescript-axios/publish.sh +1 -1
- package/targets/typescript-fetch/generate.sh +17 -5
- package/targets/typescript-fetch/publish.sh +1 -1
- package/targets/android/templates/libraries/jvm-retrofit2/api.mustache +0 -157
- package/targets/android/templates/libraries/jvm-retrofit2/infrastructure/ApiClient.kt.mustache +0 -354
package/README.md
CHANGED
|
@@ -128,38 +128,39 @@ include:
|
|
|
128
128
|
|
|
129
129
|
The table below gives an overview of the changes (breaking, non-breaking, bug fixes) introduced in various major versions. For the resolution of breaking changes please consult the [Migration Guide](#migration-guide).
|
|
130
130
|
|
|
131
|
-
| Component | | | | | | | | | | | | | | | | | |
|
|
132
|
-
|
|
133
|
-
| **Internal** | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
134
|
-
| _Core_ |💥 |✨ |🐛 |💥 |✨ |🐛 |✨ |➖ |✨ |🐛 |🐛 |➖ |💥 |💥 |✨ |💥 |🆕 |
|
|
135
|
-
| _Linter_ |➖ |🐛 |➖ |➖ |➖ |➖ |💥 |➖ |➖ |➖ |➖ |🐛 |➖ |✨ |💥 |🆕 |
|
|
136
|
-
| **Client Targets** | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
137
|
-
| `android` |➖ |➖ |➖ |🐛 |💥 |➖ |➖ |💥 |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
138
|
-
| `angular` |➖ |✨ |➖ |🐛 |💥 |➖ |➖ |➖ |🐛 |➖ |➖ |➖ |💥 |➖ |➖ |➖ |🆕 |
|
|
139
|
-
| `dotnet` |➖ |➖ |➖ |🆕 |
|
|
140
|
-
| `feign` |🐛 |✨ |➖ |➖ |➖ |➖ |➖ |✨ |💥 |💥 |➖ |➖ |🐛 |🐛 |🆕 |
|
|
141
|
-
| `feign-kotlin` |🐛 |✨ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
142
|
-
| `plain-java` |🐛 |🆕 |
|
|
143
|
-
| `flutter` |➖ |➖ |➖ |➖ |🆕 |
|
|
144
|
-
| `ios` |➖ |➖ |➖ |➖ |💥 |🐛 |➖ |➖ |➖ |✨ |➖ |💥 |➖ |➖ |✨ |🆕 |
|
|
145
|
-
| `apple-swift` |➖ |🆕 |
|
|
146
|
-
| `kmp` |✨ |➖ |➖ |🆕 |
|
|
147
|
-
| `python` |➖ |🆕 |
|
|
148
|
-
| `python-legacy` |➖ |💥 |➖ |🐛 |💥 |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
149
|
-
| `react` |➖ |🐛 |🐛 |➖ |💥 |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
150
|
-
| `typescript-axios` |➖ |🆕 |
|
|
151
|
-
| `typescript-fetch` |➖ |🆕 |
|
|
152
|
-
| **Server Targets** | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
153
|
-
| `nestjs` |🐛 |💥 |💥 |➖ |💥 |✨ |➖ |➖ |🐛 |➖ |➖ |✨ |🆕 |
|
|
154
|
-
| `python-fastapi` |➖ |➖ |➖ |🆕 |
|
|
155
|
-
| `python-fastapi-raw-request` |➖ |➖ |➖ |🆕 |
|
|
156
|
-
| `spring` |🐛 |✨ |➖ |➖ |➖ |➖ |➖ |✨ |💥 |💥 |➖ |➖ |➖ |✨ |➖ |🆕 |
|
|
157
|
-
| `spring-kotlin` |✨ |✨ |➖ |➖ |➖ |➖ |➖ |✨ |💥 |💥 |➖ |➖ |🐛 |✨ |➖ |🆕 |
|
|
158
|
-
| **Misc Targets** | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
159
|
-
| `contract-testing` |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
160
|
-
| `openapi` |➖ |➖ |➖ |➖ |➖ |💥 |➖ |➖ |✨ |➖ |🆕 |
|
|
161
|
-
| `stubby` |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |💥 |➖ |➖ |➖ |➖ |🆕 |
|
|
162
|
-
| `postman` |➖ |➖ |🆕 |
|
|
131
|
+
| Component | | | | | | | | | | | | | | | | | | |
|
|
132
|
+
|------------------------------|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|
|
133
|
+
| **Internal** | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
134
|
+
| _Core_ |✨ |💥 |✨ |🐛 |💥 |✨ |🐛 |✨ |➖ |✨ |🐛 |🐛 |➖ |💥 |💥 |✨ |💥 |🆕 |
|
|
135
|
+
| _Linter_ |➖ |➖ |🐛 |➖ |➖ |➖ |➖ |💥 |➖ |➖ |➖ |➖ |🐛 |➖ |✨ |💥 |🆕 |
|
|
136
|
+
| **Client Targets** | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
137
|
+
| `android` |✨ |➖ |➖ |➖ |🐛 |💥 |➖ |➖ |💥 |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
138
|
+
| `angular` |➖ |➖ |✨ |➖ |🐛 |💥 |➖ |➖ |➖ |🐛 |➖ |➖ |➖ |💥 |➖ |➖ |➖ |🆕 |
|
|
139
|
+
| `dotnet` |➖ |➖ |➖ |➖ |🆕 |
|
|
140
|
+
| `feign` |➖ |🐛 |✨ |➖ |➖ |➖ |➖ |➖ |✨ |💥 |💥 |➖ |➖ |🐛 |🐛 |🆕 |
|
|
141
|
+
| `feign-kotlin` |➖ |🐛 |✨ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
142
|
+
| `plain-java` |➖ |🐛 |🆕 |
|
|
143
|
+
| `flutter` |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
144
|
+
| `ios` |➖ |➖ |➖ |➖ |➖ |💥 |🐛 |➖ |➖ |➖ |✨ |➖ |💥 |➖ |➖ |✨ |🆕 |
|
|
145
|
+
| `apple-swift` |➖ |➖ |🆕 |
|
|
146
|
+
| `kmp` |✨ |✨ |➖ |➖ |🆕 |
|
|
147
|
+
| `python` |➖ |➖ |🆕 |
|
|
148
|
+
| `python-legacy` |➖ |➖ |💥 |➖ |🐛 |💥 |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
149
|
+
| `react` |💥 |➖ |🐛 |🐛 |➖ |💥 |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
150
|
+
| `typescript-axios` |✨ |➖ |🆕 |
|
|
151
|
+
| `typescript-fetch` |✨ |➖ |🆕 |
|
|
152
|
+
| **Server Targets** | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
153
|
+
| `nestjs` |✨ |🐛 |💥 |💥 |➖ |💥 |✨ |➖ |➖ |🐛 |➖ |➖ |✨ |🆕 |
|
|
154
|
+
| `python-fastapi` |➖ |➖ |➖ |➖ |🆕 |
|
|
155
|
+
| `python-fastapi-raw-request` |➖ |➖ |➖ |➖ |🆕 |
|
|
156
|
+
| `spring` |➖ |🐛 |✨ |➖ |➖ |➖ |➖ |➖ |✨ |💥 |💥 |➖ |➖ |➖ |✨ |➖ |🆕 |
|
|
157
|
+
| `spring-kotlin` |➖ |✨ |✨ |➖ |➖ |➖ |➖ |➖ |✨ |💥 |💥 |➖ |➖ |🐛 |✨ |➖ |🆕 |
|
|
158
|
+
| **Misc Targets** | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|
|
159
|
+
| `contract-testing` |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |🆕 |
|
|
160
|
+
| `openapi` |➖ |➖ |➖ |➖ |➖ |➖ |💥 |➖ |➖ |✨ |➖ |🆕 |
|
|
161
|
+
| `stubby` |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |➖ |💥 |➖ |➖ |➖ |➖ |🆕 |
|
|
162
|
+
| `postman` |➖ |➖ |➖ |🆕 |
|
|
163
|
+
| `msw` |🆕 |
|
|
163
164
|
|
|
164
165
|
**Legend:**
|
|
165
166
|
|
|
@@ -218,6 +219,15 @@ Publishes the generated API client package of the specified target. If no target
|
|
|
218
219
|
$ npx oasg publish [target]
|
|
219
220
|
```
|
|
220
221
|
|
|
222
|
+
## `save-lock`
|
|
223
|
+
|
|
224
|
+
Saves the current state of the package-lock.json file to the `.oasg` directory. This is useful for later restoring the lock file in case of a failed install or build.
|
|
225
|
+
This command is offered for `npm` based projects only to ensure that a working `package-lock.json` file is always available for the project.
|
|
226
|
+
|
|
227
|
+
```shell
|
|
228
|
+
$ npx oasg save-lock [target]
|
|
229
|
+
```
|
|
230
|
+
|
|
221
231
|
---
|
|
222
232
|
|
|
223
233
|
# Linter Rules
|
|
@@ -522,20 +532,6 @@ Common target parameters
|
|
|
522
532
|
| packageName | Name of the generated NPM package | Y | - |
|
|
523
533
|
| repository | URL of the NPM package registry | Y | - |
|
|
524
534
|
|
|
525
|
-
##### Known issue: breaking dependencies
|
|
526
|
-
|
|
527
|
-
The Angular target has a known issue related to dependency versioning. The generated Angular project's `package.json` currently defines multiple dependencies with flexible versions (e.g., using `^` or `~` in version constraints). This flexibility allows newer versions of dependencies (not to mention the transitive dependencies), to be pulled in, which can occasionally lead to breaking changes.
|
|
528
|
-
|
|
529
|
-
A notable instance of this issue occurred with **Angular version 12**, which introduced changes that broke the build of generated projects. To address this specific case, we implemented a **temporary fix** in the `targets/angular/generate.sh` script. This script now manually installs problematic dependencies with fixed, validated versions.
|
|
530
|
-
|
|
531
|
-
###### Long-Term Solution
|
|
532
|
-
|
|
533
|
-
We are actively discussing a long-term solution to this issue. Potential approaches include implementing dependency version locking mechanisms (`package-lock.json`) per Angular versions.
|
|
534
|
-
|
|
535
|
-
The temporary fix may not cover all future breaking changes from other dependencies. Projects using different versions of Angular may encounter issues if the fix does not align with their specific requirements.
|
|
536
|
-
|
|
537
|
-
We welcome feedback and contributions to help address this issue.
|
|
538
|
-
|
|
539
535
|
#### `react`
|
|
540
536
|
|
|
541
537
|
```json
|
|
@@ -553,7 +549,132 @@ We welcome feedback and contributions to help address this issue.
|
|
|
553
549
|
| packageName | Name of the generated NPM package | Y | - |
|
|
554
550
|
| repository | URL of the NPM package registry | Y | - |
|
|
555
551
|
|
|
556
|
-
>
|
|
552
|
+
**Usage**<br>
|
|
553
|
+
|
|
554
|
+
1. Provide API config and instances
|
|
555
|
+
|
|
556
|
+
Let's create a component to setup API configuration and the APIs you need. Wrap your application with this components afterwards.
|
|
557
|
+
|
|
558
|
+
```tsx
|
|
559
|
+
import { type Type, type APIS, type ConfigurationParameters, ApiConfigProvider, ApiInstancesProvider, UsersApi } from '@project/oasg-example-react';
|
|
560
|
+
|
|
561
|
+
// Provide here all the APIs you need (might change during the project)
|
|
562
|
+
const providedApis: Type<APIS>[] = [UsersApi];
|
|
563
|
+
|
|
564
|
+
const ApiProvider = ({ children }) => {
|
|
565
|
+
const config = useMemo<ConfigurationParameters>(
|
|
566
|
+
() => ({
|
|
567
|
+
basePath: 'https://your-api-url.domain',
|
|
568
|
+
middlewares: [/* Your middlewares, eg. adding authorization header */]
|
|
569
|
+
}),
|
|
570
|
+
[]
|
|
571
|
+
);
|
|
572
|
+
|
|
573
|
+
return (
|
|
574
|
+
<ApiConfigProvider config={config}>
|
|
575
|
+
<ApiInstancesProvider apis={providedApis}>{children}</ApiInstancesProvider>
|
|
576
|
+
</ApiConfigProvider>
|
|
577
|
+
);
|
|
578
|
+
};
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
2. Using the hooks
|
|
582
|
+
|
|
583
|
+
The SDK exposes two React hooks for each endpoints: a query and a mutation. Their name come from the `operationId` you provided for them in the OpenAPI files. Eg.`useGetUsersQuery` and `useGetUsersMutation`.
|
|
584
|
+
|
|
585
|
+
Note: While both hooks are generated for all endpoints, we recommend using queries for GET requests and mutations for POST/PUT/PATCH/DELETE requests.
|
|
586
|
+
|
|
587
|
+
They can be used in a very similar way like `useQuery` and `useMutation` from `@tanstack/react-query` but they provide:
|
|
588
|
+
- built-in `queryFn`s
|
|
589
|
+
- built-in `queryKey`s
|
|
590
|
+
- typed input parameters and outputs
|
|
591
|
+
|
|
592
|
+
To fetch the list of users from the above examples is as simple as:
|
|
593
|
+
|
|
594
|
+
```ts
|
|
595
|
+
const usersQuery = useGetUsersQuery();
|
|
596
|
+
// ^- usersQuery.data: GetUsersListResponse | undefined
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
Or if your query has parameters they be passed as the first parameter:
|
|
600
|
+
```ts
|
|
601
|
+
const usersQuery = useGetUsersQuery({ offset: 15, limit: 10 });
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
3. Query options
|
|
605
|
+
|
|
606
|
+
Query options are available as the first or the second parameter of the query, depending on if the query has parameters or not.
|
|
607
|
+
|
|
608
|
+
```ts
|
|
609
|
+
const usersQuery = useGetUsersQuery({ refetchInterval: 5000 });
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
or
|
|
613
|
+
```ts
|
|
614
|
+
const usersQuery = useGetUsersQuery({ offset: 15, limit: 10 }, { refetchInterval: 5000 });
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
4. Managing query keys
|
|
618
|
+
|
|
619
|
+
You don't have to and also you can't provide `queryFn` or the `queryKey` options for use*Query hooks, as the SDK handles them automatically. You might still need to access the automatically generated query keys, so the SDK also exposes query key factories that you can use to refetch/invalidate query keys. This means that the SDK is the single source of the query keys in your app.
|
|
620
|
+
|
|
621
|
+
```tsx
|
|
622
|
+
const queryClient = useQueryClient();
|
|
623
|
+
|
|
624
|
+
queryClient.invalidateQueries({ queryKey: getUsersQueryKey.all() })
|
|
625
|
+
|
|
626
|
+
// or if your query has parameters
|
|
627
|
+
queryClient.invalidateQueries({ queryKey: getUsersQueryKey.withParams({ offset: 15, limit: 10 }) })
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
5. Disabled queries
|
|
631
|
+
|
|
632
|
+
Queries with parameters can also be disabled by providing `undefined` as a parameter for them. This set's `enabled` option to `false` under the hood for the query. This could help you to write dependent queries easier.
|
|
633
|
+
|
|
634
|
+
```ts
|
|
635
|
+
const accountsQuery = useGetAccountsQuery();
|
|
636
|
+
const accountId = accountsQuery.data?.at(0)?.id;
|
|
637
|
+
|
|
638
|
+
const reportsQuery = useGetReportsQuery(accountId && { accountId });
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
In this case `reportsQuery` is not running until `accountsQuery` finished fetching.
|
|
642
|
+
|
|
643
|
+
6. Passing headers to queries and mutations
|
|
644
|
+
|
|
645
|
+
`@tanstack/react-query` is not reposinble from what data sources you gather your data. This SDK does, it is deeply integrated with an underlaying API layer. So we added support to add headers to your requests.
|
|
646
|
+
|
|
647
|
+
```ts
|
|
648
|
+
// HEADERS is a JavaScript symbol provided by the SDK. By its unique nature it makes sure that it doesn't interfere with the other parameters you pass to your queries.
|
|
649
|
+
import { HEADERS } from '@project/oasg-example-react';
|
|
650
|
+
|
|
651
|
+
// Use with queries:
|
|
652
|
+
const usersQuery = useGetUsersQuery({
|
|
653
|
+
[HEADERS]: {
|
|
654
|
+
'X-Users-Feature-Flag': 'B',
|
|
655
|
+
}
|
|
656
|
+
})
|
|
657
|
+
|
|
658
|
+
// With mutations - headers can be passed at the hook level:
|
|
659
|
+
const createUserMutation = useCreateUserMutation({
|
|
660
|
+
[HEADERS]: {
|
|
661
|
+
'X-Users-Feature-Flag': 'A',
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// Or while calling `mutate` or `mutateAsync`:
|
|
666
|
+
createUserMutation.mutate({
|
|
667
|
+
createUserRequest: userData,
|
|
668
|
+
[HEADERS]: {
|
|
669
|
+
'X-Users-Feature-Flag': 'B',
|
|
670
|
+
}
|
|
671
|
+
})
|
|
672
|
+
|
|
673
|
+
// Headers are merged in this order (later overrides earlier):
|
|
674
|
+
// 1. middleware configuration
|
|
675
|
+
// 2. mutation hook options
|
|
676
|
+
// 3. mutate/mutateAsync parameters
|
|
677
|
+
```
|
|
557
678
|
|
|
558
679
|
#### `stubby`
|
|
559
680
|
|
|
@@ -1117,12 +1238,104 @@ Validations from OpenAPI spec:
|
|
|
1117
1238
|
| packageName | Name of the generated NPM package | Y | - |
|
|
1118
1239
|
| repository | URL of the NPM package registry | Y | - |
|
|
1119
1240
|
|
|
1241
|
+
#### `msw`
|
|
1242
|
+
|
|
1243
|
+
```json
|
|
1244
|
+
{
|
|
1245
|
+
"id": "msw",
|
|
1246
|
+
"type": "msw",
|
|
1247
|
+
"source": "source-merged",
|
|
1248
|
+
"packageName": "@project/oasg-example-msw",
|
|
1249
|
+
"repository": "https://gitlab.supercharge.io/api/v4/projects/1226/packages/npm/"
|
|
1250
|
+
}
|
|
1251
|
+
```
|
|
1252
|
+
|
|
1253
|
+
|Parameter| Description| Required | Default |
|
|
1254
|
+
|-|-|-|-|
|
|
1255
|
+
| packageName | Name of the generated NPM package | Y | - |
|
|
1256
|
+
| repository | URL of the NPM package registry | Y | - |
|
|
1257
|
+
|
|
1258
|
+
**Usage**<br>
|
|
1259
|
+
|
|
1260
|
+
1. Configure the SDK
|
|
1261
|
+
|
|
1262
|
+
Start by configuring the SDK with a `baseUrl` and an optional `delay`:
|
|
1263
|
+
|
|
1264
|
+
```ts
|
|
1265
|
+
import { setMswSdkConfig } from '@project/oasg-example-msw';
|
|
1266
|
+
|
|
1267
|
+
setMswSdkConfig({
|
|
1268
|
+
baseUrl: 'https://your-api-url.domain',
|
|
1269
|
+
// each request will take at least 100ms and at most 400ms (this is the default)
|
|
1270
|
+
// disable delay by setting it to [0, 0]
|
|
1271
|
+
delay: [100, 400],
|
|
1272
|
+
});
|
|
1273
|
+
```
|
|
1274
|
+
|
|
1275
|
+
2. Mock your endpoints
|
|
1276
|
+
|
|
1277
|
+
Once configured, you can start mocking your endpoints.
|
|
1278
|
+
The SDK automatically sets up the handlers and enforces fully typed params, query params, request bodies, and responses based on your OpenAPI spec.
|
|
1279
|
+
|
|
1280
|
+
```ts
|
|
1281
|
+
import { setupWorker } from 'msw/browser';
|
|
1282
|
+
import { HttpReponse } from 'msw';
|
|
1283
|
+
import { mockUsersApi, type User } from '@project/oasg-example-msw';
|
|
1284
|
+
|
|
1285
|
+
const mockUsers: User[] = [
|
|
1286
|
+
{
|
|
1287
|
+
id: crypto.randomUUID(),
|
|
1288
|
+
firstName: 'Chester',
|
|
1289
|
+
lastName: 'Bennington',
|
|
1290
|
+
createdAt: new Date(),
|
|
1291
|
+
},
|
|
1292
|
+
{
|
|
1293
|
+
id: crypto.randomUUID(),
|
|
1294
|
+
firstName: 'Emily',
|
|
1295
|
+
lastName: 'Armstrong',
|
|
1296
|
+
createdAt: new Date(),
|
|
1297
|
+
}
|
|
1298
|
+
];
|
|
1299
|
+
|
|
1300
|
+
setupWorker(
|
|
1301
|
+
// each tag in your OpenAPI spec exposes a `mock{ApiName}Api` helper
|
|
1302
|
+
...mockUsersApi({
|
|
1303
|
+
// provide the endpoints you want to mock by their `operationId`
|
|
1304
|
+
getUsers: (info) => {
|
|
1305
|
+
return HttpResponse({
|
|
1306
|
+
items: info.queryParams.sortDirection === 'desc'
|
|
1307
|
+
? mockUsers.toSorted((a, b) => a.createdAt - b.createdAt)
|
|
1308
|
+
: mockUsers.toSorted((a, b) => b.createdAt - a.createdAt),
|
|
1309
|
+
})
|
|
1310
|
+
},
|
|
1311
|
+
createUser: (info) => {
|
|
1312
|
+
const user = await info.request.json();
|
|
1313
|
+
mockUsers.push({
|
|
1314
|
+
id: crypto.randomUUID(),
|
|
1315
|
+
createdAt: new Date(),
|
|
1316
|
+
...user,
|
|
1317
|
+
});
|
|
1318
|
+
|
|
1319
|
+
return HttpResponse(null, { status: 201 });
|
|
1320
|
+
}
|
|
1321
|
+
}),
|
|
1322
|
+
)
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1120
1325
|
---
|
|
1121
1326
|
|
|
1122
1327
|
# Migration Guide
|
|
1123
1328
|
|
|
1124
1329
|
This section covers the breaking changes and their migrations across major version upgrades.
|
|
1125
1330
|
|
|
1331
|
+
## From `17.x.x` to `18.0.0`
|
|
1332
|
+
|
|
1333
|
+
### Breaking in `react` target
|
|
1334
|
+
|
|
1335
|
+
1. Exported hooks were renamed. API names are not part of the hooks anymore as `operationId` is unique by itself. E.g. instead of `useUsersApiCreateUserMutation` the name is `useCreateApiMutation`.
|
|
1336
|
+
2. *Query keys* are now managed by the SDK itself and they were removed from the query's options object. Check the *Managing query keys* section below to get an idea of how you can still work with query keys in your application.
|
|
1337
|
+
3. If an endpoint has URL parameters, search parameters, or a body, it is now the first parameter of the `use*Query` hooks. E.g. instead of `useGetUserList({ refetchInterval: 60_000 }, { limit, offset })` it is `useGetUserList({ limit, offset }, { refetchInterval: 60_000 })`. This especially comes in handy together with the automatic queryKey management the SDK provides, as without the queryKey there are no required parameters in the query's options object, so you can completely ignore it if you don't want to set any options. E.g. instead of `useGetUserList({}, { limit, offset })` it is `useGetUserList({ limit, offset })` now.
|
|
1338
|
+
|
|
1126
1339
|
## From `16.x.x` to `17.0.0`
|
|
1127
1340
|
|
|
1128
1341
|
From this version _OASg_ requires `node` version `^20.19` by default. Please upgrade your projects accordingly.
|
package/bin/oasg
CHANGED
|
@@ -21,6 +21,7 @@ const { applyOverrides } = require(`${__dirname}/overrider.js`);
|
|
|
21
21
|
const { openApiTarget } = require(`${__dirname}/openapi-target.js`);
|
|
22
22
|
const { postmanTarget } = require(`${__dirname}/postman-target.js`);
|
|
23
23
|
const { processSource } = require(`${__dirname}/process-source.js`);
|
|
24
|
+
const { saveLock } = require(`${__dirname}/save-lock.js`);
|
|
24
25
|
const { globSync } = require('glob');
|
|
25
26
|
|
|
26
27
|
const projectPackageJson = JSON.parse(fs.readFileSync('package.json'));
|
|
@@ -35,7 +36,7 @@ const PROXY_PORT = '9999';
|
|
|
35
36
|
|
|
36
37
|
const DEFAULT_GENERATOR_MAPPING = {
|
|
37
38
|
// client targets
|
|
38
|
-
"android": { version: '7.0
|
|
39
|
+
"android": { version: '7.17.0', generator: 'kotlin' },
|
|
39
40
|
"angular": { version: '7.11.0', generator: 'typescript-angular' },
|
|
40
41
|
"feign": { version: '7.12.0', generator: 'spring' },
|
|
41
42
|
"feign-kotlin": { version: '7.12.0', generator: 'kotlin-spring' },
|
|
@@ -43,7 +44,7 @@ const DEFAULT_GENERATOR_MAPPING = {
|
|
|
43
44
|
"flutter": { version: '7.0.1', generator: 'dart-dio' },
|
|
44
45
|
"ios": { version: '7.0.1', generator: 'swift5' },
|
|
45
46
|
"apple-swift": { version: undefined, generator: undefined },
|
|
46
|
-
"kmp": { version: '7.
|
|
47
|
+
"kmp": { version: '7.17.0', generator: 'kotlin' },
|
|
47
48
|
"python": { version: '7.11.0', generator: 'python' },
|
|
48
49
|
"python-legacy": { version: '7.11.0', generator: 'python-pydantic-v1' },
|
|
49
50
|
"react": { version: '7.0.1', generator: 'typescript-fetch' },
|
|
@@ -62,6 +63,7 @@ const DEFAULT_GENERATOR_MAPPING = {
|
|
|
62
63
|
"openapi": { version: undefined, generator: undefined },
|
|
63
64
|
"stubby": { version: '4.3.1', generator: 'stubby' },
|
|
64
65
|
"postman": { version: undefined, generator: undefined },
|
|
66
|
+
"msw": { version: '7.11.0', generator: 'typescript-fetch' },
|
|
65
67
|
};
|
|
66
68
|
const DEFAULT_KTLINT_VERSION = '1.0.0';
|
|
67
69
|
const BIN_FOLDER = 'out/.bin';
|
|
@@ -134,8 +136,23 @@ async function run() {
|
|
|
134
136
|
describe: 'Generate as pre-release (optional). \nHow a pre-release is handled varies between different target types.',
|
|
135
137
|
type: 'boolean'
|
|
136
138
|
})
|
|
139
|
+
.option('force-lock', {
|
|
140
|
+
describe: 'Force usage of saved package-lock.json (skip npm install, use saved lock immediately)',
|
|
141
|
+
type: 'boolean',
|
|
142
|
+
default: false
|
|
143
|
+
})
|
|
137
144
|
}, (argv) => generate(argv))
|
|
138
145
|
|
|
146
|
+
// save-lock
|
|
147
|
+
.command(['save-lock [target]', 'sl'], 'save package-lock.json for a target', (yargs) => {
|
|
148
|
+
yargs
|
|
149
|
+
.positional('target', {
|
|
150
|
+
describe: 'specify the target name',
|
|
151
|
+
type: 'string',
|
|
152
|
+
demandOption: true
|
|
153
|
+
})
|
|
154
|
+
}, (argv) => saveLock(argv, config, checkTargetId))
|
|
155
|
+
|
|
139
156
|
// publish
|
|
140
157
|
.command(['publish [target]', 'p'], 'publish packages', (yargs) => {
|
|
141
158
|
yargs
|
|
@@ -159,7 +176,7 @@ function checkVersionMismatch() {
|
|
|
159
176
|
const oasgVersion = oasgPackageJson.version;
|
|
160
177
|
const oasgDepVersion = projectPackageJson.dependencies[oasgPackageJson.name];
|
|
161
178
|
|
|
162
|
-
if (oasgDepVersion.startsWith('file:')) {
|
|
179
|
+
if (!oasgDepVersion || oasgDepVersion.startsWith('file:')) {
|
|
163
180
|
return;
|
|
164
181
|
}
|
|
165
182
|
|
|
@@ -477,6 +494,7 @@ async function generate(argv) {
|
|
|
477
494
|
const targetIds = determineTargetIds(argv);
|
|
478
495
|
VERSION = determineArtifactVersion(argv);
|
|
479
496
|
const preRelease = determinePreRelease(argv);
|
|
497
|
+
const forceLock = argv['force-lock'] || argv.forceLock || false;
|
|
480
498
|
|
|
481
499
|
const sources = await buildSources(sourceIdsFromTargetIds(targetIds));
|
|
482
500
|
|
|
@@ -509,7 +527,7 @@ async function generate(argv) {
|
|
|
509
527
|
const templateDir = customizeTemplates(target);
|
|
510
528
|
|
|
511
529
|
// run generation
|
|
512
|
-
exec(`bash -e ${__dirname}/../targets/${target.type}/generate.sh ${VERSION} ${binary} ${CONFIG_FILE_NAME} ${target.id} ${sources[target.source]} ${formatter} ${target.generatorId} ${preRelease.toString()} ${templateDir}`);
|
|
530
|
+
exec(`bash -e ${__dirname}/../targets/${target.type}/generate.sh ${VERSION} ${binary} ${CONFIG_FILE_NAME} ${target.id} ${sources[target.source]} ${formatter} ${target.generatorId} ${preRelease.toString()} ${templateDir} ${forceLock.toString()}`);
|
|
513
531
|
});
|
|
514
532
|
}
|
|
515
533
|
|
|
@@ -721,3 +739,4 @@ function determineArtifactVersion(argv) {
|
|
|
721
739
|
function determinePreRelease(argv) {
|
|
722
740
|
return argv.preRelease ? true : false;
|
|
723
741
|
}
|
|
742
|
+
|
package/bin/save-lock.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { exit } = require('process');
|
|
4
|
+
|
|
5
|
+
const { getTargetVersion } = require(`${__dirname}/target-version.js`);
|
|
6
|
+
|
|
7
|
+
async function saveLock(argv, config, checkTargetId) {
|
|
8
|
+
const { target } = argv;
|
|
9
|
+
|
|
10
|
+
// Validate target
|
|
11
|
+
checkTargetId(target);
|
|
12
|
+
|
|
13
|
+
// Validate target is applicable for save-lock (must be npm-based)
|
|
14
|
+
const targetObj = config.targets.find(t => t.id === target);
|
|
15
|
+
if (!targetObj) {
|
|
16
|
+
console.error(`Error: target '${target}' not found in config`);
|
|
17
|
+
exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const generateScriptPath = path.join(__dirname, '..', 'targets', targetObj.type, 'generate.sh');
|
|
21
|
+
let isNpmBased = false;
|
|
22
|
+
try {
|
|
23
|
+
if (fs.existsSync(generateScriptPath)) {
|
|
24
|
+
const scriptContent = fs.readFileSync(generateScriptPath, 'utf8');
|
|
25
|
+
// Heuristics: target is npm-based if its generate script uses npm
|
|
26
|
+
isNpmBased = /\bnpm\b/.test(scriptContent);
|
|
27
|
+
}
|
|
28
|
+
} catch (_) {
|
|
29
|
+
// ignore and treat as non-npm-based below
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!isNpmBased) {
|
|
33
|
+
// Collect npm-capable targets to help the user
|
|
34
|
+
const npmTargets = config.targets
|
|
35
|
+
.filter(t => {
|
|
36
|
+
const p = path.join(__dirname, '..', 'targets', t.type, 'generate.sh');
|
|
37
|
+
try {
|
|
38
|
+
if (!fs.existsSync(p)) return false;
|
|
39
|
+
const s = fs.readFileSync(p, 'utf8');
|
|
40
|
+
return /\bnpm\b/.test(s);
|
|
41
|
+
} catch (_) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
.map(t => t.id);
|
|
46
|
+
|
|
47
|
+
console.error(`Error: target '${target}' is not applicable for save-lock. This command only supports npm-based targets.`);
|
|
48
|
+
if (npmTargets.length > 0) {
|
|
49
|
+
console.error(`Valid npm targets: ${npmTargets.join(', ')}`);
|
|
50
|
+
}
|
|
51
|
+
exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const locksDir = '.oasg';
|
|
55
|
+
const sourceLockFile = path.join('out', target, 'package-lock.json');
|
|
56
|
+
|
|
57
|
+
console.log(`Saving package-lock.json for ${target}...`);
|
|
58
|
+
|
|
59
|
+
// Check if source package-lock.json exists
|
|
60
|
+
if (!fs.existsSync(sourceLockFile)) {
|
|
61
|
+
console.error(`Error: package-lock.json not found at ${sourceLockFile}`);
|
|
62
|
+
console.error(`Please run 'oasg generate ${target}' first to create the package-lock.json file.`);
|
|
63
|
+
exit(1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Get target version for dependency locking using the abstraction
|
|
67
|
+
const targetVersion = getTargetVersion(targetObj);
|
|
68
|
+
|
|
69
|
+
// Build path based on whether we have a target version
|
|
70
|
+
let targetLockDir, targetLockFile;
|
|
71
|
+
if (targetVersion) {
|
|
72
|
+
targetLockDir = path.join(locksDir, `${target}-${targetVersion}`);
|
|
73
|
+
targetLockFile = path.join(targetLockDir, 'package-lock.json');
|
|
74
|
+
} else {
|
|
75
|
+
targetLockDir = path.join(locksDir, target);
|
|
76
|
+
targetLockFile = path.join(targetLockDir, 'package-lock.json');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Create target directory
|
|
80
|
+
if (!fs.existsSync(targetLockDir)) {
|
|
81
|
+
fs.mkdirSync(targetLockDir, { recursive: true });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Copy package-lock.json
|
|
85
|
+
try {
|
|
86
|
+
fs.copyFileSync(sourceLockFile, targetLockFile);
|
|
87
|
+
console.log(`✓ Package-lock.json saved to ${targetLockFile}`);
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log('Next steps:');
|
|
90
|
+
console.log(`1. Commit the saved lock file to version control:`);
|
|
91
|
+
console.log(` git add ${targetLockFile}`);
|
|
92
|
+
console.log(` git commit -m "Add/update package-lock.json for ${target}"`);
|
|
93
|
+
console.log('');
|
|
94
|
+
console.log('2. This lock file will be used as a fallback if future builds fail due to dependency issues.');
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error(`Error copying package-lock.json: ${error.message}`);
|
|
97
|
+
exit(1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
exports.saveLock = saveLock;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility module for extracting target versions from target configurations.
|
|
3
|
+
*
|
|
4
|
+
* This module is used exclusively by the save-lock feature for npm-based projects
|
|
5
|
+
* to determine version-specific lock file paths.
|
|
6
|
+
*
|
|
7
|
+
* Different target types may have different target version extraction strategies.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Get the target version for a target.
|
|
15
|
+
*
|
|
16
|
+
* This function is used by the save-lock feature for npm-based targets to determine
|
|
17
|
+
* version-specific paths for storing package-lock.json files in the .oasg directory.
|
|
18
|
+
*
|
|
19
|
+
* For npm-based Angular and NestJS targets:
|
|
20
|
+
* - First checks if ngVersion is overridden in generatorCustomArgs (-p ngVersion=X.X.X)
|
|
21
|
+
* - Falls back to ngVersion in generator-config.json
|
|
22
|
+
*
|
|
23
|
+
* For other npm-based targets (react, typescript-axios, typescript-fetch, contract-testing):
|
|
24
|
+
* - Returns empty string (no target version, uses target id only for lock file path)
|
|
25
|
+
*
|
|
26
|
+
* @param {Object} targetObj - The target object from config
|
|
27
|
+
* @param {string} targetObj.type - The target type (e.g., 'angular', 'nestjs', 'react')
|
|
28
|
+
* @param {string} [targetObj.generatorCustomArgs] - Optional custom arguments passed to generator
|
|
29
|
+
* @returns {string} The target version or empty string if not applicable
|
|
30
|
+
*/
|
|
31
|
+
function getTargetVersion(targetObj) {
|
|
32
|
+
const targetType = targetObj.type;
|
|
33
|
+
|
|
34
|
+
// Only Angular and NestJS have target versions (ngVersion)
|
|
35
|
+
if (targetType !== 'angular' && targetType !== 'nestjs') {
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return getAngularNestjsTargetVersion(targetObj);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get the ngVersion for Angular or NestJS npm-based targets.
|
|
44
|
+
*
|
|
45
|
+
* Used by save-lock to create version-specific lock file paths (e.g., .oasg/angular-12.0.0/).
|
|
46
|
+
*
|
|
47
|
+
* Priority: 1. generatorCustomArgs override, 2. generator-config.json default
|
|
48
|
+
*
|
|
49
|
+
* @param {Object} targetObj - The target object
|
|
50
|
+
* @returns {string} The ngVersion or empty string
|
|
51
|
+
*/
|
|
52
|
+
function getAngularNestjsTargetVersion(targetObj) {
|
|
53
|
+
let targetVersion = '';
|
|
54
|
+
|
|
55
|
+
// First, check if ngVersion is overridden in generatorCustomArgs
|
|
56
|
+
if (targetObj.generatorCustomArgs) {
|
|
57
|
+
const ngVersionMatch = targetObj.generatorCustomArgs.match(/-p\s*ngVersion=(\d+\.\d+\.\d+)/);
|
|
58
|
+
if (ngVersionMatch) {
|
|
59
|
+
targetVersion = ngVersionMatch[1];
|
|
60
|
+
console.log(`Using ngVersion from generatorCustomArgs: ${targetVersion}`);
|
|
61
|
+
return targetVersion;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Fall back to generator-config.json if not found in generatorCustomArgs
|
|
66
|
+
const generatorConfigPath = path.join(__dirname, '..', 'targets', targetObj.type, 'generator-config.json');
|
|
67
|
+
try {
|
|
68
|
+
if (fs.existsSync(generatorConfigPath)) {
|
|
69
|
+
const generatorConfig = JSON.parse(fs.readFileSync(generatorConfigPath, 'utf8'));
|
|
70
|
+
targetVersion = generatorConfig.ngVersion || '';
|
|
71
|
+
if (targetVersion) {
|
|
72
|
+
console.log(`Using ngVersion from generator-config.json: ${targetVersion}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
// Silently ignore - no target version available
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return targetVersion;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = {
|
|
83
|
+
getTargetVersion
|
|
84
|
+
};
|
package/config.schema.yml
CHANGED
|
@@ -38,6 +38,7 @@ properties:
|
|
|
38
38
|
- $ref: '#/targets/Postman'
|
|
39
39
|
- $ref: '#/targets/TypeScriptAxios'
|
|
40
40
|
- $ref: '#/targets/TypeScriptFetch'
|
|
41
|
+
- $ref: '#/targets/MSW'
|
|
41
42
|
required:
|
|
42
43
|
- targets
|
|
43
44
|
additionalProperties: false
|
|
@@ -533,6 +534,20 @@ targets:
|
|
|
533
534
|
- packageName
|
|
534
535
|
- repository
|
|
535
536
|
|
|
537
|
+
MSW:
|
|
538
|
+
allOf:
|
|
539
|
+
- $ref: '#/targets/Base'
|
|
540
|
+
- properties:
|
|
541
|
+
type:
|
|
542
|
+
pattern: "^msw$"
|
|
543
|
+
packageName:
|
|
544
|
+
type: string
|
|
545
|
+
repository:
|
|
546
|
+
type: string
|
|
547
|
+
required:
|
|
548
|
+
- packageName
|
|
549
|
+
- repository
|
|
550
|
+
|
|
536
551
|
definitions:
|
|
537
552
|
# default
|
|
538
553
|
SourceOverrides:
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
#!/bin/bash
|
|
2
2
|
|
|
3
3
|
source $(dirname "$0")/../common.sh
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ mkdir -p out/$targetId
|
|
|
7
7
|
|
|
8
8
|
if [ -z "$formatterCustomArgs" ]
|
|
9
9
|
then
|
|
10
|
-
formatterCustomArgs="--disabled_rules=no-wildcard-imports,max-line-length,enum-entry-name-case"
|
|
10
|
+
formatterCustomArgs="--disabled_rules=no-wildcard-imports,max-line-length,enum-entry-name-case,filename,no-empty-file"
|
|
11
11
|
fi
|
|
12
12
|
|
|
13
13
|
java -jar $binary generate \
|