1#!/usr/bin/env node
2'use strict';
3var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4    if (k2 === undefined) k2 = k;
5    var desc = Object.getOwnPropertyDescriptor(m, k);
6    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7      desc = { enumerable: true, get: function() { return m[k]; } };
8    }
9    Object.defineProperty(o, k2, desc);
10}) : (function(o, m, k, k2) {
11    if (k2 === undefined) k2 = k;
12    o[k2] = m[k];
13}));
14var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15    Object.defineProperty(o, "default", { enumerable: true, value: v });
16}) : function(o, v) {
17    o["default"] = v;
18});
19var __importStar = (this && this.__importStar) || function (mod) {
20    if (mod && mod.__esModule) return mod;
21    var result = {};
22    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23    __setModuleDefault(result, mod);
24    return result;
25};
26var __importDefault = (this && this.__importDefault) || function (mod) {
27    return (mod && mod.__esModule) ? mod : { "default": mod };
28};
29Object.defineProperty(exports, "__esModule", { value: true });
30exports.generateMocks = void 0;
31const fs_1 = __importDefault(require("fs"));
32const path_1 = __importDefault(require("path"));
33const prettier = __importStar(require("prettier"));
34const typescript_1 = __importDefault(require("typescript"));
35const directoryPath = process.cwd();
36function maybeUnwrapSwiftArray(type) {
37    const isArray = type.startsWith('[') && type.endsWith(']');
38    if (!isArray) {
39        return type;
40    }
41    const innerType = type.substring(1, type.length - 1);
42    return innerType;
43}
44function isSwiftArray(type) {
45    return type.startsWith('[') && type.endsWith(']');
46}
47function mapSwiftTypeToTsType(type) {
48    if (!type) {
49        return typescript_1.default.factory.createKeywordTypeNode(typescript_1.default.SyntaxKind.VoidKeyword);
50    }
51    if (isSwiftArray(type)) {
52        return typescript_1.default.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));
53    }
54    switch (type) {
55        case 'unknown':
56            return typescript_1.default.factory.createKeywordTypeNode(typescript_1.default.SyntaxKind.AnyKeyword);
57        case 'String':
58            return typescript_1.default.factory.createKeywordTypeNode(typescript_1.default.SyntaxKind.StringKeyword);
59        case 'Bool':
60            return typescript_1.default.factory.createKeywordTypeNode(typescript_1.default.SyntaxKind.BooleanKeyword);
61        case 'Int':
62        case 'Float':
63        case 'Double':
64            return typescript_1.default.factory.createKeywordTypeNode(typescript_1.default.SyntaxKind.NumberKeyword);
65        default:
66            return typescript_1.default.factory.createTypeReferenceNode(type);
67    }
68}
69function getMockReturnStatements(tsReturnType) {
70    if (!tsReturnType) {
71        return [];
72    }
73    switch (tsReturnType.kind) {
74        case typescript_1.default.SyntaxKind.AnyKeyword:
75            return [typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createNull())];
76        case typescript_1.default.SyntaxKind.StringKeyword:
77            return [typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createStringLiteral(''))];
78        case typescript_1.default.SyntaxKind.BooleanKeyword:
79            return [typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createFalse())];
80        case typescript_1.default.SyntaxKind.NumberKeyword:
81            return [typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createNumericLiteral('0'))];
82        case typescript_1.default.SyntaxKind.VoidKeyword:
83            return [];
84        case typescript_1.default.SyntaxKind.ArrayType:
85            return [typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createArrayLiteralExpression())];
86    }
87    return [];
88}
89function wrapWithAsync(tsType) {
90    return typescript_1.default.factory.createTypeReferenceNode('Promise', [tsType]);
91}
92function getMockedFunctions(functions, async = false) {
93    return functions.map((fnStructure) => {
94        const name = typescript_1.default.factory.createIdentifier(fnStructure.name);
95        const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);
96        const func = typescript_1.default.factory.createFunctionDeclaration([
97            typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword),
98            async ? typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.AsyncKeyword) : undefined,
99        ].filter((f) => !!f), undefined, name, undefined, fnStructure?.types?.parameters.map((p) => typescript_1.default.factory.createParameterDeclaration(undefined, undefined, p.name, undefined, mapSwiftTypeToTsType(p.typename), undefined)) ?? [], async ? wrapWithAsync(returnType) : returnType, typescript_1.default.factory.createBlock(getMockReturnStatements(returnType), true));
100        return func;
101    });
102}
103function getTypesToMock(module) {
104    const foundTypes = [];
105    Object.values(module)
106        .flatMap((t) => (Array.isArray(t) ? t?.map((t2) => t2?.types) : [] ?? []))
107        .forEach((types) => {
108        types?.parameters.forEach(({ typename }) => {
109            foundTypes.push(maybeUnwrapSwiftArray(typename));
110        });
111        types?.returnType && foundTypes.push(maybeUnwrapSwiftArray(types.returnType));
112    });
113    return new Set(foundTypes.filter((ft) => mapSwiftTypeToTsType(ft).kind === typescript_1.default.SyntaxKind.TypeReference));
114}
115function getMockedTypes(types) {
116    return Array.from(types).map((type) => {
117        const name = typescript_1.default.factory.createIdentifier(type);
118        const typeAlias = typescript_1.default.factory.createTypeAliasDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], name, undefined, typescript_1.default.factory.createKeywordTypeNode(typescript_1.default.SyntaxKind.AnyKeyword));
119        return typeAlias;
120    });
121}
122function getMockForModule(module) {
123    return [].concat(getMockedTypes(getTypesToMock(module)), getMockedFunctions(module.functions), getMockedFunctions(module.asyncFunctions, true));
124}
125async function generateMocks(modules) {
126    const printer = typescript_1.default.createPrinter({ newLine: typescript_1.default.NewLineKind.LineFeed });
127    for (const m of modules) {
128        const resultFile = typescript_1.default.createSourceFile(m.name + '.ts', '', typescript_1.default.ScriptTarget.Latest, false, typescript_1.default.ScriptKind.TSX);
129        fs_1.default.mkdirSync(path_1.default.join(directoryPath, 'mocks'), { recursive: true });
130        const filePath = path_1.default.join(directoryPath, 'mocks', m.name + '.ts');
131        // get ts nodearray from getMockForModule(m) array
132        const mock = typescript_1.default.factory.createNodeArray(getMockForModule(m));
133        const printedTs = printer.printList(typescript_1.default.ListFormat.MultiLine, mock, resultFile);
134        const compiledJs = typescript_1.default.transpileModule(printedTs, {
135            compilerOptions: { module: typescript_1.default.ModuleKind.ESNext, target: typescript_1.default.ScriptTarget.ESNext },
136        }).outputText;
137        const prettyJs = await prettier.format(compiledJs, {
138            parser: 'babel',
139            tabWidth: 2,
140            singleQuote: true,
141        });
142        fs_1.default.writeFileSync(filePath, prettyJs);
143    }
144}
145exports.generateMocks = generateMocks;
146//# sourceMappingURL=mockgen.js.map