@qualisero/openapi-endpoint 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,17 @@
7
7
 
8
8
  Type-safe OpenAPI integration for Vue Query (TanStack Query).
9
9
 
10
+ ## Overview
11
+
12
+ Let's you get TanStack Vue Query composables that enforce consistency (name of endpoints, typing) with your API's `openapi.json` file:
13
+
14
+ ```typescript
15
+ const { data, isLoading } = api.useQuery(OperationId.getPet, { petId: '123' })
16
+
17
+ const createPetMutation = api.useMutation(OperationId.createPet)
18
+ createPetMutation.mutate({ data: { name: 'Fluffy', species: 'cat' } })
19
+ ```
20
+
10
21
  ## Installation
11
22
 
12
23
  ```bash
@@ -75,3 +86,114 @@ await createPetMutation.mutateAsync({
75
86
  data: { name: 'Fluffy', species: 'cat' },
76
87
  })
77
88
  ```
89
+
90
+ ## Advanced Usage
91
+
92
+ ### Automatic Operation Type Detection with `api.useEndpoint`
93
+
94
+ The `api.useEndpoint` method automatically detects whether an operation is a query (GET/HEAD/OPTIONS) or mutation (POST/PUT/PATCH/DELETE) based on the HTTP method defined in your OpenAPI specification:
95
+
96
+ ```typescript
97
+ import { ref, computed } from 'vue'
98
+ import { api, OperationId } from './api/init'
99
+
100
+ // Automatically becomes a query for GET operations
101
+ const listEndpoint = api.useEndpoint(OperationId.listPets)
102
+ // TypeScript knows this has query properties like .data, .isLoading, .refetch()
103
+
104
+ // Automatically becomes a mutation for POST operations
105
+ const createEndpoint = api.useEndpoint(OperationId.createPet)
106
+ // TypeScript knows this has mutation properties like .mutate(), .mutateAsync()
107
+
108
+ // Use the endpoints according to their detected type
109
+ const petData = listEndpoint.data // Query data
110
+ await createEndpoint.mutateAsync({ data: { name: 'Fluffy' } }) // Mutation execution
111
+ ```
112
+
113
+ ### Automatic Cache Management and Refetching
114
+
115
+ By default, mutations automatically:
116
+
117
+ 1. Update cache for matching queries with returned data
118
+ 2. Invalidate them to trigger a reload
119
+ 3. Invalidate matching list endpoints
120
+
121
+ ```typescript
122
+ // Default behavior: automatic cache management
123
+ const createPet = api.useMutation(OperationId.createPet)
124
+ // No additional configuration needed - cache management is automatic
125
+
126
+ // Manual control over cache invalidation
127
+ const updatePet = api.useMutation(OperationId.updatePet, {
128
+ dontInvalidate: true, // Disable automatic invalidation
129
+ dontUpdateCache: true, // Disable automatic cache updates
130
+ invalidateOperations: [OperationId.listPets], // Manually specify operations to invalidate
131
+ })
132
+
133
+ // Refetch specific endpoints after mutation
134
+ const petListQuery = api.useQuery(OperationId.listPets)
135
+ const createPetWithRefetch = api.useMutation(OperationId.createPet, {
136
+ refetchEndpoints: [petListQuery], // Manually refetch these endpoints
137
+ })
138
+ ```
139
+
140
+ ### Reactive Enabling/Disabling Based on Path Parameters
141
+
142
+ One powerful feature is chaining queries where one query provides the parameters for another:
143
+
144
+ ```typescript
145
+ import { ref, computed } from 'vue'
146
+
147
+ // First query to get user information
148
+ const userQuery = api.useQuery(OperationId.getUser, { userId: 123 })
149
+
150
+ // Second query that depends on the first query's result
151
+ const userPetsQuery = api.useQuery(
152
+ OperationId.listUserPets,
153
+ computed(() => ({
154
+ userId: userQuery.data.value?.id, // Chain: use ID from first query
155
+ })),
156
+ )
157
+
158
+ // Reactive parameter example
159
+ const selectedPetId = ref<string | undefined>(undefined)
160
+
161
+ // Query automatically enables/disables based on parameter availability
162
+ const petQuery = api.useQuery(
163
+ OperationId.getPet,
164
+ computed(() => ({ petId: selectedPetId.value })),
165
+ )
166
+
167
+ // Query is automatically disabled when petId is null/undefined
168
+ console.log(petQuery.isEnabled.value) // false when selectedPetId.value is null
169
+
170
+ // Enable the query by setting the parameter
171
+ selectedPetId.value = '123'
172
+ console.log(petQuery.isEnabled.value) // true when selectedPetId.value is set
173
+
174
+ // Complex conditional enabling
175
+ const userId = ref<string>('user1')
176
+ const shouldFetchPets = ref(true)
177
+
178
+ const userPetsQuery = api.useQuery(
179
+ OperationId.listUserPets,
180
+ computed(() => ({ userId: userId.value })),
181
+ {
182
+ enabled: computed(
183
+ () => shouldFetchPets.value, // Additional business logic
184
+ ),
185
+ },
186
+ )
187
+ ```
188
+
189
+ ## API Documentation
190
+
191
+ Full API documentation is available at [https://qualisero.github.io/openapi-endpoint/](https://qualisero.github.io/openapi-endpoint/). The documentation includes detailed information about all methods, types, and configuration options.
192
+
193
+ ## Contributing
194
+
195
+ Contributions are welcome! Please read our contributing guidelines and ensure all tests pass.
196
+
197
+ ## License
198
+
199
+ MIT
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { QueryClient } from '@tanstack/vue-query';
3
3
  import { EndpointQueryReturn } from './openapi-query';
4
4
  import { EndpointMutationReturn } from './openapi-mutation';
5
5
  import { Operations, GetPathParameters, OpenApiConfig, QQueryOptions, QMutationOptions, IsQueryOperation } from './types';
6
- export type { OperationInfo, QQueryOptions, OpenApiConfig, OpenApiInstance } from './types';
6
+ export type { OpenApiConfig, OpenApiInstance } from './types';
7
7
  export { type EndpointQueryReturn, useEndpointQuery } from './openapi-query';
8
8
  export { type EndpointMutationReturn, useEndpointMutation } from './openapi-mutation';
9
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -86,16 +86,16 @@ pathParamsOrOptions, optionsOrNull) {
86
86
  },
