react-query-lightbase-codegen 0.3.0 → 1.0.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.
Files changed (45) hide show
  1. package/README.md +76 -0
  2. package/lib/commonjs/convertSwaggerFile.js +37 -0
  3. package/lib/commonjs/convertSwaggerFile.js.map +1 -0
  4. package/lib/commonjs/generateHooks.js +492 -0
  5. package/lib/commonjs/generateHooks.js.map +1 -0
  6. package/lib/commonjs/generateImports.js +48 -0
  7. package/lib/commonjs/generateImports.js.map +1 -0
  8. package/lib/commonjs/generateSchemas.js +119 -0
  9. package/lib/commonjs/generateSchemas.js.map +1 -0
  10. package/lib/commonjs/importSpecs.js +117 -0
  11. package/lib/commonjs/importSpecs.js.map +1 -0
  12. package/lib/commonjs/index.js +22 -0
  13. package/lib/commonjs/index.js.map +1 -0
  14. package/lib/commonjs/utils.js +212 -0
  15. package/lib/commonjs/utils.js.map +1 -0
  16. package/lib/src/convertSwaggerFile.js +29 -0
  17. package/lib/src/generateHooks.js +249 -0
  18. package/lib/src/generateImports.js +29 -0
  19. package/lib/src/generateSchemas.js +108 -0
  20. package/lib/src/importSpecs.js +134 -0
  21. package/lib/src/index.js +7 -0
  22. package/lib/src/utils.js +172 -0
  23. package/lib/typescript/convertSwaggerFile.d.ts +5 -0
  24. package/lib/typescript/generateHooks.d.ts +25 -0
  25. package/lib/typescript/generateImports.d.ts +7 -0
  26. package/lib/typescript/generateSchemas.d.ts +7 -0
  27. package/lib/typescript/importSpecs.d.ts +15 -0
  28. package/lib/typescript/index.d.ts +3 -0
  29. package/lib/typescript/utils.d.ts +24 -0
  30. package/package.json +71 -17
  31. package/src/convertSwaggerFile.ts +25 -0
  32. package/src/generateHooks.ts +490 -0
  33. package/src/generateImports.ts +41 -0
  34. package/src/generateSchemas.ts +114 -0
  35. package/src/importSpecs.ts +110 -0
  36. package/src/index.ts +3 -0
  37. package/src/utils.ts +190 -0
  38. package/lib/cjs/import-open-api.js +0 -1034
  39. package/lib/cjs/index.js +0 -5
  40. package/lib/cjs/react-query-codegen-import.js +0 -41
  41. package/lib/cjs/types.js +0 -2
  42. package/lib/esm/import-open-api.js +0 -1012
  43. package/lib/esm/index.js +0 -2
  44. package/lib/esm/react-query-codegen-import.js +0 -34
  45. package/lib/esm/types.js +0 -1
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.getResReqTypes = exports.formatDescription = exports.resolveValue = exports.getScalar = exports.isReference = exports.getDocs = void 0;
4
+ var lodash_1 = require("lodash");
5
+ var uniq = lodash_1["default"].uniq, isEmpty = lodash_1["default"].isEmpty;
6
+ var case_1 = require("case");
7
+ var pascal = case_1["default"].pascal;
8
+ var getDocs = function (data) {
9
+ return (0, exports.isReference)(data) ? '' : (0, exports.formatDescription)(data.description);
10
+ };
11
+ exports.getDocs = getDocs;
12
+ /**
13
+ * Discriminator helper for `ReferenceObject`
14
+ */
15
+ var isReference = function (property) {
16
+ return Boolean(property.$ref);
17
+ };
18
+ exports.isReference = isReference;
19
+ /**
20
+ * Return the typescript equivalent of open-api data type
21
+ */
22
+ var getScalar = function (item) {
23
+ var nullable = item.nullable ? ' | null' : '';
24
+ switch (item.type) {
25
+ case 'number':
26
+ case 'integer':
27
+ return 'number' + nullable;
28
+ case 'boolean':
29
+ return 'boolean' + nullable;
30
+ case 'array':
31
+ return getArray(item) + nullable;
32
+ case 'string':
33
+ return (item["enum"] ? "\"".concat(item["enum"].join("\" | \""), "\"") : 'string') + nullable;
34
+ case 'object':
35
+ default:
36
+ return getObject(item) + nullable;
37
+ }
38
+ };
39
+ exports.getScalar = getScalar;
40
+ /**
41
+ * Return the output type from the $ref
42
+ */
43
+ var getRef = function ($ref) {
44
+ if ($ref.startsWith('#/components/schemas')) {
45
+ return pascal($ref.replace('#/components/schemas/', ''));
46
+ }
47
+ else if ($ref.startsWith('#/components/responses')) {
48
+ return pascal($ref.replace('#/components/responses/', '')) + 'Response';
49
+ }
50
+ else if ($ref.startsWith('#/components/parameters')) {
51
+ return pascal($ref.replace('#/components/parameters/', '')) + 'Parameter';
52
+ }
53
+ else if ($ref.startsWith('#/components/requestBodies')) {
54
+ return pascal($ref.replace('#/components/requestBodies/', '')) + 'RequestBody';
55
+ }
56
+ else {
57
+ throw new Error('This library only resolve $ref that are include into `#/components/*` for now');
58
+ }
59
+ };
60
+ /**
61
+ * Return the output type from an array
62
+ */
63
+ var getArray = function (item) {
64
+ if (item.items) {
65
+ if (!(0, exports.isReference)(item.items) && (item.items.oneOf || item.items.allOf || item.items["enum"])) {
66
+ return "(".concat((0, exports.resolveValue)(item.items), ")[]");
67
+ }
68
+ else {
69
+ return "".concat((0, exports.resolveValue)(item.items), "[]");
70
+ }
71
+ }
72
+ else {
73
+ throw new Error('All arrays must have an `items` key define');
74
+ }
75
+ };
76
+ /**
77
+ * Return the output type from an object
78
+ */
79
+ var getObject = function (item) {
80
+ if ((0, exports.isReference)(item)) {
81
+ return getRef(item.$ref);
82
+ }
83
+ if (item.allOf) {
84
+ return item.allOf.map(exports.resolveValue).join(' & ');
85
+ }
86
+ if (item.oneOf) {
87
+ return item.oneOf.map(exports.resolveValue).join(' | ');
88
+ }
89
+ if (!item.type && !item.properties && !item.additionalProperties) {
90
+ return '{}';
91
+ }
92
+ // Free form object (https://swagger.io/docs/specification/data-models/data-types/#free-form)
93
+ if (item.type === 'object' &&
94
+ !item.properties &&
95
+ (!item.additionalProperties || item.additionalProperties === true || isEmpty(item.additionalProperties))) {
96
+ return '{[key: string]: any}';
97
+ }
98
+ var IdentifierRegexp = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
99
+ // Consolidation of item.properties & item.additionalProperties
100
+ var output = '{\n';
101
+ if (item.properties) {
102
+ output += Object.entries(item.properties)
103
+ .map(function (_a) {
104
+ var key = _a[0], prop = _a[1];
105
+ var doc = (0, exports.getDocs)(prop);
106
+ var isRequired = (item.required || []).includes(key);
107
+ var processedKey = IdentifierRegexp.test(key) ? key : "\"".concat(key, "\"");
108
+ return "".concat(doc, "\n").concat(processedKey).concat(isRequired ? '' : '?', ": ").concat((0, exports.resolveValue)(prop), ";");
109
+ })
110
+ .join('');
111
+ }
112
+ if (item.additionalProperties) {
113
+ if (item.properties) {
114
+ output += '\n';
115
+ }
116
+ output += "} & { [key: string]: ".concat(item.additionalProperties === true ? 'any' : (0, exports.resolveValue)(item.additionalProperties));
117
+ }
118
+ if (item.properties || item.additionalProperties) {
119
+ if (output === '{\n') {
120
+ return '{}';
121
+ }
122
+ return output + '\n}';
123
+ }
124
+ return item.type === 'object' ? '{[key: string]: any}' : 'any';
125
+ };
126
+ /**
127
+ * Resolve the value of a schema object to a proper type definition.
128
+ */
129
+ var resolveValue = function (schema) {
130
+ return (0, exports.isReference)(schema) ? getRef(schema.$ref) : (0, exports.getScalar)(schema);
131
+ };
132
+ exports.resolveValue = resolveValue;
133
+ /**
134
+ * Format a description to code documentation.
135
+ */
136
+ var formatDescription = function (description) {
137
+ if (!description) {
138
+ return '';
139
+ }
140
+ return "\n/**\n".concat(description
141
+ .split('\n')
142
+ .map(function (i) { return "* ".concat(i); })
143
+ .join('\n'), "\n */");
144
+ };
145
+ exports.formatDescription = formatDescription;
146
+ /**
147
+ * Extract responses / request types from open-api specs
148
+ */
149
+ var getResReqTypes = function (responsesOrRequests) {
150
+ return uniq(responsesOrRequests.map(function (_a) {
151
+ var _ = _a[0], res = _a[1];
152
+ if (!res) {
153
+ return;
154
+ }
155
+ if ((0, exports.isReference)(res)) {
156
+ return getRef(res.$ref);
157
+ }
158
+ if (res.content) {
159
+ for (var _i = 0, _b = Object.keys(res.content); _i < _b.length; _i++) {
160
+ var contentType = _b[_i];
161
+ if (contentType.startsWith('application/json') ||
162
+ contentType.startsWith('application/octet-stream')) {
163
+ var schema = res.content[contentType].schema;
164
+ return (0, exports.resolveValue)(schema);
165
+ }
166
+ }
167
+ return;
168
+ }
169
+ return;
170
+ })).join(' | ');
171
+ };
172
+ exports.getResReqTypes = getResReqTypes;
@@ -0,0 +1,5 @@
1
+ import { OpenAPIObject } from 'openapi3-ts';
2
+ /**
3
+ * Import and parse the openapi spec from a yaml/json
4
+ */
5
+ export declare const convertSwaggerFile: (data: string, extension: 'yaml' | 'json') => Promise<OpenAPIObject>;
@@ -0,0 +1,25 @@
1
+ import { ComponentsObject, OperationObject, ParameterObject, ReferenceObject } from 'openapi3-ts';
2
+ /**
3
+ * Generate a react-query component from openapi operation specs
4
+ */
5
+ export declare const createHook: ({ operation, verb, route, operationIds, parameters, schemasComponents, headerFilters, overrides, }: {
6
+ operation: OperationObject;
7
+ verb: string;
8
+ route: string;
9
+ operationIds: string[];
10
+ parameters: (ReferenceObject | ParameterObject)[] | undefined;
11
+ schemasComponents?: ComponentsObject | undefined;
12
+ headerFilters?: string[] | undefined;
13
+ overrides?: Record<string, {
14
+ type: 'query';
15
+ } | {
16
+ type: 'mutation';
17
+ } | {
18
+ type: 'infiniteQuery';
19
+ infiniteQueryParm: string;
20
+ }> | undefined;
21
+ }) => {
22
+ implementation: string;
23
+ imports: string[];
24
+ queryImports: ("query" | "mutation" | "infiniteQuery")[];
25
+ };
@@ -0,0 +1,7 @@
1
+ export declare const generateImports: ({ schemaName, apiDirectory, queryClientDir, schemaImports, queryImports, }: {
2
+ apiDirectory: string;
3
+ queryClientDir: string;
4
+ schemaName: string;
5
+ schemaImports: string[];
6
+ queryImports: ('query' | 'mutation' | 'infiniteQuery')[];
7
+ }) => string;
@@ -0,0 +1,7 @@
1
+ import { OpenAPIObject } from 'openapi3-ts';
2
+ /**
3
+ * Extract all types from #/components/schemas
4
+ */
5
+ export declare const generateSchemas: ({ spec }: {
6
+ spec: OpenAPIObject;
7
+ }) => string;
@@ -0,0 +1,15 @@
1
+ export declare function importSpecs({ sourceDirectory, exportDirectory, apiDirectory, queryClientDir, headerFilters, overrides, }: {
2
+ sourceDirectory: string;
3
+ exportDirectory: string;
4
+ apiDirectory: string;
5
+ queryClientDir: string;
6
+ headerFilters?: string[];
7
+ overrides?: Record<string, {
8
+ type: 'query';
9
+ } | {
10
+ type: 'mutation';
11
+ } | {
12
+ type: 'infiniteQuery';
13
+ infiniteQueryParm: string;
14
+ }>;
15
+ }): void;
@@ -0,0 +1,3 @@
1
+ import { convertSwaggerFile } from './convertSwaggerFile.js';
2
+ import { importSpecs } from './importSpecs.js';
3
+ export { importSpecs, convertSwaggerFile };
@@ -0,0 +1,24 @@
1
+ import { ReferenceObject, RequestBodyObject, ResponseObject, SchemaObject } from 'openapi3-ts';
2
+ export declare const getDocs: (data: ReferenceObject | {
3
+ description?: string;
4
+ }) => string;
5
+ /**
6
+ * Discriminator helper for `ReferenceObject`
7
+ */
8
+ export declare const isReference: (property: any) => property is ReferenceObject;
9
+ /**
10
+ * Return the typescript equivalent of open-api data type
11
+ */
12
+ export declare const getScalar: (item: SchemaObject) => string;
13
+ /**
14
+ * Resolve the value of a schema object to a proper type definition.
15
+ */
16
+ export declare const resolveValue: (schema: SchemaObject) => string;
17
+ /**
18
+ * Format a description to code documentation.
19
+ */
20
+ export declare const formatDescription: (description?: string) => string;
21
+ /**
22
+ * Extract responses / request types from open-api specs
23
+ */
24
+ export declare const getResReqTypes: (responsesOrRequests: Array<[string, ResponseObject | ReferenceObject | RequestBodyObject]>) => string;
package/package.json CHANGED
@@ -1,43 +1,97 @@
1
1
  {
2
2
  "name": "react-query-lightbase-codegen",
3
- "version": "0.3.0",
3
+ "description": "Fully typed react query code generation tool based on openApi specifications",
4
+ "version": "1.0.1",
4
5
  "license": "MIT",
5
- "main": "./lib/cjs/index.js",
6
- "module": "./lib/esm/index.js",
6
+ "type": "module",
7
+ "exports": "./src/index.js",
7
8
  "files": [
8
- "lib/"
9
+ "src",
10
+ "lib",
11
+ "!**/__tests__",
12
+ "!**/__fixtures__",
13
+ "!**/__mocks__"
14
+ ],
15
+ "keywords": [
16
+ "rest",
17
+ "client",
18
+ "swagger",
19
+ "open-api",
20
+ "fetch",
21
+ "data fetching",
22
+ "code-generation",
23
+ "react",
24
+ "react-query",
25
+ "axios",
26
+ "vue-query",
27
+ "tanstack"
9
28
  ],
29
+ "author": {
30
+ "name": "Oliver Winter",
31
+ "email": "owinter86@gmail.com"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/owinter86/react-query-codegen"
36
+ },
37
+ "engines": {
38
+ "node": ">=14.16"
39
+ },
10
40
  "scripts": {
11
41
  "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
12
42
  "tsc": "tsc -p tsconfig.json && tsc -p tsconfig-cjs.json",
13
- "test": "yarn tsc && node test/script.mjs && eslint . --ext .js,.jsx,.ts,.tsx --fix"
43
+ "test": "node test/script.mjs && prettier --check ./test/generated/**/*.tsx --write && eslint ./test/generated/**/*.tsx --fix",
44
+ "prepare": "bob build"
14
45
  },
15
46
  "dependencies": {
16
- "@tanstack/react-query": "^4.0.9",
17
47
  "axios": "0.27.2",
18
48
  "case": "1.6.3",
19
- "chalk": "4.1.0",
49
+ "chalk": "4.1.2",
20
50
  "js-yaml": "4.1.0",
21
51
  "lodash": "4.17.21",
22
52
  "openapi3-ts": "2.0.2",
23
- "qs": "6.10.3",
24
- "query-string": "7.1.1",
25
53
  "swagger2openapi": "7.0.8",
26
54
  "yamljs": "0.3.0"
27
55
  },
28
56
  "devDependencies": {
29
- "@babel/core": "7.17.10",
57
+ "@babel/core": "7.18.10",
30
58
  "@babel/eslint-parser": "7.17.0",
31
- "@react-native-community/eslint-config": "3.0.2",
59
+ "@commitlint/cli": "^17.0.3",
60
+ "@commitlint/config-conventional": "^17.0.3",
61
+ "@react-native-community/eslint-config": "3.1.0",
62
+ "@semantic-release/changelog": "^6.0.1",
63
+ "@semantic-release/git": "^10.0.1",
64
+ "@semantic-release/github": "^8.0.5",
65
+ "@semantic-release/npm": "^9.0.1",
66
+ "@tanstack/react-query": "4.0.10",
67
+ "@types/js-yaml": "4.0.5",
32
68
  "@types/lodash": "4.14.182",
33
- "@types/node": "17.0.32",
69
+ "@types/node": "18.6.3",
34
70
  "@types/qs": "6.9.7",
35
71
  "@types/query-string": "6.3.0",
36
72
  "@types/yamljs": "0.2.31",
37
- "eslint": "8.15.0",
38
- "eslint-plugin-prettier": "4.0.0",
39
- "prettier": "2.6.2",
73
+ "eslint": "8.21.0",
74
+ "eslint-plugin-prettier": "4.2.1",
75
+ "husky": "^8.0.1",
76
+ "prettier": "2.7.1",
40
77
  "react": "17.0.2",
41
- "typescript": "4.6.4"
42
- }
78
+ "react-native-builder-bob": "^0.18.3",
79
+ "semantic-release": "^19.0.3",
80
+ "typescript": "4.7.4"
81
+ },
82
+ "main": "lib/commonjs/index.js",
83
+ "react-native": "src/index.ts",
84
+ "types": "lib/typescript/src/index.d.ts",
85
+ "react-native-builder-bob": {
86
+ "source": "src",
87
+ "output": "lib",
88
+ "targets": [
89
+ "commonjs",
90
+ "typescript"
91
+ ]
92
+ },
93
+ "eslintIgnore": [
94
+ "node_modules/",
95
+ "lib/"
96
+ ]
43
97
  }
@@ -0,0 +1,25 @@
1
+ import { OpenAPIObject } from 'openapi3-ts';
2
+ import swagger2openapi from 'swagger2openapi';
3
+ import yaml from 'js-yaml';
4
+
5
+ /**
6
+ * Import and parse the openapi spec from a yaml/json
7
+ */
8
+ export const convertSwaggerFile = (data: string, extension: 'yaml' | 'json'): Promise<OpenAPIObject> => {
9
+ const schema = extension === 'yaml' ? yaml.load(data) : JSON.parse(data);
10
+ return new Promise((resolve, reject) => {
11
+ if (!schema.openapi || !schema.openapi.startsWith('3.')) {
12
+ swagger2openapi.convertObj(schema, {}, (err, convertedObj) => {
13
+ if (err) {
14
+ reject(err);
15
+ } else {
16
+ // @ts-ignore
17
+ convertedObj.openapi.basePath = convertedObj.original.basePath;
18
+ resolve(convertedObj.openapi);
19
+ }
20
+ });
21
+ } else {
22
+ resolve(schema);
23
+ }
24
+ });
25
+ };