@onereach/types-contacts-api 2.2.1 → 2.2.2-beta.1634.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.
@@ -43,12 +43,12 @@ export interface ListApiParams {
43
43
  }
44
44
 
45
45
  export interface CreateContactDto {
46
- contact_book: string;
46
+ contact_book?: string;
47
47
  data: FieldValueRequestDto[];
48
48
  }
49
49
 
50
50
  export interface CreateMultipleContactsDto {
51
- contact_book: string;
51
+ contact_book?: string;
52
52
  contacts: ContactRequestDto[];
53
53
  }
54
54
 
@@ -192,7 +192,8 @@ export interface UpsertFieldValueByMachineNameDto {
192
192
 
193
193
  export interface FieldValueRequestDto {
194
194
  value: any;
195
- schemaId: string;
195
+ schemaId?: string;
196
+ machine_name?: string;
196
197
  id?: string;
197
198
  }
198
199
 
@@ -0,0 +1,195 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import {
4
+ ClassDeclaration,
5
+ EnumDeclaration,
6
+ EnumDeclarationStructure,
7
+ ImportDeclaration,
8
+ ImportSpecifierStructure,
9
+ InterfaceDeclaration,
10
+ Project,
11
+ PropertyDeclaration,
12
+ SourceFile,
13
+ TypeAliasDeclaration,
14
+ } from 'ts-morph';
15
+
16
+ const ROOT = path.resolve(__dirname, './');
17
+ const TYPES_DIST = path.resolve(ROOT, 'dist');
18
+ const API_PATH = path.resolve(ROOT, '../api');
19
+ const apiTsconfig = path.resolve(API_PATH, 'tsconfig.json');
20
+ const typesTsconfig = path.resolve(ROOT, 'tsconfig.json');
21
+
22
+ if (fs.existsSync(TYPES_DIST)) {
23
+ fs.rmSync(TYPES_DIST, { recursive: true });
24
+ }
25
+ fs.mkdirSync(TYPES_DIST);
26
+
27
+ const typesProject = new Project({
28
+ tsConfigFilePath: typesTsconfig,
29
+ });
30
+ const apiProject = new Project({
31
+ tsConfigFilePath: apiTsconfig,
32
+ });
33
+
34
+
35
+ const FILE = typesProject.createSourceFile('./dist/index.d.ts');
36
+ const SWAGGER_MOCK = typesProject.getSourceFile('./swagger-type-mock.ts');
37
+
38
+ function generateTypes() {
39
+ FILE.replaceWithText(SWAGGER_MOCK?.getText() || '');
40
+ const [src] = apiProject.getDirectories().filter(dir => dir.getBaseName() === 'src');
41
+ src.getSourceFiles(['**/*.dto.ts']).forEach(sourceFile => {
42
+ sourceFile.getClasses().forEach(classDec => {
43
+ createInterfaceFrom(sourceFile, classDec);
44
+ });
45
+ });
46
+ FILE.formatText({ indentSize: 2 });
47
+ FILE.saveSync();
48
+ }
49
+
50
+ function createInterfaceFrom(
51
+ sourceFile: SourceFile,
52
+ dec: ClassDeclaration | InterfaceDeclaration,
53
+ isExported = true) {
54
+ if (dec && !hasBeenCreatedBefore(dec.getName() as string)) {
55
+ const interfaceDeclaration = FILE.addInterface({
56
+ name: dec.getName() as string,
57
+ });
58
+ const importsDeclarations = sourceFile.getImportDeclarations();
59
+ const structure = dec.getStructure();
60
+ const properties = structure.properties;
61
+
62
+ if (properties?.length) {
63
+ properties.forEach(p => {
64
+ const propertyDec = dec.getProperty(p.name as string) as PropertyDeclaration;
65
+ const importDec = findInImports(importsDeclarations, `${p.type}` as string);
66
+
67
+ if (importDec) {
68
+ sourceFile = importDec.getModuleSpecifierSourceFile() as SourceFile;
69
+ }
70
+
71
+ createByPropertyType(sourceFile, propertyDec);
72
+
73
+ interfaceDeclaration.addProperty({
74
+ name: p.name,
75
+ type: p.type ?? propertyDec.getType().getText(),
76
+ hasQuestionToken: p.hasQuestionToken,
77
+ isReadonly: p.isReadonly,
78
+ });
79
+ });
80
+ }
81
+
82
+ //check if extends is part of import
83
+ const extendsDef = (Array.isArray(structure.extends) ? structure.extends : [structure.extends]) as string[];
84
+ extendsDef.filter(Boolean).forEach((def: string) => {
85
+ //first check if extend has generic
86
+ def = def.replace(/<.*/, '');
87
+ const helperFunc = SWAGGER_MOCK?.getFunctions().map(f => f.getName()) || [];
88
+ // if extend is something like PartialType<SomeClass>
89
+ const hlpFn = (str: string): string => {
90
+ const match = /(\w+)(\(.*\))/.exec(str);
91
+ if (match) {
92
+ const fnName = match[1];
93
+ if (helperFunc.includes(fnName)) {
94
+ let args = match[2].replace(/^\(|\)$/g, '');
95
+ const possibleImports = args.split(',');
96
+ possibleImports.forEach(p => extractInterfaceFromImport(p.trim(), importsDeclarations));
97
+ // tuple to literal
98
+ const toLiteral = args.match(/(\[.*])\s*as\s*const/) || [];
99
+ if (toLiteral.length) {
100
+ const literal = (JSON.parse(toLiteral[1].replace(/'/g, '"')) as string[]).map(i => `'${i}'`).join('|');
101
+ args = args.replace(toLiteral[0] as string, literal);
102
+ }
103
+ return `ReturnType<typeof ${fnName}<${hlpFn(args)}>>`;
104
+ }
105
+ return str;
106
+ }
107
+ return str;
108
+ };
109
+ def = hlpFn(def);
110
+ extractInterfaceFromImport(def, importsDeclarations);
111
+
112
+ //if extends is part of sourceFile
113
+ const innerExtends = [
114
+ sourceFile.getClass(def),
115
+ sourceFile.getInterface(def),
116
+ ].filter(Boolean) as (ClassDeclaration | InterfaceDeclaration)[];
117
+
118
+ innerExtends.filter(Boolean).forEach(innerDef => {
119
+ createInterfaceFrom(sourceFile, innerDef);
120
+ });
121
+
122
+ interfaceDeclaration.addExtends(def);
123
+ });
124
+
125
+ interfaceDeclaration.setIsExported(isExported);
126
+ }
127
+ }
128
+
129
+ function extractInterfaceFromImport(name: string, importsDeclarations: ImportDeclaration[]) {
130
+ const importDec = findInImports(importsDeclarations, name);
131
+ // create interface if needed
132
+ if (importDec) {
133
+ const sourceFile = importDec.getModuleSpecifierSourceFile() as SourceFile;
134
+ createInterfaceFrom(sourceFile, sourceFile.getClass(name) as ClassDeclaration);
135
+ }
136
+ }
137
+
138
+ function createByPropertyType(sourceFile: SourceFile, propDec: PropertyDeclaration) {
139
+ const propType = propDec.getType();
140
+ const type = propDec.getStructure().type as string;
141
+ const typeAlias = sourceFile.getTypeAliases();
142
+
143
+ if (propType?.isInterface()) {
144
+ createInterfaceFrom(sourceFile, sourceFile.getInterface(type) as InterfaceDeclaration);
145
+ }
146
+ if (propType?.isClass()) {
147
+ createInterfaceFrom(sourceFile, sourceFile.getClass(type) as ClassDeclaration);
148
+ }
149
+ if (propType?.isEnum()) {
150
+ addEnum((sourceFile.getEnum(type) as EnumDeclaration).getStructure());
151
+ }
152
+
153
+ if (typeAlias) {
154
+ typeAlias.forEach(addTypes);
155
+ }
156
+ }
157
+
158
+
159
+ function addTypes(type: TypeAliasDeclaration) {
160
+ const structure = type.getStructure();
161
+ if (!FILE.getTypeAlias(structure.name)) {
162
+ FILE.addTypeAlias(type.getStructure())
163
+ .setIsExported(type.isExported());
164
+ }
165
+ }
166
+
167
+ function addEnum(enumDec: EnumDeclarationStructure) {
168
+ if (!FILE.getEnums().some(en => en.getName() === enumDec.name)) {
169
+ FILE.addEnum(enumDec);
170
+ enumDec.isExported = true;
171
+ }
172
+ }
173
+
174
+ function findInImports(imports: ImportDeclaration[], search: string): ImportDeclaration | undefined {
175
+ for (const imp of imports) {
176
+ const structure = imp.getStructure();
177
+ if (structure.defaultImport === search) {
178
+ return imp;
179
+ }
180
+ for (const named of structure.namedImports as ImportSpecifierStructure[]) {
181
+ if (named.name === search || named.alias === search) {
182
+ return imp;
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ /**
189
+ * checks if interface has been created before
190
+ */
191
+ function hasBeenCreatedBefore(interfaceName: string): boolean {
192
+ return FILE.getInterfaces().some(int => int.getName() === interfaceName);
193
+ }
194
+
195
+ generateTypes();
package/package.json CHANGED
@@ -1,15 +1,13 @@
1
1
  {
2
2
  "name": "@onereach/types-contacts-api",
3
3
  "description": "Generated types for Contacts Api",
4
- "version": "2.2.1",
4
+ "version": "2.2.2-beta.1634.0",
5
5
  "author": "OneReach.ai",
6
- "types": "./dist/index.ts",
6
+ "main": "",
7
+ "types": "./dist/index.d.ts",
7
8
  "publishConfig": {
8
9
  "access": "public"
9
10
  },
10
- "files": [
11
- "dist/"
12
- ],
13
11
  "scripts": {
14
12
  "build:types": "ts-node ./generate-types.ts"
15
13
  },
@@ -17,6 +15,5 @@
17
15
  "@types/node": "^18.11.10",
18
16
  "ts-morph": "^17.0.1",
19
17
  "ts-node": "^10.9.1"
20
- },
21
- "gitHead": "efabd933c29083d2e49a86cffa06d0dcb3ae7fff"
18
+ }
22
19
  }
@@ -0,0 +1,4 @@
1
+ declare function OmitType<T, K extends keyof T>(classRef: T, keys: readonly K[]): Omit<T, typeof keys[number]>;
2
+ declare function IntersectionType<A, B>(classARef: A, classBRef: B): A & B;
3
+ declare function PartialType<T>(classRef: T): Partial<T>;
4
+ declare function PickType<T, K extends keyof T>(classRef: T, keys: readonly K[]): Pick<T, typeof keys[number]>;
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "exclude": ["node_modules"],
4
+ "compilerOptions": {
5
+ "module": "commonjs",
6
+ "strictPropertyInitialization": false,
7
+ "emitDecoratorMetadata": true,
8
+ "experimentalDecorators": true,
9
+ "baseUrl": "./",
10
+ "outDir": "dist",
11
+ "types": ["node"]
12
+ }
13
+ }