87
87
  onSuccess: async (data, vars, _context) => {
88
88
  const { dontInvalidate: dontInvalidateMutate, dontUpdateCache: dontUpdateCacheMutate, invalidateOperations: invalidateOperationsMutate, refetchEndpoints: refetchEndpointsMutate, } = vars || {};
89
- // Optimistically update cache with returned data for PUT/PATCH requests
89
+ // update cache with returned data for PUT/PATCH requests
90
90
  if (
91
91
  // dontUpdateCacheMutate supersedes dontUpdateCache from options
92
- (dontInvalidateMutate !== undefined ? !dontInvalidateMutate : !dontInvalidate) &&
92
+ (dontUpdateCacheMutate !== undefined ? !dontUpdateCacheMutate : !dontUpdateCache) &&
93
93
  data &&
94
94
  [HttpMethod.PUT, HttpMethod.PATCH].includes(method)) {
95
95
  await h.queryClient.setQueryData(queryKey.value, data);
96
96
  }
97
97
  // Invalidate queries for this path, and any additional specified operations
98
- if (dontUpdateCacheMutate !== undefined ? !dontUpdateCacheMutate : !dontUpdateCache) {
98
+ if (dontInvalidateMutate !== undefined ? !dontInvalidateMutate : !dontInvalidate) {
99
99
  // Invalidate all queries for this path (exact for POST, prefix for others):
100
100
  await h.queryClient.invalidateQueries({ queryKey: queryKey.value, exact: method !== HttpMethod.POST });
101
101
  const listPath = h.getListOperationPath(operationId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qualisero/openapi-endpoint",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/qualisero/openapi-endpoint.git"
@@ -37,6 +37,8 @@
37
37
  "lint:fix": "eslint . --fix",
38
38
  "format": "prettier --write .",
39
39
  "format:check": "prettier --check .",
40
+ "docs": "typedoc",
41
+ "docs:publish": "npm run docs && gh-pages -d docs",
40
42
  "prepublishOnly": "npm run build && npm run check"
41
43
  },
42
44
  "keywords": [
@@ -67,10 +69,12 @@
67
69
  "@vue/test-utils": "^2.4.6",
68
70
  "eslint": "^9.37.0",
69
71
  "eslint-plugin-prettier": "^5.5.4",
72
+ "gh-pages": "^6.3.0",
70
73
  "globals": "^16.4.0",
71
74
  "jsdom": "^27.0.0",
72
75
  "openapi-typescript": "^7.9.1",
73
76
  "prettier": "^3.6.2",
77
+ "typedoc": "^0.28.14",
74
78
  "typescript": "^5.9.2",
75
79
  "vitest": "^3.2.4"
76
80
  },