@dorval/dio 0.2.1

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.
@@ -0,0 +1,24 @@
1
+ import { ClientGeneratorBuilder, ClientBuilder, ClientHeaderBuilder, ClientDependenciesBuilder, ClientFooterBuilder } from '@dorval/core';
2
+
3
+ /**
4
+ * Generate Dio client builder
5
+ */
6
+ declare const generateDioClient: ClientBuilder;
7
+ /**
8
+ * Generate Dio header
9
+ */
10
+ declare const generateDioHeader: ClientHeaderBuilder;
11
+ /**
12
+ * Get Dio dependencies
13
+ */
14
+ declare const getDioDependencies: ClientDependenciesBuilder;
15
+ /**
16
+ * Generate Dio footer
17
+ */
18
+ declare const generateDioFooter: ClientFooterBuilder;
19
+ /**
20
+ * Builder factory function (following Orval pattern)
21
+ */
22
+ declare const builder: () => () => ClientGeneratorBuilder;
23
+
24
+ export { builder, builder as default, generateDioClient, generateDioFooter, generateDioHeader, getDioDependencies };
package/dist/index.js ADDED
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ builder: () => builder,
24
+ default: () => index_default,
25
+ generateDioClient: () => generateDioClient,
26
+ generateDioFooter: () => generateDioFooter,
27
+ generateDioHeader: () => generateDioHeader,
28
+ getDioDependencies: () => getDioDependencies
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+ var DIO_DEPENDENCIES = [
32
+ {
33
+ exports: [
34
+ { name: "Dio", default: false, values: false },
35
+ { name: "Options", default: false, values: false },
36
+ { name: "DioException", default: false, values: false },
37
+ { name: "Response", default: false, values: false }
38
+ ],
39
+ dependency: "dio"
40
+ }
41
+ ];
42
+ var generateDioImplementation = ({
43
+ verb,
44
+ route,
45
+ operationName,
46
+ response,
47
+ body,
48
+ headers,
49
+ queryParams,
50
+ pathParams,
51
+ props,
52
+ override,
53
+ formData,
54
+ formUrlEncoded
55
+ }, { output }) => {
56
+ const httpMethod = verb.toLowerCase();
57
+ const hasBody = ["post", "put", "patch"].includes(httpMethod) && body;
58
+ const hasQueryParams = !!queryParams;
59
+ const hasHeaders = !!headers;
60
+ const hasPathParams = pathParams && pathParams.length > 0;
61
+ let pathConstruction = hasPathParams ? `final path = '${route}'${pathParams.map((p) => `.replaceAll('{${p.name}}', ${p.dartName}.toString())`).join("")};` : `const path = '${route}';`;
62
+ let queryParamsConstruction = "";
63
+ if (hasQueryParams) {
64
+ queryParamsConstruction = `
65
+ final queryParameters = <String, dynamic>{
66
+ ${queryParams.map((q) => `if (${q.dartName} != null) '${q.name}': ${q.dartName},`).join("\n ")}
67
+ };`;
68
+ }
69
+ let headersConstruction = "";
70
+ if (hasHeaders) {
71
+ headersConstruction = `
72
+ final requestHeaders = <String, String>{
73
+ ${headers.map((h) => `if (${h.dartName} != null) '${h.name}': ${h.dartName}.toString(),`).join("\n ")}
74
+ };`;
75
+ }
76
+ let methodCall = `await client.${httpMethod}(
77
+ path,`;
78
+ if (hasBody) {
79
+ methodCall += `
80
+ data: ${body.dartName}${body.isModel ? ".toJson()" : ""},`;
81
+ }
82
+ if (hasQueryParams) {
83
+ methodCall += `
84
+ queryParameters: queryParameters,`;
85
+ }
86
+ if (hasHeaders) {
87
+ methodCall += `
88
+ options: Options(headers: requestHeaders),`;
89
+ }
90
+ methodCall += `
91
+ )`;
92
+ let responseHandling = "";
93
+ if (response.isVoid) {
94
+ responseHandling = "return;";
95
+ } else if (response.isList) {
96
+ responseHandling = `
97
+ return (response.data as List<dynamic>)
98
+ .map((item) => ${response.itemType}.fromJson(item as Map<String, dynamic>))
99
+ .toList();`;
100
+ } else if (response.isModel) {
101
+ responseHandling = `
102
+ return ${response.type}.fromJson(response.data as Map<String, dynamic>);`;
103
+ } else if (response.isPrimitive) {
104
+ responseHandling = `
105
+ return response.data as ${response.type};`;
106
+ } else {
107
+ responseHandling = `
108
+ return response.data;`;
109
+ }
110
+ return `
111
+ Future<${response.dartType}> ${operationName}(${props.map((p) => `${p.type} ${p.name}`).join(", ")}) async {
112
+ ${pathConstruction}
113
+ ${queryParamsConstruction}
114
+ ${headersConstruction}
115
+
116
+ try {
117
+ final response = ${methodCall};
118
+ ${responseHandling}
119
+ } on DioException catch (e) {
120
+ throw ApiException(
121
+ statusCode: e.response?.statusCode,
122
+ message: e.message ?? 'Unknown error occurred',
123
+ error: e,
124
+ );
125
+ }
126
+ }`;
127
+ };
128
+ var generateDioClient = (verbOptions, options) => {
129
+ const implementation = generateDioImplementation(verbOptions, options);
130
+ const imports = [
131
+ "import 'package:dio/dio.dart';",
132
+ "import '../api_client.dart';",
133
+ "import '../api_exception.dart';"
134
+ ];
135
+ if (verbOptions.response?.isModel) {
136
+ imports.push(`import '../models/${verbOptions.response.fileName}.dart';`);
137
+ }
138
+ if (verbOptions.body?.isModel) {
139
+ imports.push(`import '../models/${verbOptions.body.fileName}.dart';`);
140
+ }
141
+ return { implementation, imports };
142
+ };
143
+ var generateDioHeader = ({ title }) => {
144
+ return `
145
+ /// ${title ? `${title} - ` : ""}Generated Dio client service
146
+ /// This service uses Dio for HTTP requests
147
+ `;
148
+ };
149
+ var getDioDependencies = (hasGlobalMutator) => {
150
+ if (hasGlobalMutator) {
151
+ return [];
152
+ }
153
+ return DIO_DEPENDENCIES;
154
+ };
155
+ var generateDioFooter = ({ operationNames }) => {
156
+ return "";
157
+ };
158
+ var dioClientBuilder = {
159
+ client: generateDioClient,
160
+ header: generateDioHeader,
161
+ dependencies: getDioDependencies,
162
+ footer: generateDioFooter
163
+ };
164
+ var builder = () => () => dioClientBuilder;
165
+ var index_default = builder;
166
+ // Annotate the CommonJS export names for ESM import in node:
167
+ 0 && (module.exports = {
168
+ builder,
169
+ generateDioClient,
170
+ generateDioFooter,
171
+ generateDioHeader,
172
+ getDioDependencies
173
+ });
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@dorval/dio",
3
+ "version": "0.2.1",
4
+ "description": "Dio client implementation for Dorval",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsup src/index.ts --dts",
9
+ "dev": "tsup src/index.ts --dts --watch",
10
+ "test": "vitest run"
11
+ },
12
+ "dependencies": {
13
+ "@dorval/core": "*"
14
+ },
15
+ "devDependencies": {
16
+ "tsup": "^8.0.1",
17
+ "typescript": "^5.3.3",
18
+ "vitest": "^0.6.3"
19
+ },
20
+ "peerDependencies": {
21
+ "@dorval/core": "*"
22
+ }
23
+ }
@@ -0,0 +1,18 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateDioClient } from './index';
3
+
4
+ describe('@dorval/dio', () => {
5
+ it('should export generateDioClient function', () => {
6
+ expect(generateDioClient).toBeDefined();
7
+ expect(typeof generateDioClient).toBe('function');
8
+ });
9
+
10
+ it('should be a client builder function', () => {
11
+ // generateDioClient is a ClientGeneratorBuilder function
12
+ // It returns a builder that will be called by the core generator
13
+ const builder = generateDioClient;
14
+ expect(builder).toBeDefined();
15
+ expect(typeof builder).toBe('function');
16
+ expect(builder.name).toBe('generateDioClient');
17
+ });
18
+ });
package/src/index.ts ADDED
@@ -0,0 +1,206 @@
1
+ import {
2
+ ClientBuilder,
3
+ ClientGeneratorBuilder,
4
+ ClientHeaderBuilder,
5
+ ClientDependenciesBuilder,
6
+ ClientFooterBuilder,
7
+ GeneratorVerbOptions,
8
+ GeneratorOptions,
9
+ GeneratorDependency,
10
+ } from '@dorval/core';
11
+
12
+ const DIO_DEPENDENCIES: GeneratorDependency[] = [
13
+ {
14
+ exports: [
15
+ { name: 'Dio', default: false, values: false },
16
+ { name: 'Options', default: false, values: false },
17
+ { name: 'DioException', default: false, values: false },
18
+ { name: 'Response', default: false, values: false },
19
+ ],
20
+ dependency: 'dio',
21
+ },
22
+ ];
23
+
24
+ /**
25
+ * Generate Dio client implementation for a service method
26
+ */
27
+ const generateDioImplementation = (
28
+ {
29
+ verb,
30
+ route,
31
+ operationName,
32
+ response,
33
+ body,
34
+ headers,
35
+ queryParams,
36
+ pathParams,
37
+ props,
38
+ override,
39
+ formData,
40
+ formUrlEncoded,
41
+ }: GeneratorVerbOptions,
42
+ { output }: GeneratorOptions,
43
+ ): string => {
44
+ const httpMethod = verb.toLowerCase();
45
+ const hasBody = ['post', 'put', 'patch'].includes(httpMethod) && body;
46
+ const hasQueryParams = !!queryParams;
47
+ const hasHeaders = !!headers;
48
+ const hasPathParams = pathParams && pathParams.length > 0;
49
+
50
+ // Build path with parameters
51
+ let pathConstruction = hasPathParams
52
+ ? `final path = '${route}'${pathParams.map((p: any) => `.replaceAll('{${p.name}}', ${p.dartName}.toString())`).join('')};`
53
+ : `const path = '${route}';`;
54
+
55
+ // Build query parameters
56
+ let queryParamsConstruction = '';
57
+ if (hasQueryParams) {
58
+ queryParamsConstruction = `
59
+ final queryParameters = <String, dynamic>{
60
+ ${queryParams.map((q: any) => `if (${q.dartName} != null) '${q.name}': ${q.dartName},`).join('\n ')}
61
+ };`;
62
+ }
63
+
64
+ // Build headers
65
+ let headersConstruction = '';
66
+ if (hasHeaders) {
67
+ headersConstruction = `
68
+ final requestHeaders = <String, String>{
69
+ ${headers.map((h: any) => `if (${h.dartName} != null) '${h.name}': ${h.dartName}.toString(),`).join('\n ')}
70
+ };`;
71
+ }
72
+
73
+ // Build method call
74
+ let methodCall = `await client.${httpMethod}(
75
+ path,`;
76
+
77
+ if (hasBody) {
78
+ methodCall += `
79
+ data: ${body.dartName}${body.isModel ? '.toJson()' : ''},`;
80
+ }
81
+
82
+ if (hasQueryParams) {
83
+ methodCall += `
84
+ queryParameters: queryParameters,`;
85
+ }
86
+
87
+ if (hasHeaders) {
88
+ methodCall += `
89
+ options: Options(headers: requestHeaders),`;
90
+ }
91
+
92
+ methodCall += `
93
+ )`;
94
+
95
+ // Build response handling
96
+ let responseHandling = '';
97
+ if (response.isVoid) {
98
+ responseHandling = 'return;';
99
+ } else if (response.isList) {
100
+ responseHandling = `
101
+ return (response.data as List<dynamic>)
102
+ .map((item) => ${response.itemType}.fromJson(item as Map<String, dynamic>))
103
+ .toList();`;
104
+ } else if (response.isModel) {
105
+ responseHandling = `
106
+ return ${response.type}.fromJson(response.data as Map<String, dynamic>);`;
107
+ } else if (response.isPrimitive) {
108
+ responseHandling = `
109
+ return response.data as ${response.type};`;
110
+ } else {
111
+ responseHandling = `
112
+ return response.data;`;
113
+ }
114
+
115
+ // Build complete implementation
116
+ return `
117
+ Future<${response.dartType}> ${operationName}(${props.map((p: any) => `${p.type} ${p.name}`).join(', ')}) async {
118
+ ${pathConstruction}
119
+ ${queryParamsConstruction}
120
+ ${headersConstruction}
121
+
122
+ try {
123
+ final response = ${methodCall};
124
+ ${responseHandling}
125
+ } on DioException catch (e) {
126
+ throw ApiException(
127
+ statusCode: e.response?.statusCode,
128
+ message: e.message ?? 'Unknown error occurred',
129
+ error: e,
130
+ );
131
+ }
132
+ }`;
133
+ };
134
+
135
+ /**
136
+ * Generate Dio client builder
137
+ */
138
+ export const generateDioClient: ClientBuilder = (
139
+ verbOptions: GeneratorVerbOptions,
140
+ options: GeneratorOptions,
141
+ ) => {
142
+ const implementation = generateDioImplementation(verbOptions, options);
143
+
144
+ const imports = [
145
+ "import 'package:dio/dio.dart';",
146
+ "import '../api_client.dart';",
147
+ "import '../api_exception.dart';",
148
+ ];
149
+
150
+ // Add model imports if needed
151
+ if (verbOptions.response?.isModel) {
152
+ imports.push(`import '../models/${verbOptions.response.fileName}.dart';`);
153
+ }
154
+
155
+ if (verbOptions.body?.isModel) {
156
+ imports.push(`import '../models/${verbOptions.body.fileName}.dart';`);
157
+ }
158
+
159
+ return { implementation, imports };
160
+ };
161
+
162
+ /**
163
+ * Generate Dio header
164
+ */
165
+ export const generateDioHeader: ClientHeaderBuilder = ({ title }) => {
166
+ return `
167
+ /// ${title ? `${title} - ` : ''}Generated Dio client service
168
+ /// This service uses Dio for HTTP requests
169
+ `;
170
+ };
171
+
172
+ /**
173
+ * Get Dio dependencies
174
+ */
175
+ export const getDioDependencies: ClientDependenciesBuilder = (
176
+ hasGlobalMutator: boolean,
177
+ ) => {
178
+ if (hasGlobalMutator) {
179
+ return []; // Don't include Dio dependencies if using custom mutator
180
+ }
181
+ return DIO_DEPENDENCIES;
182
+ };
183
+
184
+ /**
185
+ * Generate Dio footer
186
+ */
187
+ export const generateDioFooter: ClientFooterBuilder = ({ operationNames }) => {
188
+ return ''; // No special footer needed for Dio
189
+ };
190
+
191
+ /**
192
+ * Dio client builder configuration
193
+ */
194
+ const dioClientBuilder: ClientGeneratorBuilder = {
195
+ client: generateDioClient,
196
+ header: generateDioHeader,
197
+ dependencies: getDioDependencies,
198
+ footer: generateDioFooter,
199
+ };
200
+
201
+ /**
202
+ * Builder factory function (following Orval pattern)
203
+ */
204
+ export const builder = () => () => dioClientBuilder;
205
+
206
+ export default builder;
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "composite": false,
7
+ "declaration": true
8
+ },
9
+ "include": ["src/**/*"],
10
+ "exclude": ["node_modules", "dist", "**/*.test.ts"],
11
+ "references": []
12
+ }