expo-modules-test-core 0.18.1-canary-20240904-69100c1 → 0.18.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.
@@ -1,7 +1,7 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
3
  group = 'org.unimodules'
4
- version = '0.18.0'
4
+ version = '0.18.1'
5
5
 
6
6
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
7
  apply from: expoModulesCorePlugin
@@ -14,21 +14,42 @@ android {
14
14
  namespace "org.unimodules.test.core"
15
15
  defaultConfig {
16
16
  versionCode 3
17
- versionName '0.18.0'
17
+ versionName '0.18.1'
18
18
  }
19
- packaging {
20
- exclude 'META-INF/LICENSE-notice.md'
21
- exclude 'META-INF/LICENSE.md'
19
+ packagingOptions {
20
+ resources {
21
+ excludes += [
22
+ 'META-INF/LICENSE.md',
23
+ 'META-INF/LICENSE-notice.md',
24
+ ]
25
+ }
22
26
  }
23
27
  }
24
28
 
25
29
  dependencies {
26
30
  api 'androidx.test:core:1.5.0'
27
31
  api 'junit:junit:4.13.2'
28
- api 'io.mockk:mockk:1.13.5'
29
- api "org.robolectric:robolectric:4.10"
32
+ api('io.mockk:mockk:1.13.5') {
33
+ // jupiter is junit 5 which we don't use
34
+ exclude group: 'org.junit.jupiter'
35
+ }
36
+ api ("org.robolectric:robolectric:4.11.1") {
37
+ // Duplicate class bcprov-jdk15to18-1.78.1.jar and bcprov-jdk18on-1.78.1.jar
38
+ // Exclude the conflicting jdk18on version, so that jdk15to18 is used
39
+ exclude group: 'org.bouncycastle', module: 'bcprov-jdk18on'
40
+ }
41
+ // specify a version of Bouncy Castle - used in robolectric and androidx.room (expo-updates)
42
+ implementation 'org.bouncycastle:bcprov-jdk15to18:1.78.1'
43
+ testImplementation 'org.bouncycastle:bcprov-jdk15to18:1.78.1'
30
44
 
31
45
  implementation 'com.facebook.react:react-android'
32
46
 
33
47
  implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion()}"
48
+
49
+ // instrumented testing dependencies
50
+ api 'androidx.test.ext:junit:1.1.5'
51
+ api 'androidx.test:runner:1.5.2'
52
+ api 'androidx.test:rules:1.5.0'
53
+ api "com.google.truth:truth:1.1.2"
54
+ api "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
34
55
  }
@@ -3,7 +3,7 @@ package expo.modules.test.core.legacy
3
3
  import android.content.Context
4
4
  import android.os.Bundle
5
5
  import androidx.test.core.app.ApplicationProvider
6
- import com.facebook.react.bridge.BridgeReactContext
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
7
  import expo.modules.core.interfaces.services.EventEmitter
8
8
  import expo.modules.kotlin.AppContext
9
9
  import expo.modules.kotlin.ModuleHolder
@@ -119,7 +119,7 @@ data class ModuleMock<TestInterfaceType : Any, ModuleType : Module>(
119
119
  }
120
120
 
121
121
  private fun prepareMockAppContext(customAppContext: AppContext?): AppContext {
122
- val reactContext = BridgeReactContext(ApplicationProvider.getApplicationContext<Context>())
122
+ val reactContext = ReactApplicationContext(ApplicationProvider.getApplicationContext<Context>())
123
123
  val appContext = customAppContext ?: AppContext(
124
124
  modulesProvider = mockk(relaxed = true),
125
125
  legacyModuleRegistry = mockk(relaxed = true),
@@ -1 +1 @@
1
- {"version":3,"file":"getStructure.d.ts","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAuQjB,wBAAgB,mCAAmC,6BAGlD"}
1
+ {"version":3,"file":"getStructure.d.ts","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,sBAAsB,EAGvB,MAAM,SAAS,CAAC;AA8PjB,wBAAgB,mCAAmC,6BAGlD"}
@@ -166,29 +166,27 @@ function findGroupedDefinitionsOfType(type, moduleDefinition, file) {
166
166
  return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));
167
167
  });
168
168
  }
169
- function findAndParseNestedClassesOfType(moduleDefinition, file, type) {
170
- // we support reading definitions from closure only
171
- const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);
172
- return definitionsOfType
173
- .map((df) => {
174
- const nestedModuleDefinition = df['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.['key.substructure'];
175
- if (!nestedModuleDefinition) {
176
- console.warn('Could not parse definition');
177
- return null;
178
- }
179
- const name = getIdentifierFromOffsetObject(df['key.substructure']?.[0], file).replace('.self', '');
180
- // let's drop nested view field and classes (are null anyways)
181
- const { views: _, classes: _2, ...definition } = parseModuleDefinition(nestedModuleDefinition, file);
182
- return { ...definition, name };
183
- })
184
- .flatMap((f) => (f ? [f] : []));
169
+ function findAndParseView(moduleDefinition, file) {
170
+ const viewDefinition = moduleDefinition.find((md) => md['key.name'] === 'View');
171
+ if (!viewDefinition) {
172
+ return null;
173
+ }
174
+ // we support reading view definitions from closure only
175
+ const viewModuleDefinition = viewDefinition['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.['key.substructure'];
176
+ if (!viewModuleDefinition) {
177
+ console.warn('Could not parse view definition');
178
+ return null;
179
+ }
180
+ // let's drop nested view field (is null anyways)
181
+ const { view: _, ...definition } = parseModuleDefinition(viewModuleDefinition, file);
182
+ return definition;
185
183
  }
186
184
  function omitParamsFromClosureArguments(definitions, paramsToOmit) {
187
185
  return definitions.map((d) => ({
188
186
  ...d,
189
187
  types: {
190
188
  ...d.types,
191
- parameters: d.types?.parameters?.filter((t, idx) => !paramsToOmit.includes(t.name)) ?? [],
189
+ parameters: d.types?.parameters?.filter((t, idx) => idx !== 0 && !paramsToOmit.includes(t.name)) ?? [],
192
190
  },
193
191
  }));
194
192
  }
@@ -208,8 +206,7 @@ function parseModuleDefinition(moduleDefinition, file) {
208
206
  events: findGroupedDefinitionsOfType('Events', preparedModuleDefinition, file),
209
207
  properties: findNamedDefinitionsOfType('Property', preparedModuleDefinition, file),
210
208
  props: omitParamsFromClosureArguments(findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file), ['view']),
211
- views: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'View'),
212
- classes: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'Class'),
209
+ view: findAndParseView(preparedModuleDefinition, file),
213
210
  };
214
211
  return parsedDefinition;
215
212
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getStructure.js","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"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","sourcesContent":["// convert requires above to imports\nimport { execSync } from 'child_process';\nimport fsNode from 'fs';\nimport { globSync } from 'glob';\nimport XML from 'xml-js';\nimport YAML from 'yaml';\n\nimport {\n Closure,\n CursorInfoOutput,\n FileType,\n FullyAnnotatedDecl,\n OutputModuleDefinition,\n Structure,\n} from './types';\n\nconst rootDir = process.cwd();\nconst pattern = `${rootDir}/**/*.swift`;\n\nfunction getStructureFromFile(file: FileType) {\n const command = 'sourcekitten structure --file ' + file.path;\n\n try {\n const output = execSync(command);\n return JSON.parse(output.toString());\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n}\n// find an object with \"key.typename\" : \"ModuleDefinition\" somewhere in the structure and return it\nfunction findModuleDefinitionInStructure(structure: Structure): Structure[] | null {\n if (!structure) {\n return null;\n }\n if (structure?.['key.typename'] === 'ModuleDefinition') {\n const root = structure?.['key.substructure'];\n if (!root) {\n console.warn('Found ModuleDefinition but it is malformed');\n }\n return root;\n }\n const substructure = structure['key.substructure'];\n if (Array.isArray(substructure) && substructure.length > 0) {\n for (const child of substructure) {\n let result = null;\n result = findModuleDefinitionInStructure(child);\n if (result) {\n return result;\n }\n }\n }\n return null;\n}\n\n// Read string straight from file – needed since we can't get cursorinfo for modulename\nfunction getIdentifierFromOffsetObject(offsetObject: Structure, file: FileType) {\n // adding 1 and removing 1 to get rid of quotes\n return file.content\n .substring(offsetObject['key.offset'], offsetObject['key.offset'] + offsetObject['key.length'])\n .replaceAll('\"', '');\n}\n\nfunction maybeUnwrapXMLStructs(type: string | Partial<{ _text: string; 'ref.struct': string }>) {\n if (!type) {\n return type;\n }\n if (typeof type === 'string') {\n return type;\n }\n if (type['_text']) {\n return type['_text'];\n }\n if (type['ref.struct']) {\n return maybeUnwrapXMLStructs(type['ref.struct']);\n }\n return type;\n}\n\nfunction maybeWrapArray<T>(itemOrItems: T[] | T | null) {\n if (!itemOrItems) {\n return null;\n }\n if (Array.isArray(itemOrItems)) {\n return itemOrItems;\n } else {\n return [itemOrItems];\n }\n}\n\nfunction parseXMLAnnotatedDeclarations(cursorInfoOutput: CursorInfoOutput) {\n const xml = cursorInfoOutput['key.fully_annotated_decl'];\n if (!xml) {\n return null;\n }\n const parsed = XML.xml2js(xml, { compact: true }) as FullyAnnotatedDecl;\n\n const parameters =\n maybeWrapArray(parsed?.['decl.function.free']?.['decl.var.parameter'])?.map((p) => ({\n name: maybeUnwrapXMLStructs(p['decl.var.parameter.argument_label']),\n typename: maybeUnwrapXMLStructs(p['decl.var.parameter.type']),\n })) ?? [];\n const returnType = maybeUnwrapXMLStructs(\n parsed?.['decl.function.free']?.['decl.function.returntype']\n );\n return { parameters, returnType };\n}\n\nlet cachedSDKPath: string | null = null;\nfunction getSDKPath() {\n if (cachedSDKPath) {\n return cachedSDKPath;\n }\n const sdkPath = execSync('xcrun --sdk iphoneos --show-sdk-path').toString().trim();\n cachedSDKPath = sdkPath;\n return cachedSDKPath;\n}\n\n// Read type description with sourcekitten, works only for variables\nfunction getTypeFromOffsetObject(offsetObject: Structure, file: FileType) {\n if (!offsetObject) {\n return null;\n }\n const request = {\n 'key.request': 'source.request.cursorinfo',\n 'key.sourcefile': file.path,\n 'key.offset': offsetObject['key.offset'],\n 'key.compilerargs': [file.path, '-target', 'arm64-apple-ios', '-sdk', getSDKPath()],\n };\n const yamlRequest = YAML.stringify(request, {\n defaultStringType: 'QUOTE_DOUBLE',\n lineWidth: 0,\n defaultKeyType: 'PLAIN',\n // needed since behaviour of sourcekitten is not consistent\n } as any).replace('\"source.request.cursorinfo\"', 'source.request.cursorinfo');\n\n const command = 'sourcekitten request --yaml \"' + yamlRequest.replaceAll('\"', '\\\\\"') + '\"';\n try {\n const output = execSync(command, { stdio: 'pipe' });\n return parseXMLAnnotatedDeclarations(JSON.parse(output.toString()));\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n return null;\n}\n\nfunction hasSubstructure(structureObject: Structure) {\n return structureObject?.['key.substructure'] && structureObject['key.substructure'].length > 0;\n}\n\nfunction parseClosureTypes(structureObject: Structure) {\n const closure = structureObject['key.substructure']?.find(\n (s) => s['key.kind'] === 'source.lang.swift.expr.closure'\n );\n if (!closure) {\n return null;\n }\n const parameters = closure['key.substructure']\n ?.filter((s) => s['key.kind'] === 'source.lang.swift.decl.var.parameter')\n .map((p) => ({ name: p['key.name'], typename: p['key.typename'] }));\n\n const returnType = closure?.['key.typename'] ?? 'unknown';\n return { parameters, returnType };\n}\n\n// Used for functions,async functions, all of shape Identifier(name, closure or function)\nfunction findNamedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.map((d) => {\n const definitionParams = d['key.substructure'];\n const name = getIdentifierFromOffsetObject(definitionParams[0], file);\n let types = null;\n if (hasSubstructure(definitionParams[1])) {\n types = parseClosureTypes(definitionParams[1]);\n } else {\n types = getTypeFromOffsetObject(definitionParams[1], file);\n }\n return { name, types };\n });\n}\n\n// Used for events\nfunction findGroupedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.flatMap((d) => {\n const definitionParams = d['key.substructure'];\n return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));\n });\n}\nfunction findAndParseNestedClassesOfType(\n moduleDefinition: Structure[],\n file: FileType,\n type: string\n) {\n // we support reading definitions from closure only\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType\n .map((df) => {\n const nestedModuleDefinition =\n df['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.[\n 'key.substructure'\n ];\n if (!nestedModuleDefinition) {\n console.warn('Could not parse definition');\n return null;\n }\n const name = getIdentifierFromOffsetObject(df['key.substructure']?.[0], file).replace(\n '.self',\n ''\n );\n // let's drop nested view field and classes (are null anyways)\n const {\n views: _,\n classes: _2,\n ...definition\n } = parseModuleDefinition(nestedModuleDefinition, file);\n return { ...definition, name };\n })\n .flatMap((f) => (f ? [f] : []));\n}\n\nfunction omitParamsFromClosureArguments<T extends Closure>(\n definitions: T[],\n paramsToOmit: string[]\n) {\n return definitions.map((d) => ({\n ...d,\n types: {\n ...d.types,\n parameters: d.types?.parameters?.filter((t, idx) => !paramsToOmit.includes(t.name)) ?? [],\n },\n }));\n}\n\n// Some blocks have additional modifiers like runOnQueue – we may need to do additional traversing to get to the function definition\nfunction parseBlockModifiers(structureObject: Structure) {\n if (structureObject['key.name']?.includes('runOnQueue')) {\n return structureObject['key.substructure'][0];\n }\n return structureObject;\n}\n\nfunction parseModuleDefinition(\n moduleDefinition: Structure[],\n file: FileType\n): OutputModuleDefinition {\n const preparedModuleDefinition = moduleDefinition.map(parseBlockModifiers);\n const parsedDefinition = {\n name: findNamedDefinitionsOfType('Name', preparedModuleDefinition, file)?.[0]?.name,\n functions: findNamedDefinitionsOfType('Function', preparedModuleDefinition, file),\n asyncFunctions: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('AsyncFunction', preparedModuleDefinition, file),\n ['promise']\n ),\n events: findGroupedDefinitionsOfType('Events', preparedModuleDefinition, file),\n properties: findNamedDefinitionsOfType('Property', preparedModuleDefinition, file),\n props: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file),\n ['view']\n ),\n views: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'View'),\n classes: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'Class'),\n };\n return parsedDefinition;\n}\n\nfunction findModuleDefinitionsInFiles(files: string[]) {\n const modules = [];\n for (const path of files) {\n const file = { path, content: fsNode.readFileSync(path, 'utf8') };\n const definition = findModuleDefinitionInStructure(getStructureFromFile(file));\n if (definition) {\n modules.push(parseModuleDefinition(definition, file));\n }\n }\n return modules;\n}\n\nexport function getAllExpoModulesInWorkingDirectory() {\n const files = globSync(pattern);\n return findModuleDefinitionsInFiles(files);\n}\n"]}
1
+ {"version":3,"file":"getStructure.js","sourceRoot":"","sources":["../src/getStructure.ts"],"names":[],"mappings":"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","sourcesContent":["// convert requires above to imports\nimport { execSync } from 'child_process';\nimport fsNode from 'fs';\nimport { globSync } from 'glob';\nimport XML from 'xml-js';\nimport YAML from 'yaml';\n\nimport {\n Closure,\n CursorInfoOutput,\n FileType,\n FullyAnnotatedDecl,\n OutputModuleDefinition,\n OutputViewDefinition,\n Structure,\n} from './types';\n\nconst rootDir = process.cwd();\nconst pattern = `${rootDir}/**/*.swift`;\n\nfunction getStructureFromFile(file: FileType) {\n const command = 'sourcekitten structure --file ' + file.path;\n\n try {\n const output = execSync(command);\n return JSON.parse(output.toString());\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n}\n// find an object with \"key.typename\" : \"ModuleDefinition\" somewhere in the structure and return it\nfunction findModuleDefinitionInStructure(structure: Structure): Structure[] | null {\n if (!structure) {\n return null;\n }\n if (structure?.['key.typename'] === 'ModuleDefinition') {\n const root = structure?.['key.substructure'];\n if (!root) {\n console.warn('Found ModuleDefinition but it is malformed');\n }\n return root;\n }\n const substructure = structure['key.substructure'];\n if (Array.isArray(substructure) && substructure.length > 0) {\n for (const child of substructure) {\n let result = null;\n result = findModuleDefinitionInStructure(child);\n if (result) {\n return result;\n }\n }\n }\n return null;\n}\n\n// Read string straight from file – needed since we can't get cursorinfo for modulename\nfunction getIdentifierFromOffsetObject(offsetObject: Structure, file: FileType) {\n // adding 1 and removing 1 to get rid of quotes\n return file.content\n .substring(offsetObject['key.offset'], offsetObject['key.offset'] + offsetObject['key.length'])\n .replaceAll('\"', '');\n}\n\nfunction maybeUnwrapXMLStructs(type: string | Partial<{ _text: string; 'ref.struct': string }>) {\n if (!type) {\n return type;\n }\n if (typeof type === 'string') {\n return type;\n }\n if (type['_text']) {\n return type['_text'];\n }\n if (type['ref.struct']) {\n return maybeUnwrapXMLStructs(type['ref.struct']);\n }\n return type;\n}\n\nfunction maybeWrapArray<T>(itemOrItems: T[] | T | null) {\n if (!itemOrItems) {\n return null;\n }\n if (Array.isArray(itemOrItems)) {\n return itemOrItems;\n } else {\n return [itemOrItems];\n }\n}\n\nfunction parseXMLAnnotatedDeclarations(cursorInfoOutput: CursorInfoOutput) {\n const xml = cursorInfoOutput['key.fully_annotated_decl'];\n if (!xml) {\n return null;\n }\n const parsed = XML.xml2js(xml, { compact: true }) as FullyAnnotatedDecl;\n\n const parameters =\n maybeWrapArray(parsed?.['decl.function.free']?.['decl.var.parameter'])?.map((p) => ({\n name: maybeUnwrapXMLStructs(p['decl.var.parameter.argument_label']),\n typename: maybeUnwrapXMLStructs(p['decl.var.parameter.type']),\n })) ?? [];\n const returnType = maybeUnwrapXMLStructs(\n parsed?.['decl.function.free']?.['decl.function.returntype']\n );\n return { parameters, returnType };\n}\n\nlet cachedSDKPath: string | null = null;\nfunction getSDKPath() {\n if (cachedSDKPath) {\n return cachedSDKPath;\n }\n const sdkPath = execSync('xcrun --sdk iphoneos --show-sdk-path').toString().trim();\n cachedSDKPath = sdkPath;\n return cachedSDKPath;\n}\n\n// Read type description with sourcekitten, works only for variables\nfunction getTypeFromOffsetObject(offsetObject: Structure, file: FileType) {\n if (!offsetObject) {\n return null;\n }\n const request = {\n 'key.request': 'source.request.cursorinfo',\n 'key.sourcefile': file.path,\n 'key.offset': offsetObject['key.offset'],\n 'key.compilerargs': [file.path, '-target', 'arm64-apple-ios', '-sdk', getSDKPath()],\n };\n const yamlRequest = YAML.stringify(request, {\n defaultStringType: 'QUOTE_DOUBLE',\n lineWidth: 0,\n defaultKeyType: 'PLAIN',\n // needed since behaviour of sourcekitten is not consistent\n } as any).replace('\"source.request.cursorinfo\"', 'source.request.cursorinfo');\n\n const command = 'sourcekitten request --yaml \"' + yamlRequest.replaceAll('\"', '\\\\\"') + '\"';\n try {\n const output = execSync(command, { stdio: 'pipe' });\n return parseXMLAnnotatedDeclarations(JSON.parse(output.toString()));\n } catch (error) {\n console.error('An error occurred while executing the command:', error);\n }\n return null;\n}\n\nfunction hasSubstructure(structureObject: Structure) {\n return structureObject?.['key.substructure'] && structureObject['key.substructure'].length > 0;\n}\n\nfunction parseClosureTypes(structureObject: Structure) {\n const closure = structureObject['key.substructure']?.find(\n (s) => s['key.kind'] === 'source.lang.swift.expr.closure'\n );\n if (!closure) {\n return null;\n }\n const parameters = closure['key.substructure']\n ?.filter((s) => s['key.kind'] === 'source.lang.swift.decl.var.parameter')\n .map((p) => ({ name: p['key.name'], typename: p['key.typename'] }));\n\n const returnType = closure?.['key.typename'] ?? 'unknown';\n return { parameters, returnType };\n}\n\n// Used for functions,async functions, all of shape Identifier(name, closure or function)\nfunction findNamedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.map((d) => {\n const definitionParams = d['key.substructure'];\n const name = getIdentifierFromOffsetObject(definitionParams[0], file);\n let types = null;\n if (hasSubstructure(definitionParams[1])) {\n types = parseClosureTypes(definitionParams[1]);\n } else {\n types = getTypeFromOffsetObject(definitionParams[1], file);\n }\n return { name, types };\n });\n}\n\n// Used for events\nfunction findGroupedDefinitionsOfType(type: string, moduleDefinition: Structure[], file: FileType) {\n const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);\n return definitionsOfType.flatMap((d) => {\n const definitionParams = d['key.substructure'];\n return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));\n });\n}\n\nfunction findAndParseView(\n moduleDefinition: Structure[],\n file: FileType\n): null | OutputViewDefinition {\n const viewDefinition = moduleDefinition.find((md) => md['key.name'] === 'View');\n if (!viewDefinition) {\n return null;\n }\n // we support reading view definitions from closure only\n const viewModuleDefinition =\n viewDefinition['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.[\n 'key.substructure'\n ];\n if (!viewModuleDefinition) {\n console.warn('Could not parse view definition');\n return null;\n }\n // let's drop nested view field (is null anyways)\n const { view: _, ...definition } = parseModuleDefinition(viewModuleDefinition, file);\n return definition;\n}\n\nfunction omitParamsFromClosureArguments<T extends Closure>(\n definitions: T[],\n paramsToOmit: string[]\n) {\n return definitions.map((d) => ({\n ...d,\n types: {\n ...d.types,\n parameters:\n d.types?.parameters?.filter((t, idx) => idx !== 0 && !paramsToOmit.includes(t.name)) ?? [],\n },\n }));\n}\n\n// Some blocks have additional modifiers like runOnQueue – we may need to do additional traversing to get to the function definition\nfunction parseBlockModifiers(structureObject: Structure) {\n if (structureObject['key.name']?.includes('runOnQueue')) {\n return structureObject['key.substructure'][0];\n }\n return structureObject;\n}\n\nfunction parseModuleDefinition(\n moduleDefinition: Structure[],\n file: FileType\n): OutputModuleDefinition {\n const preparedModuleDefinition = moduleDefinition.map(parseBlockModifiers);\n const parsedDefinition = {\n name: findNamedDefinitionsOfType('Name', preparedModuleDefinition, file)?.[0]?.name,\n functions: findNamedDefinitionsOfType('Function', preparedModuleDefinition, file),\n asyncFunctions: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('AsyncFunction', preparedModuleDefinition, file),\n ['promise']\n ),\n events: findGroupedDefinitionsOfType('Events', preparedModuleDefinition, file),\n properties: findNamedDefinitionsOfType('Property', preparedModuleDefinition, file),\n props: omitParamsFromClosureArguments(\n findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file),\n ['view']\n ),\n view: findAndParseView(preparedModuleDefinition, file),\n };\n return parsedDefinition;\n}\n\nfunction findModuleDefinitionsInFiles(files: string[]) {\n const modules = [];\n for (const path of files) {\n const file = { path, content: fsNode.readFileSync(path, 'utf8') };\n const definition = findModuleDefinitionInStructure(getStructureFromFile(file));\n if (definition) {\n modules.push(parseModuleDefinition(definition, file));\n }\n }\n return modules;\n}\n\nexport function getAllExpoModulesInWorkingDirectory() {\n const files = globSync(pattern);\n return findModuleDefinitionsInFiles(files);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mockgen.d.ts","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":";AAQA,OAAO,EAGL,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AA2bjB,wBAAsB,aAAa,CACjC,OAAO,EAAE,sBAAsB,EAAE,EACjC,cAAc,GAAE,YAAY,GAAG,YAA2B,iBAqC3D"}
1
+ {"version":3,"file":"mockgen.d.ts","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":";AAQA,OAAO,EAAyB,sBAAsB,EAAwB,MAAM,SAAS,CAAC;AAgW9F,wBAAsB,aAAa,CACjC,OAAO,EAAE,sBAAsB,EAAE,EACjC,cAAc,GAAE,YAAY,GAAG,YAA2B,iBAqC3D"}
package/build/mockgen.js CHANGED
@@ -67,17 +67,6 @@ function isSwiftDictionary(type) {
67
67
  type.endsWith(']') &&
68
68
  findRootColonInDictionary(type.substring(1, type.length - 1)) >= 0);
69
69
  }
70
- function isEither(type) {
71
- return type.startsWith('Either<');
72
- }
73
- // "Either<TypeOne, TypeTwo>" -> ["TypeOne", "TypeTwo"]
74
- function maybeUnwrapEither(type) {
75
- if (!isEither(type)) {
76
- return [type];
77
- }
78
- const innerType = type.substring(7, type.length - 1);
79
- return innerType.split(',').map((t) => t.trim());
80
- }
81
70
  /*
82
71
  The Swift object type can have nested objects as the type of it's values (or maybe even keys).
83
72
  [String: [String: Any]]
@@ -134,10 +123,6 @@ function mapSwiftTypeToTsType(type) {
134
123
  if (isSwiftArray(type)) {
135
124
  return typescript_1.default.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));
136
125
  }
137
- // Custom handling for the Either convertible
138
- if (isEither(type)) {
139
- return typescript_1.default.factory.createUnionTypeNode(maybeUnwrapEither(type).map((t) => mapSwiftTypeToTsType(t)));
140
- }
141
126
  switch (type) {
142
127
  // Our custom representation for types that we have no type hints for. Not necessairly Swift any.
143
128
  case 'unknown':
@@ -180,6 +165,9 @@ function getMockLiterals(tsReturnType) {
180
165
  case typescript_1.default.SyntaxKind.TypeLiteral:
181
166
  // handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one
182
167
  return typescript_1.default.factory.createObjectLiteralExpression([], false);
168
+ case typescript_1.default.SyntaxKind.TypeReference:
169
+ // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
170
+ return typescript_1.default.addSyntheticTrailingComment(typescript_1.default.factory.createNull(), typescript_1.default.SyntaxKind.SingleLineCommentTrivia, ` TODO: Replace with mock for value of type ${tsReturnType?.typeName?.escapedText ?? ''}.`);
183
171
  }
184
172
  return undefined;
185
173
  }
@@ -190,30 +178,19 @@ function maybeWrapWithReturnStatement(tsType) {
190
178
  if (tsType.kind === typescript_1.default.SyntaxKind.AnyKeyword || tsType.kind === typescript_1.default.SyntaxKind.VoidKeyword) {
191
179
  return [];
192
180
  }
193
- if (tsType.kind === typescript_1.default.SyntaxKind.TypeReference) {
194
- // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
195
- return [
196
- typescript_1.default.addSyntheticTrailingComment(typescript_1.default.factory.createReturnStatement(typescript_1.default.factory.createNull()), typescript_1.default.SyntaxKind.SingleLineCommentTrivia, ` TODO: Replace with mock for value of type ${tsType?.typeName?.escapedText ?? ''}.`),
197
- ];
198
- }
199
181
  return [typescript_1.default.factory.createReturnStatement(getMockLiterals(tsType))];
200
182
  }
201
183
  /*
202
184
  We iterate over a list of functions and we create TS AST for each of them.
203
185
  */
204
- function getMockedFunctions(functions, { async = false, classMethod = false } = {}) {
186
+ function getMockedFunctions(functions, async = false) {
205
187
  return functions.map((fnStructure) => {
206
188
  const name = typescript_1.default.factory.createIdentifier(fnStructure.name);
207
189
  const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);
208
- const parameters = fnStructure?.types?.parameters.map((p) => typescript_1.default.factory.createParameterDeclaration(undefined, undefined, p.name ?? '_', undefined, mapSwiftTypeToTsType(p.typename), undefined)) ?? [];
209
- const returnBlock = typescript_1.default.factory.createBlock(maybeWrapWithReturnStatement(returnType), true);
210
- if (classMethod) {
211
- return typescript_1.default.factory.createMethodDeclaration([async ? typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.AsyncKeyword) : undefined].flatMap((f) => f ? [f] : []), undefined, name, undefined, undefined, parameters, async ? wrapWithAsync(returnType) : returnType, returnBlock);
212
- }
213
190
  const func = typescript_1.default.factory.createFunctionDeclaration([
214
191
  typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword),
215
192
  async ? typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.AsyncKeyword) : undefined,
216
- ].flatMap((f) => (f ? [f] : [])), undefined, name, undefined, parameters, async ? wrapWithAsync(returnType) : returnType, returnBlock);
193
+ ].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(maybeWrapWithReturnStatement(returnType), true));
217
194
  return func;
218
195
  });
219
196
  }
@@ -261,8 +238,14 @@ and works out of the box with the expo jest preset.
261
238
  function getPrefix() {
262
239
  return [typescript_1.default.factory.createJSDocComment(prefix)];
263
240
  }
264
- function generatePropTypesForDefinition(definition) {
265
- return typescript_1.default.factory.createTypeAliasDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], 'ViewProps', undefined, typescript_1.default.factory.createTypeLiteralNode([
241
+ /*
242
+ Generate a mock for view props and functions.
243
+ */
244
+ function getMockedView(definition) {
245
+ if (!definition) {
246
+ return [];
247
+ }
248
+ const propsType = typescript_1.default.factory.createTypeAliasDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], 'ViewProps', undefined, typescript_1.default.factory.createTypeLiteralNode([
266
249
  ...definition.props.map((p) => {
267
250
  const propType = mapSwiftTypeToTsType(p.types.parameters[0].typename);
268
251
  return typescript_1.default.factory.createPropertySignature(undefined, p.name, undefined, propType);
@@ -274,61 +257,17 @@ function generatePropTypesForDefinition(definition) {
274
257
  return typescript_1.default.factory.createPropertySignature(undefined, e.name, undefined, eventType);
275
258
  }),
276
259
  ]));
277
- }
278
- /*
279
- Generate a mock for view props and functions.
280
- */
281
- function getMockedViews(viewDefinitions) {
282
- return viewDefinitions.flatMap((definition) => {
283
- if (!definition) {
284
- return [];
285
- }
286
- const propsType = generatePropTypesForDefinition(definition);
287
- const props = typescript_1.default.factory.createParameterDeclaration(undefined, undefined, 'props', undefined, typescript_1.default.factory.createTypeReferenceNode('ViewProps', undefined), undefined);
288
- const viewFunction = typescript_1.default.factory.createFunctionDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], undefined,
289
- // TODO: Handle this better once requireNativeViewManager accepts view name or a different solution for multiple views is built.
290
- viewDefinitions.length === 1 ? 'View' : definition.name, undefined, [props], undefined, typescript_1.default.factory.createBlock([]));
291
- return [propsType, viewFunction];
292
- });
293
- }
294
- function getMockedClass(def) {
295
- const classDecl = typescript_1.default.factory.createClassDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], typescript_1.default.factory.createIdentifier(def.name), undefined, undefined, [
296
- ...getMockedFunctions(def.functions, { classMethod: true }),
297
- ...getMockedFunctions(def.asyncFunctions, { async: true, classMethod: true }),
298
- ]);
299
- return classDecl;
300
- }
301
- function getMockedClasses(def) {
302
- return def.map((d) => getMockedClass(d));
260
+ const props = typescript_1.default.factory.createParameterDeclaration(undefined, undefined, 'props', undefined, typescript_1.default.factory.createTypeReferenceNode('ViewProps', undefined), undefined);
261
+ const viewFunction = typescript_1.default.factory.createFunctionDeclaration([typescript_1.default.factory.createToken(typescript_1.default.SyntaxKind.ExportKeyword)], undefined, 'View', undefined, [props], undefined, typescript_1.default.factory.createBlock([]));
262
+ return [propsType, viewFunction];
303
263
  }
304
264
  const newlineIdentifier = typescript_1.default.factory.createIdentifier('\n\n');
305
265
  function separateWithNewlines(arr) {
306
266
  return [arr, newlineIdentifier];
307
267
  }
308
- function omitFromSet(set, toOmit) {
309
- const newSet = new Set(set);
310
- toOmit.forEach((item) => {
311
- if (item) {
312
- newSet.delete(item);
313
- }
314
- });
315
- return newSet;
316
- }
317
268
  function getMockForModule(module, includeTypes) {
318
269
  return []
319
- .concat(getPrefix(), newlineIdentifier, includeTypes
320
- ? getMockedTypes(omitFromSet(new Set([
321
- ...getTypesToMock(module),
322
- ...new Set(...module.views.map((v) => getTypesToMock(v))),
323
- ...new Set(...module.classes.map((c) => getTypesToMock(c))),
324
- ]),
325
- // Ignore all types that are actually native classes
326
- [
327
- module.name,
328
- ...module.views.map((c) => c.name),
329
- ...module.classes.map((c) => c.name),
330
- ]))
331
- : [], newlineIdentifier, getMockedFunctions(module.functions), getMockedFunctions(module.asyncFunctions, { async: true }), newlineIdentifier, getMockedViews(module.views), getMockedClasses(module.classes))
270
+ .concat(getPrefix(), newlineIdentifier, includeTypes ? getMockedTypes(getTypesToMock(module)) : [], newlineIdentifier, getMockedFunctions(module.functions).flatMap((mf) => [mf, newlineIdentifier]), getMockedFunctions(module.asyncFunctions, true), newlineIdentifier, includeTypes && module.view ? getMockedTypes(getTypesToMock(module.view)) : [], newlineIdentifier, getMockedView(module.view))
332
271
  .flatMap(separateWithNewlines);
333
272
  }
334
273
  async function prettifyCode(text, parser = 'babel') {
@@ -1 +1 @@
1
- {"version":3,"file":"mockgen.js","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport fs from 'fs';\nimport path from 'path';\nimport * as prettier from 'prettier';\nimport ts from 'typescript';\n\nimport {\n Closure,\n ClosureTypes,\n OutputModuleDefinition,\n OutputNestedClassDefinition,\n} from './types';\n\nconst directoryPath = process.cwd();\n\n/*\nWe receive types from SourceKitten and `getStructure` like so (examples):\n[AcceptedTypes]?, UIColor?, [String: Any]\n\nWe need to parse them first to TS nodes in `mapSwiftTypeToTsType` with the following helper functions.\n*/\n\nfunction isSwiftArray(type: string) {\n // This can also be an object, but we check that first, so if it's not an object and is wrapped with [] it's an array.\n return type.startsWith('[') && type.endsWith(']');\n}\nfunction maybeUnwrapSwiftArray(type: string) {\n const isArray = isSwiftArray(type);\n if (!isArray) {\n return type;\n }\n const innerType = type.substring(1, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftOptional(type: string) {\n return type.endsWith('?');\n}\nfunction maybeUnwrapSwiftOptional(type: string) {\n const isOptional = isSwiftOptional(type);\n if (!isOptional) {\n return type;\n }\n const innerType = type.substring(0, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftDictionary(type: string) {\n return (\n type.startsWith('[') &&\n type.endsWith(']') &&\n findRootColonInDictionary(type.substring(1, type.length - 1)) >= 0\n );\n}\n\nfunction isEither(type: string) {\n return type.startsWith('Either<');\n}\n// \"Either<TypeOne, TypeTwo>\" -> [\"TypeOne\", \"TypeTwo\"]\nfunction maybeUnwrapEither(type: string): string[] {\n if (!isEither(type)) {\n return [type];\n }\n const innerType = type.substring(7, type.length - 1);\n return innerType.split(',').map((t) => t.trim());\n}\n\n/*\nThe Swift object type can have nested objects as the type of it's values (or maybe even keys).\n[String: [String: Any]]\n\nWe can't use regex to find the root colon, so this is the safest way – by counting brackets.\n*/\nfunction findRootColonInDictionary(type: string) {\n let colonIndex = -1;\n let openBracketsCount = 0;\n for (let i = 0; i < type.length; i++) {\n if (type[i] === '[') {\n openBracketsCount++;\n } else if (type[i] === ']') {\n openBracketsCount--;\n } else if (type[i] === ':' && openBracketsCount === 0) {\n colonIndex = i;\n break;\n }\n }\n return colonIndex;\n}\nfunction unwrapSwiftDictionary(type: string) {\n const innerType = type.substring(1, type.length - 1);\n const colonPosition = findRootColonInDictionary(innerType);\n return {\n key: innerType.slice(0, colonPosition).trim(),\n value: innerType.slice(colonPosition + 1).trim(),\n };\n}\n\ntype TSNode =\n | ts.UnionTypeNode\n | ts.KeywordTypeNode\n | ts.TypeReferenceNode\n | ts.ArrayTypeNode\n | ts.OptionalTypeNode\n | ts.TypeLiteralNode;\n\n/*\nMain function that converts a string representation of a Swift type to a TypeScript compiler API node AST.\nWe can pass those types straight to a TypeScript printer (a function that converts AST to text).\n*/\nfunction mapSwiftTypeToTsType(type: string): TSNode {\n if (!type) {\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);\n }\n if (isSwiftOptional(type)) {\n return ts.factory.createUnionTypeNode([\n mapSwiftTypeToTsType(maybeUnwrapSwiftOptional(type)),\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),\n ]);\n }\n if (isSwiftDictionary(type)) {\n const { key, value } = unwrapSwiftDictionary(type);\n const keyType = mapSwiftTypeToTsType(key);\n const valueType = mapSwiftTypeToTsType(value);\n\n const indexSignature = ts.factory.createIndexSignature(\n undefined,\n [ts.factory.createParameterDeclaration(undefined, undefined, 'key', undefined, keyType)],\n valueType\n );\n\n const typeLiteralNode = ts.factory.createTypeLiteralNode([indexSignature]);\n return typeLiteralNode;\n }\n if (isSwiftArray(type)) {\n return ts.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));\n }\n // Custom handling for the Either convertible\n if (isEither(type)) {\n return ts.factory.createUnionTypeNode(\n maybeUnwrapEither(type).map((t) => mapSwiftTypeToTsType(t))\n );\n }\n\n switch (type) {\n // Our custom representation for types that we have no type hints for. Not necessairly Swift any.\n case 'unknown':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n case 'String':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);\n case 'Bool':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);\n case 'Int':\n case 'Float':\n case 'Double':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);\n case 'Any': // Swift Any type\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n default: // Custom Swift type (record) – for now mapped to a custom TS type exported at the top of the file by `getMockedTypes`.\n return ts.factory.createTypeReferenceNode(type);\n }\n}\n\n// Mocks require sample return values, so we generate them based on TS AST.\nfunction getMockLiterals(tsReturnType: TSNode) {\n if (!tsReturnType) {\n return undefined;\n }\n switch (tsReturnType.kind) {\n case ts.SyntaxKind.AnyKeyword:\n case ts.SyntaxKind.VoidKeyword:\n return undefined;\n case ts.SyntaxKind.UnionType:\n // we take the first element of our union for the mock – we know the cast is correct since we create the type ourselves\n // the second is `undefined` for optionals.\n return getMockLiterals(tsReturnType.types[0] as TSNode);\n case ts.SyntaxKind.StringKeyword:\n return ts.factory.createStringLiteral('');\n case ts.SyntaxKind.BooleanKeyword:\n return ts.factory.createFalse();\n case ts.SyntaxKind.NumberKeyword:\n return ts.factory.createNumericLiteral('0');\n case ts.SyntaxKind.ArrayType:\n return ts.factory.createArrayLiteralExpression();\n case ts.SyntaxKind.TypeLiteral:\n // handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one\n return ts.factory.createObjectLiteralExpression([], false);\n }\n return undefined;\n}\n\nfunction wrapWithAsync(tsType: ts.TypeNode) {\n return ts.factory.createTypeReferenceNode('Promise', [tsType]);\n}\n\nfunction maybeWrapWithReturnStatement(tsType: TSNode) {\n if (tsType.kind === ts.SyntaxKind.AnyKeyword || tsType.kind === ts.SyntaxKind.VoidKeyword) {\n return [];\n }\n if (tsType.kind === ts.SyntaxKind.TypeReference) {\n // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.\n return [\n ts.addSyntheticTrailingComment(\n ts.factory.createReturnStatement(ts.factory.createNull()),\n ts.SyntaxKind.SingleLineCommentTrivia,\n ` TODO: Replace with mock for value of type ${\n ((tsType as any)?.typeName as any)?.escapedText ?? ''\n }.`\n ),\n ];\n }\n return [ts.factory.createReturnStatement(getMockLiterals(tsType))];\n}\n\n/*\nWe iterate over a list of functions and we create TS AST for each of them.\n*/\nfunction getMockedFunctions(functions: Closure[], { async = false, classMethod = false } = {}) {\n return functions.map((fnStructure) => {\n const name = ts.factory.createIdentifier(fnStructure.name);\n const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);\n const parameters =\n fnStructure?.types?.parameters.map((p) =>\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n p.name ?? '_',\n undefined,\n mapSwiftTypeToTsType(p.typename),\n undefined\n )\n ) ?? [];\n const returnBlock = ts.factory.createBlock(maybeWrapWithReturnStatement(returnType), true);\n\n if (classMethod) {\n return ts.factory.createMethodDeclaration(\n [async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined].flatMap((f) =>\n f ? [f] : []\n ),\n undefined,\n name,\n undefined,\n undefined,\n parameters,\n async ? wrapWithAsync(returnType) : returnType,\n returnBlock\n );\n }\n const func = ts.factory.createFunctionDeclaration(\n [\n ts.factory.createToken(ts.SyntaxKind.ExportKeyword),\n async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,\n ].flatMap((f) => (f ? [f] : [])),\n undefined,\n name,\n undefined,\n parameters,\n async ? wrapWithAsync(returnType) : returnType,\n returnBlock\n );\n return func;\n });\n}\n\n/**\n * Collect all type references used in any of the AST types to generate type aliases\n * e.g. type `[URL: string]?` will generate `type URL = any;`\n */\nfunction getAllTypeReferences(node: ts.Node, accumulator: string[]) {\n if (ts.isTypeReferenceNode(node)) {\n accumulator.push((node.typeName as any)?.escapedText);\n }\n node.forEachChild((n) => getAllTypeReferences(n, accumulator));\n}\n\n/**\n * Iterates over types to collect the aliases.\n */\nfunction getTypesToMock(module: OutputModuleDefinition | OutputNestedClassDefinition) {\n const foundTypes: string[] = [];\n\n Object.values(module)\n .flatMap((t) => (Array.isArray(t) ? t?.map((t2) => (t2 as Closure)?.types) : [] ?? []))\n .forEach((types: ClosureTypes | null) => {\n types?.parameters.forEach(({ typename }) => {\n getAllTypeReferences(mapSwiftTypeToTsType(typename), foundTypes);\n });\n types?.returnType &&\n getAllTypeReferences(mapSwiftTypeToTsType(types?.returnType), foundTypes);\n });\n return new Set(foundTypes);\n}\n\n/**\n * Gets a mock for a custom type.\n */\nfunction getMockedTypes(types: Set<string>) {\n return Array.from(types).map((type) => {\n const name = ts.factory.createIdentifier(type);\n const typeAlias = ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n name,\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n );\n return typeAlias;\n });\n}\n\nconst prefix = `Automatically generated by expo-modules-test-core.\n\nThis autogenerated file provides a mock for native Expo module,\nand works out of the box with the expo jest preset.\n`;\nfunction getPrefix() {\n return [ts.factory.createJSDocComment(prefix)];\n}\n\nfunction generatePropTypesForDefinition(definition: OutputNestedClassDefinition) {\n return ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n 'ViewProps',\n undefined,\n ts.factory.createTypeLiteralNode([\n ...definition.props.map((p) => {\n const propType = mapSwiftTypeToTsType(p.types.parameters[0].typename);\n return ts.factory.createPropertySignature(undefined, p.name, undefined, propType);\n }),\n ...definition.events.map((e) => {\n const eventType = ts.factory.createFunctionTypeNode(\n undefined,\n [\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'event',\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n ),\n ],\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)\n );\n return ts.factory.createPropertySignature(undefined, e.name, undefined, eventType);\n }),\n ])\n );\n}\n/*\nGenerate a mock for view props and functions.\n*/\nfunction getMockedViews(viewDefinitions: OutputNestedClassDefinition[]) {\n return viewDefinitions.flatMap((definition) => {\n if (!definition) {\n return [];\n }\n const propsType = generatePropTypesForDefinition(definition);\n const props = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'props',\n undefined,\n ts.factory.createTypeReferenceNode('ViewProps', undefined),\n undefined\n );\n const viewFunction = ts.factory.createFunctionDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n undefined,\n // TODO: Handle this better once requireNativeViewManager accepts view name or a different solution for multiple views is built.\n viewDefinitions.length === 1 ? 'View' : definition.name,\n undefined,\n [props],\n undefined,\n ts.factory.createBlock([])\n );\n return [propsType, viewFunction];\n });\n}\n\nfunction getMockedClass(def: OutputNestedClassDefinition) {\n const classDecl = ts.factory.createClassDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n ts.factory.createIdentifier(def.name),\n undefined,\n undefined,\n [\n ...getMockedFunctions(def.functions, { classMethod: true }),\n ...getMockedFunctions(def.asyncFunctions, { async: true, classMethod: true }),\n ] as ts.MethodDeclaration[]\n );\n return classDecl;\n}\n\nfunction getMockedClasses(def: OutputNestedClassDefinition[]) {\n return def.map((d) => getMockedClass(d));\n}\n\nconst newlineIdentifier = ts.factory.createIdentifier('\\n\\n') as any;\nfunction separateWithNewlines<T>(arr: T) {\n return [arr, newlineIdentifier];\n}\n\nfunction omitFromSet(set: Set<string>, toOmit: (string | undefined)[]) {\n const newSet = new Set(set);\n toOmit.forEach((item) => {\n if (item) {\n newSet.delete(item);\n }\n });\n return newSet;\n}\n\nfunction getMockForModule(module: OutputModuleDefinition, includeTypes: boolean) {\n return (\n [] as (ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.JSDoc | ts.ClassDeclaration)[]\n )\n .concat(\n getPrefix(),\n newlineIdentifier,\n includeTypes\n ? getMockedTypes(\n omitFromSet(\n new Set([\n ...getTypesToMock(module),\n ...new Set(...module.views.map((v) => getTypesToMock(v))),\n ...new Set(...module.classes.map((c) => getTypesToMock(c))),\n ]),\n // Ignore all types that are actually native classes\n [\n module.name,\n ...module.views.map((c) => c.name),\n ...module.classes.map((c) => c.name),\n ]\n )\n )\n : [],\n newlineIdentifier,\n getMockedFunctions(module.functions) as ts.FunctionDeclaration[],\n getMockedFunctions(module.asyncFunctions, { async: true }) as ts.FunctionDeclaration[],\n newlineIdentifier,\n getMockedViews(module.views),\n getMockedClasses(module.classes)\n )\n .flatMap(separateWithNewlines);\n}\n\nasync function prettifyCode(text: string, parser: 'babel' | 'typescript' = 'babel') {\n return await prettier.format(text, {\n parser,\n tabWidth: 2,\n printWidth: 100,\n trailingComma: 'none',\n singleQuote: true,\n });\n}\n\nexport async function generateMocks(\n modules: OutputModuleDefinition[],\n outputLanguage: 'javascript' | 'typescript' = 'javascript'\n) {\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n\n for (const m of modules) {\n const filename = m.name + (outputLanguage === 'javascript' ? '.js' : '.ts');\n const resultFile = ts.createSourceFile(\n filename,\n '',\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TSX\n );\n fs.mkdirSync(path.join(directoryPath, 'mocks'), { recursive: true });\n const filePath = path.join(directoryPath, 'mocks', filename);\n // get ts nodearray from getMockForModule(m) array\n const mock = ts.factory.createNodeArray(getMockForModule(m, outputLanguage === 'typescript'));\n const printedTs = printer.printList(\n ts.ListFormat.MultiLine + ts.ListFormat.PreserveLines,\n mock,\n resultFile\n );\n\n if (outputLanguage === 'javascript') {\n const compiledJs = ts.transpileModule(printedTs, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ESNext,\n },\n }).outputText;\n const prettifiedJs = await prettifyCode(compiledJs);\n fs.writeFileSync(filePath, prettifiedJs);\n } else {\n const prettifiedTs = await prettifyCode(printedTs, 'typescript');\n fs.writeFileSync(filePath, prettifiedTs);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"mockgen.js","sourceRoot":"","sources":["../src/mockgen.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport fs from 'fs';\nimport path from 'path';\nimport * as prettier from 'prettier';\nimport ts from 'typescript';\n\nimport { Closure, ClosureTypes, OutputModuleDefinition, OutputViewDefinition } from './types';\n\nconst directoryPath = process.cwd();\n\n/*\nWe receive types from SourceKitten and `getStructure` like so (examples):\n[AcceptedTypes]?, UIColor?, [String: Any]\n\nWe need to parse them first to TS nodes in `mapSwiftTypeToTsType` with the following helper functions.\n*/\n\nfunction isSwiftArray(type: string) {\n // This can also be an object, but we check that first, so if it's not an object and is wrapped with [] it's an array.\n return type.startsWith('[') && type.endsWith(']');\n}\nfunction maybeUnwrapSwiftArray(type: string) {\n const isArray = isSwiftArray(type);\n if (!isArray) {\n return type;\n }\n const innerType = type.substring(1, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftOptional(type: string) {\n return type.endsWith('?');\n}\nfunction maybeUnwrapSwiftOptional(type: string) {\n const isOptional = isSwiftOptional(type);\n if (!isOptional) {\n return type;\n }\n const innerType = type.substring(0, type.length - 1);\n return innerType;\n}\n\nfunction isSwiftDictionary(type: string) {\n return (\n type.startsWith('[') &&\n type.endsWith(']') &&\n findRootColonInDictionary(type.substring(1, type.length - 1)) >= 0\n );\n}\n\n/*\nThe Swift object type can have nested objects as the type of it's values (or maybe even keys).\n[String: [String: Any]]\n\nWe can't use regex to find the root colon, so this is the safest way – by counting brackets.\n*/\nfunction findRootColonInDictionary(type: string) {\n let colonIndex = -1;\n let openBracketsCount = 0;\n for (let i = 0; i < type.length; i++) {\n if (type[i] === '[') {\n openBracketsCount++;\n } else if (type[i] === ']') {\n openBracketsCount--;\n } else if (type[i] === ':' && openBracketsCount === 0) {\n colonIndex = i;\n break;\n }\n }\n return colonIndex;\n}\nfunction unwrapSwiftDictionary(type: string) {\n const innerType = type.substring(1, type.length - 1);\n const colonPosition = findRootColonInDictionary(innerType);\n return {\n key: innerType.slice(0, colonPosition).trim(),\n value: innerType.slice(colonPosition + 1).trim(),\n };\n}\n\ntype TSNode =\n | ts.UnionTypeNode\n | ts.KeywordTypeNode\n | ts.TypeReferenceNode\n | ts.ArrayTypeNode\n | ts.OptionalTypeNode\n | ts.TypeLiteralNode;\n\n/*\nMain function that converts a string representation of a Swift type to a TypeScript compiler API node AST.\nWe can pass those types straight to a TypeScript printer (a function that converts AST to text).\n*/\nfunction mapSwiftTypeToTsType(type: string): TSNode {\n if (!type) {\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);\n }\n if (isSwiftOptional(type)) {\n return ts.factory.createUnionTypeNode([\n mapSwiftTypeToTsType(maybeUnwrapSwiftOptional(type)),\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),\n ]);\n }\n if (isSwiftDictionary(type)) {\n const { key, value } = unwrapSwiftDictionary(type);\n const keyType = mapSwiftTypeToTsType(key);\n const valueType = mapSwiftTypeToTsType(value);\n\n const indexSignature = ts.factory.createIndexSignature(\n undefined,\n [ts.factory.createParameterDeclaration(undefined, undefined, 'key', undefined, keyType)],\n valueType\n );\n\n const typeLiteralNode = ts.factory.createTypeLiteralNode([indexSignature]);\n return typeLiteralNode;\n }\n if (isSwiftArray(type)) {\n return ts.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));\n }\n switch (type) {\n // Our custom representation for types that we have no type hints for. Not necessairly Swift any.\n case 'unknown':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n case 'String':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);\n case 'Bool':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);\n case 'Int':\n case 'Float':\n case 'Double':\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);\n case 'Any': // Swift Any type\n return ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n default: // Custom Swift type (record) – for now mapped to a custom TS type exported at the top of the file by `getMockedTypes`.\n return ts.factory.createTypeReferenceNode(type);\n }\n}\n\n// Mocks require sample return values, so we generate them based on TS AST.\nfunction getMockLiterals(tsReturnType: TSNode) {\n if (!tsReturnType) {\n return undefined;\n }\n switch (tsReturnType.kind) {\n case ts.SyntaxKind.AnyKeyword:\n case ts.SyntaxKind.VoidKeyword:\n return undefined;\n case ts.SyntaxKind.UnionType:\n // we take the first element of our union for the mock – we know the cast is correct since we create the type ourselves\n // the second is `undefined` for optionals.\n return getMockLiterals(tsReturnType.types[0] as TSNode);\n case ts.SyntaxKind.StringKeyword:\n return ts.factory.createStringLiteral('');\n case ts.SyntaxKind.BooleanKeyword:\n return ts.factory.createFalse();\n case ts.SyntaxKind.NumberKeyword:\n return ts.factory.createNumericLiteral('0');\n case ts.SyntaxKind.ArrayType:\n return ts.factory.createArrayLiteralExpression();\n case ts.SyntaxKind.TypeLiteral:\n // handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one\n return ts.factory.createObjectLiteralExpression([], false);\n case ts.SyntaxKind.TypeReference:\n // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.\n return ts.addSyntheticTrailingComment(\n ts.factory.createNull(),\n ts.SyntaxKind.SingleLineCommentTrivia,\n ` TODO: Replace with mock for value of type ${\n ((tsReturnType as any)?.typeName as any)?.escapedText ?? ''\n }.`\n );\n }\n return undefined;\n}\n\nfunction wrapWithAsync(tsType: ts.TypeNode) {\n return ts.factory.createTypeReferenceNode('Promise', [tsType]);\n}\n\nfunction maybeWrapWithReturnStatement(tsType: TSNode) {\n if (tsType.kind === ts.SyntaxKind.AnyKeyword || tsType.kind === ts.SyntaxKind.VoidKeyword) {\n return [];\n }\n return [ts.factory.createReturnStatement(getMockLiterals(tsType))];\n}\n\n/*\nWe iterate over a list of functions and we create TS AST for each of them.\n*/\nfunction getMockedFunctions(functions: Closure[], async = false) {\n return functions.map((fnStructure) => {\n const name = ts.factory.createIdentifier(fnStructure.name);\n const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);\n const func = ts.factory.createFunctionDeclaration(\n [\n ts.factory.createToken(ts.SyntaxKind.ExportKeyword),\n async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,\n ].filter((f) => !!f) as ts.ModifierToken<any>[],\n undefined,\n name,\n undefined,\n fnStructure?.types?.parameters.map((p) =>\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n p.name,\n undefined,\n mapSwiftTypeToTsType(p.typename),\n undefined\n )\n ) ?? [],\n async ? wrapWithAsync(returnType) : returnType,\n ts.factory.createBlock(maybeWrapWithReturnStatement(returnType), true)\n );\n return func;\n });\n}\n\n/**\n * Collect all type references used in any of the AST types to generate type aliases\n * e.g. type `[URL: string]?` will generate `type URL = any;`\n */\nfunction getAllTypeReferences(node: ts.Node, accumulator: string[]) {\n if (ts.isTypeReferenceNode(node)) {\n accumulator.push((node.typeName as any)?.escapedText);\n }\n node.forEachChild((n) => getAllTypeReferences(n, accumulator));\n}\n\n/**\n * Iterates over types to collect the aliases.\n */\nfunction getTypesToMock(module: OutputModuleDefinition | OutputViewDefinition) {\n const foundTypes: string[] = [];\n\n Object.values(module)\n .flatMap((t) => (Array.isArray(t) ? t?.map((t2) => (t2 as Closure)?.types) : [] ?? []))\n .forEach((types: ClosureTypes | null) => {\n types?.parameters.forEach(({ typename }) => {\n getAllTypeReferences(mapSwiftTypeToTsType(typename), foundTypes);\n });\n types?.returnType &&\n getAllTypeReferences(mapSwiftTypeToTsType(types?.returnType), foundTypes);\n });\n return new Set(foundTypes);\n}\n\n/**\n * Gets a mock for a custom type.\n */\nfunction getMockedTypes(types: Set<string>) {\n return Array.from(types).map((type) => {\n const name = ts.factory.createIdentifier(type);\n const typeAlias = ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n name,\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n );\n return typeAlias;\n });\n}\n\nconst prefix = `Automatically generated by expo-modules-test-core.\n\nThis autogenerated file provides a mock for native Expo module,\nand works out of the box with the expo jest preset.\n`;\nfunction getPrefix() {\n return [ts.factory.createJSDocComment(prefix)];\n}\n\n/*\nGenerate a mock for view props and functions.\n*/\nfunction getMockedView(definition: OutputViewDefinition | null) {\n if (!definition) {\n return [];\n }\n const propsType = ts.factory.createTypeAliasDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n 'ViewProps',\n undefined,\n ts.factory.createTypeLiteralNode([\n ...definition.props.map((p) => {\n const propType = mapSwiftTypeToTsType(p.types.parameters[0].typename);\n return ts.factory.createPropertySignature(undefined, p.name, undefined, propType);\n }),\n ...definition.events.map((e) => {\n const eventType = ts.factory.createFunctionTypeNode(\n undefined,\n [\n ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'event',\n undefined,\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)\n ),\n ],\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword)\n );\n return ts.factory.createPropertySignature(undefined, e.name, undefined, eventType);\n }),\n ])\n );\n const props = ts.factory.createParameterDeclaration(\n undefined,\n undefined,\n 'props',\n undefined,\n ts.factory.createTypeReferenceNode('ViewProps', undefined),\n undefined\n );\n const viewFunction = ts.factory.createFunctionDeclaration(\n [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],\n undefined,\n 'View',\n undefined,\n [props],\n undefined,\n ts.factory.createBlock([])\n );\n return [propsType, viewFunction];\n}\n\nconst newlineIdentifier = ts.factory.createIdentifier('\\n\\n') as any;\nfunction separateWithNewlines<T>(arr: T) {\n return [arr, newlineIdentifier];\n}\n\nfunction getMockForModule(module: OutputModuleDefinition, includeTypes: boolean) {\n return ([] as (ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.JSDoc)[])\n .concat(\n getPrefix(),\n newlineIdentifier,\n includeTypes ? getMockedTypes(getTypesToMock(module)) : [],\n newlineIdentifier,\n getMockedFunctions(module.functions).flatMap((mf) => [mf, newlineIdentifier]),\n getMockedFunctions(module.asyncFunctions, true),\n newlineIdentifier,\n includeTypes && module.view ? getMockedTypes(getTypesToMock(module.view)) : [],\n newlineIdentifier,\n getMockedView(module.view)\n )\n .flatMap(separateWithNewlines);\n}\n\nasync function prettifyCode(text: string, parser: 'babel' | 'typescript' = 'babel') {\n return await prettier.format(text, {\n parser,\n tabWidth: 2,\n printWidth: 100,\n trailingComma: 'none',\n singleQuote: true,\n });\n}\n\nexport async function generateMocks(\n modules: OutputModuleDefinition[],\n outputLanguage: 'javascript' | 'typescript' = 'javascript'\n) {\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n\n for (const m of modules) {\n const filename = m.name + (outputLanguage === 'javascript' ? '.js' : '.ts');\n const resultFile = ts.createSourceFile(\n filename,\n '',\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TSX\n );\n fs.mkdirSync(path.join(directoryPath, 'mocks'), { recursive: true });\n const filePath = path.join(directoryPath, 'mocks', filename);\n // get ts nodearray from getMockForModule(m) array\n const mock = ts.factory.createNodeArray(getMockForModule(m, outputLanguage === 'typescript'));\n const printedTs = printer.printList(\n ts.ListFormat.MultiLine + ts.ListFormat.PreserveLines,\n mock,\n resultFile\n );\n\n if (outputLanguage === 'javascript') {\n const compiledJs = ts.transpileModule(printedTs, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ESNext,\n },\n }).outputText;\n const prettifiedJs = await prettifyCode(compiledJs);\n fs.writeFileSync(filePath, prettifiedJs);\n } else {\n const prettifiedTs = await prettifyCode(printedTs, 'typescript');\n fs.writeFileSync(filePath, prettifiedTs);\n }\n }\n}\n"]}
package/build/types.d.ts CHANGED
@@ -40,11 +40,10 @@ export type Prop = {
40
40
  };
41
41
  export type OutputModuleDefinition = {
42
42
  name: string;
43
- views: OutputNestedClassDefinition[];
44
- classes: OutputNestedClassDefinition[];
43
+ view: OutputViewDefinition | null;
45
44
  events: {
46
45
  name: string;
47
46
  }[];
48
47
  } & Record<'asyncFunctions' | 'functions' | 'properties', Closure[]> & Record<'props', Prop[]>;
49
- export type OutputNestedClassDefinition = Omit<OutputModuleDefinition, 'views' | 'classes'>;
48
+ export type OutputViewDefinition = Omit<OutputModuleDefinition, 'view'>;
50
49
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,kBAAkB,EAAE,SAAS,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0BAA0B,EAAE,MAAM,CAAC;IACnC,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,oBAAoB,EAAE;QACpB,oBAAoB,EAAE;YACpB,mCAAmC,EAAE,MAAM,CAAC;YAC5C,yBAAyB,EAAE,MAAM,CAAC;SACnC,EAAE,CAAC;QACJ,0BAA0B,EAAE,MAAM,CAAC;KACpC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,GAAG,CAAC;QACV,QAAQ,EAAE,GAAG,CAAC;KACf,EAAE,CAAC;IACJ,UAAU,EAAE,GAAG,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,2BAA2B,EAAE,CAAC;IACrC,OAAO,EAAE,2BAA2B,EAAE,CAAC;IACvC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;CACL,GAAG,MAAM,CAAC,gBAAgB,GAAG,WAAW,GAAG,YAAY,EAAE,OAAO,EAAE,CAAC,GAClE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAG1B,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,kBAAkB,EAAE,SAAS,EAAE,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0BAA0B,EAAE,MAAM,CAAC;IACnC,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,oBAAoB,EAAE;QACpB,oBAAoB,EAAE;YACpB,mCAAmC,EAAE,MAAM,CAAC;YAC5C,yBAAyB,EAAE,MAAM,CAAC;SACnC,EAAE,CAAC;QACJ,0BAA0B,EAAE,MAAM,CAAC;KACpC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,GAAG,CAAC;QACV,QAAQ,EAAE,GAAG,CAAC;KACf,EAAE,CAAC;IACJ,UAAU,EAAE,GAAG,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;CACL,GAAG,MAAM,CAAC,gBAAgB,GAAG,WAAW,GAAG,YAAY,EAAE,OAAO,EAAE,CAAC,GAClE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAE1B,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type FileType = {\n path: string;\n content: string;\n};\n\nexport type Structure = {\n 'key.substructure': Structure[];\n 'key.typename': string;\n 'key.name': string;\n 'key.kind': string;\n 'key.offset': number;\n 'key.length': number;\n};\n\nexport type CursorInfoOutput = {\n 'key.fully_annotated_decl': string;\n 'key.annotated_decl': string;\n};\n\nexport type FullyAnnotatedDecl = {\n 'decl.function.free': {\n 'decl.var.parameter': {\n 'decl.var.parameter.argument_label': string;\n 'decl.var.parameter.type': string;\n }[];\n 'decl.function.returntype': string;\n };\n};\n\nexport type ClosureTypes = {\n parameters: {\n name: any;\n typename: any;\n }[];\n returnType: any;\n};\n\nexport type Closure = {\n name: string;\n types: ClosureTypes | null;\n};\n\nexport type Prop = {\n name: string;\n types: Omit<ClosureTypes, 'returnType'>;\n};\n\nexport type OutputModuleDefinition = {\n name: string;\n views: OutputNestedClassDefinition[];\n classes: OutputNestedClassDefinition[];\n events: {\n name: string;\n }[];\n} & Record<'asyncFunctions' | 'functions' | 'properties', Closure[]> &\n Record<'props', Prop[]>;\n\n// views and classes are a very similar structure, same as module but without more nesting levels\nexport type OutputNestedClassDefinition = Omit<OutputModuleDefinition, 'views' | 'classes'>;\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type FileType = {\n path: string;\n content: string;\n};\n\nexport type Structure = {\n 'key.substructure': Structure[];\n 'key.typename': string;\n 'key.name': string;\n 'key.kind': string;\n 'key.offset': number;\n 'key.length': number;\n};\n\nexport type CursorInfoOutput = {\n 'key.fully_annotated_decl': string;\n 'key.annotated_decl': string;\n};\n\nexport type FullyAnnotatedDecl = {\n 'decl.function.free': {\n 'decl.var.parameter': {\n 'decl.var.parameter.argument_label': string;\n 'decl.var.parameter.type': string;\n }[];\n 'decl.function.returntype': string;\n };\n};\n\nexport type ClosureTypes = {\n parameters: {\n name: any;\n typename: any;\n }[];\n returnType: any;\n};\n\nexport type Closure = {\n name: string;\n types: ClosureTypes | null;\n};\n\nexport type Prop = {\n name: string;\n types: Omit<ClosureTypes, 'returnType'>;\n};\n\nexport type OutputModuleDefinition = {\n name: string;\n view: OutputViewDefinition | null;\n events: {\n name: string;\n }[];\n} & Record<'asyncFunctions' | 'functions' | 'properties', Closure[]> &\n Record<'props', Prop[]>;\n\nexport type OutputViewDefinition = Omit<OutputModuleDefinition, 'view'>;\n"]}
@@ -10,9 +10,7 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.author = package['author']
12
12
  s.homepage = package['homepage']
13
- s.platforms = {
14
- :ios => '15.1'
15
- }
13
+ s.platform = :ios, '13.4'
16
14
  s.swift_version = '5.4'
17
15
  s.source = { git: 'https://github.com/expo/expo.git' }
18
16
  s.static_framework = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-test-core",
3
- "version": "0.18.1-canary-20240904-69100c1",
3
+ "version": "0.18.1",
4
4
  "main": "./app.plugin.js",
5
5
  "description": "Module providing native testing utilities for testing Expo modules",
6
6
  "keywords": [
@@ -34,5 +34,5 @@
34
34
  "xml-js": "^1.6.11",
35
35
  "yaml": "^2.3.2"
36
36
  },
37
- "gitHead": "69100c1b099b707057c052ed8096e06cb208aca1"
37
+ "gitHead": "80602dd9f2501843baf8da0bd9df3f4e6c49edb8"
38
38
  }
@@ -11,6 +11,7 @@ import {
11
11
  FileType,
12
12
  FullyAnnotatedDecl,
13
13
  OutputModuleDefinition,
14
+ OutputViewDefinition,
14
15
  Structure,
15
16
  } from './types';
16
17
 
@@ -186,36 +187,27 @@ function findGroupedDefinitionsOfType(type: string, moduleDefinition: Structure[
186
187
  return definitionParams.map((d) => ({ name: getIdentifierFromOffsetObject(d, file) }));
187
188
  });
188
189
  }
189
- function findAndParseNestedClassesOfType(
190
+
191
+ function findAndParseView(
190
192
  moduleDefinition: Structure[],
191
- file: FileType,
192
- type: string
193
- ) {
194
- // we support reading definitions from closure only
195
- const definitionsOfType = moduleDefinition.filter((md) => md['key.name'] === type);
196
- return definitionsOfType
197
- .map((df) => {
198
- const nestedModuleDefinition =
199
- df['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.[
200
- 'key.substructure'
201
- ];
202
- if (!nestedModuleDefinition) {
203
- console.warn('Could not parse definition');
204
- return null;
205
- }
206
- const name = getIdentifierFromOffsetObject(df['key.substructure']?.[0], file).replace(
207
- '.self',
208
- ''
209
- );
210
- // let's drop nested view field and classes (are null anyways)
211
- const {
212
- views: _,
213
- classes: _2,
214
- ...definition
215
- } = parseModuleDefinition(nestedModuleDefinition, file);
216
- return { ...definition, name };
217
- })
218
- .flatMap((f) => (f ? [f] : []));
193
+ file: FileType
194
+ ): null | OutputViewDefinition {
195
+ const viewDefinition = moduleDefinition.find((md) => md['key.name'] === 'View');
196
+ if (!viewDefinition) {
197
+ return null;
198
+ }
199
+ // we support reading view definitions from closure only
200
+ const viewModuleDefinition =
201
+ viewDefinition['key.substructure']?.[1]?.['key.substructure']?.[0]?.['key.substructure']?.[0]?.[
202
+ 'key.substructure'
203
+ ];
204
+ if (!viewModuleDefinition) {
205
+ console.warn('Could not parse view definition');
206
+ return null;
207
+ }
208
+ // let's drop nested view field (is null anyways)
209
+ const { view: _, ...definition } = parseModuleDefinition(viewModuleDefinition, file);
210
+ return definition;
219
211
  }
220
212
 
221
213
  function omitParamsFromClosureArguments<T extends Closure>(
@@ -226,7 +218,8 @@ function omitParamsFromClosureArguments<T extends Closure>(
226
218
  ...d,
227
219
  types: {
228
220
  ...d.types,
229
- parameters: d.types?.parameters?.filter((t, idx) => !paramsToOmit.includes(t.name)) ?? [],
221
+ parameters:
222
+ d.types?.parameters?.filter((t, idx) => idx !== 0 && !paramsToOmit.includes(t.name)) ?? [],
230
223
  },
231
224
  }));
232
225
  }
@@ -257,8 +250,7 @@ function parseModuleDefinition(
257
250
  findNamedDefinitionsOfType('Prop', preparedModuleDefinition, file),
258
251
  ['view']
259
252
  ),
260
- views: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'View'),
261
- classes: findAndParseNestedClassesOfType(preparedModuleDefinition, file, 'Class'),
253
+ view: findAndParseView(preparedModuleDefinition, file),
262
254
  };
263
255
  return parsedDefinition;
264
256
  }
package/src/mockgen.ts CHANGED
@@ -6,12 +6,7 @@ import path from 'path';
6
6
  import * as prettier from 'prettier';
7
7
  import ts from 'typescript';
8
8
 
9
- import {
10
- Closure,
11
- ClosureTypes,
12
- OutputModuleDefinition,
13
- OutputNestedClassDefinition,
14
- } from './types';
9
+ import { Closure, ClosureTypes, OutputModuleDefinition, OutputViewDefinition } from './types';
15
10
 
16
11
  const directoryPath = process.cwd();
17
12
 
@@ -55,18 +50,6 @@ function isSwiftDictionary(type: string) {
55
50
  );
56
51
  }
57
52
 
58
- function isEither(type: string) {
59
- return type.startsWith('Either<');
60
- }
61
- // "Either<TypeOne, TypeTwo>" -> ["TypeOne", "TypeTwo"]
62
- function maybeUnwrapEither(type: string): string[] {
63
- if (!isEither(type)) {
64
- return [type];
65
- }
66
- const innerType = type.substring(7, type.length - 1);
67
- return innerType.split(',').map((t) => t.trim());
68
- }
69
-
70
53
  /*
71
54
  The Swift object type can have nested objects as the type of it's values (or maybe even keys).
72
55
  [String: [String: Any]]
@@ -136,13 +119,6 @@ function mapSwiftTypeToTsType(type: string): TSNode {
136
119
  if (isSwiftArray(type)) {
137
120
  return ts.factory.createArrayTypeNode(mapSwiftTypeToTsType(maybeUnwrapSwiftArray(type)));
138
121
  }
139
- // Custom handling for the Either convertible
140
- if (isEither(type)) {
141
- return ts.factory.createUnionTypeNode(
142
- maybeUnwrapEither(type).map((t) => mapSwiftTypeToTsType(t))
143
- );
144
- }
145
-
146
122
  switch (type) {
147
123
  // Our custom representation for types that we have no type hints for. Not necessairly Swift any.
148
124
  case 'unknown':
@@ -186,6 +162,15 @@ function getMockLiterals(tsReturnType: TSNode) {
186
162
  case ts.SyntaxKind.TypeLiteral:
187
163
  // handles a dictionary, could be improved by creating an object fitting the schema instead of an empty one
188
164
  return ts.factory.createObjectLiteralExpression([], false);
165
+ case ts.SyntaxKind.TypeReference:
166
+ // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
167
+ return ts.addSyntheticTrailingComment(
168
+ ts.factory.createNull(),
169
+ ts.SyntaxKind.SingleLineCommentTrivia,
170
+ ` TODO: Replace with mock for value of type ${
171
+ ((tsReturnType as any)?.typeName as any)?.escapedText ?? ''
172
+ }.`
173
+ );
189
174
  }
190
175
  return undefined;
191
176
  }
@@ -198,66 +183,36 @@ function maybeWrapWithReturnStatement(tsType: TSNode) {
198
183
  if (tsType.kind === ts.SyntaxKind.AnyKeyword || tsType.kind === ts.SyntaxKind.VoidKeyword) {
199
184
  return [];
200
185
  }
201
- if (tsType.kind === ts.SyntaxKind.TypeReference) {
202
- // A fallback – we print a comment that these mocks are not fitting the custom type. Could be improved by expanding a set of default mocks.
203
- return [
204
- ts.addSyntheticTrailingComment(
205
- ts.factory.createReturnStatement(ts.factory.createNull()),
206
- ts.SyntaxKind.SingleLineCommentTrivia,
207
- ` TODO: Replace with mock for value of type ${
208
- ((tsType as any)?.typeName as any)?.escapedText ?? ''
209
- }.`
210
- ),
211
- ];
212
- }
213
186
  return [ts.factory.createReturnStatement(getMockLiterals(tsType))];
214
187
  }
215
188
 
216
189
  /*
217
190
  We iterate over a list of functions and we create TS AST for each of them.
218
191
  */
219
- function getMockedFunctions(functions: Closure[], { async = false, classMethod = false } = {}) {
192
+ function getMockedFunctions(functions: Closure[], async = false) {
220
193
  return functions.map((fnStructure) => {
221
194
  const name = ts.factory.createIdentifier(fnStructure.name);
222
195
  const returnType = mapSwiftTypeToTsType(fnStructure.types?.returnType);
223
- const parameters =
196
+ const func = ts.factory.createFunctionDeclaration(
197
+ [
198
+ ts.factory.createToken(ts.SyntaxKind.ExportKeyword),
199
+ async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,
200
+ ].filter((f) => !!f) as ts.ModifierToken<any>[],
201
+ undefined,
202
+ name,
203
+ undefined,
224
204
  fnStructure?.types?.parameters.map((p) =>
225
205
  ts.factory.createParameterDeclaration(
226
206
  undefined,
227
207
  undefined,
228
- p.name ?? '_',
208
+ p.name,
229
209
  undefined,
230
210
  mapSwiftTypeToTsType(p.typename),
231
211
  undefined
232
212
  )
233
- ) ?? [];
234
- const returnBlock = ts.factory.createBlock(maybeWrapWithReturnStatement(returnType), true);
235
-
236
- if (classMethod) {
237
- return ts.factory.createMethodDeclaration(
238
- [async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined].flatMap((f) =>
239
- f ? [f] : []
240
- ),
241
- undefined,
242
- name,
243
- undefined,
244
- undefined,
245
- parameters,
246
- async ? wrapWithAsync(returnType) : returnType,
247
- returnBlock
248
- );
249
- }
250
- const func = ts.factory.createFunctionDeclaration(
251
- [
252
- ts.factory.createToken(ts.SyntaxKind.ExportKeyword),
253
- async ? ts.factory.createToken(ts.SyntaxKind.AsyncKeyword) : undefined,
254
- ].flatMap((f) => (f ? [f] : [])),
255
- undefined,
256
- name,
257
- undefined,
258
- parameters,
213
+ ) ?? [],
259
214
  async ? wrapWithAsync(returnType) : returnType,
260
- returnBlock
215
+ ts.factory.createBlock(maybeWrapWithReturnStatement(returnType), true)
261
216
  );
262
217
  return func;
263
218
  });
@@ -277,7 +232,7 @@ function getAllTypeReferences(node: ts.Node, accumulator: string[]) {
277
232
  /**
278
233
  * Iterates over types to collect the aliases.
279
234
  */
280
- function getTypesToMock(module: OutputModuleDefinition | OutputNestedClassDefinition) {
235
+ function getTypesToMock(module: OutputModuleDefinition | OutputViewDefinition) {
281
236
  const foundTypes: string[] = [];
282
237
 
283
238
  Object.values(module)
@@ -317,8 +272,14 @@ function getPrefix() {
317
272
  return [ts.factory.createJSDocComment(prefix)];
318
273
  }
319
274
 
320
- function generatePropTypesForDefinition(definition: OutputNestedClassDefinition) {
321
- return ts.factory.createTypeAliasDeclaration(
275
+ /*
276
+ Generate a mock for view props and functions.
277
+ */
278
+ function getMockedView(definition: OutputViewDefinition | null) {
279
+ if (!definition) {
280
+ return [];
281
+ }
282
+ const propsType = ts.factory.createTypeAliasDeclaration(
322
283
  [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
323
284
  'ViewProps',
324
285
  undefined,
@@ -345,54 +306,24 @@ function generatePropTypesForDefinition(definition: OutputNestedClassDefinition)
345
306
  }),
346
307
  ])
347
308
  );
348
- }
349
- /*
350
- Generate a mock for view props and functions.
351
- */
352
- function getMockedViews(viewDefinitions: OutputNestedClassDefinition[]) {
353
- return viewDefinitions.flatMap((definition) => {
354
- if (!definition) {
355
- return [];
356
- }
357
- const propsType = generatePropTypesForDefinition(definition);
358
- const props = ts.factory.createParameterDeclaration(
359
- undefined,
360
- undefined,
361
- 'props',
362
- undefined,
363
- ts.factory.createTypeReferenceNode('ViewProps', undefined),
364
- undefined
365
- );
366
- const viewFunction = ts.factory.createFunctionDeclaration(
367
- [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
368
- undefined,
369
- // TODO: Handle this better once requireNativeViewManager accepts view name or a different solution for multiple views is built.
370
- viewDefinitions.length === 1 ? 'View' : definition.name,
371
- undefined,
372
- [props],
373
- undefined,
374
- ts.factory.createBlock([])
375
- );
376
- return [propsType, viewFunction];
377
- });
378
- }
379
-
380
- function getMockedClass(def: OutputNestedClassDefinition) {
381
- const classDecl = ts.factory.createClassDeclaration(
309
+ const props = ts.factory.createParameterDeclaration(
310
+ undefined,
311
+ undefined,
312
+ 'props',
313
+ undefined,
314
+ ts.factory.createTypeReferenceNode('ViewProps', undefined),
315
+ undefined
316
+ );
317
+ const viewFunction = ts.factory.createFunctionDeclaration(
382
318
  [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
383
- ts.factory.createIdentifier(def.name),
384
319
  undefined,
320
+ 'View',
321
+ undefined,
322
+ [props],
385
323
  undefined,
386
- [
387
- ...getMockedFunctions(def.functions, { classMethod: true }),
388
- ...getMockedFunctions(def.asyncFunctions, { async: true, classMethod: true }),
389
- ] as ts.MethodDeclaration[]
324
+ ts.factory.createBlock([])
390
325
  );
391
- return classDecl;
392
- }
393
-
394
- function getMockedClasses(def: OutputNestedClassDefinition[]) {
395
- return def.map((d) => getMockedClass(d));
326
+ return [propsType, viewFunction];
396
327
  }
397
328
 
398
329
  const newlineIdentifier = ts.factory.createIdentifier('\n\n') as any;
@@ -400,46 +331,19 @@ function separateWithNewlines<T>(arr: T) {
400
331
  return [arr, newlineIdentifier];
401
332
  }
402
333
 
403
- function omitFromSet(set: Set<string>, toOmit: (string | undefined)[]) {
404
- const newSet = new Set(set);
405
- toOmit.forEach((item) => {
406
- if (item) {
407
- newSet.delete(item);
408
- }
409
- });
410
- return newSet;
411
- }
412
-
413
334
  function getMockForModule(module: OutputModuleDefinition, includeTypes: boolean) {
414
- return (
415
- [] as (ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.JSDoc | ts.ClassDeclaration)[]
416
- )
335
+ return ([] as (ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.JSDoc)[])
417
336
  .concat(
418
337
  getPrefix(),
419
338
  newlineIdentifier,
420
- includeTypes
421
- ? getMockedTypes(
422
- omitFromSet(
423
- new Set([
424
- ...getTypesToMock(module),
425
- ...new Set(...module.views.map((v) => getTypesToMock(v))),
426
- ...new Set(...module.classes.map((c) => getTypesToMock(c))),
427
- ]),
428
- // Ignore all types that are actually native classes
429
- [
430
- module.name,
431
- ...module.views.map((c) => c.name),
432
- ...module.classes.map((c) => c.name),
433
- ]
434
- )
435
- )
436
- : [],
339
+ includeTypes ? getMockedTypes(getTypesToMock(module)) : [],
340
+ newlineIdentifier,
341
+ getMockedFunctions(module.functions).flatMap((mf) => [mf, newlineIdentifier]),
342
+ getMockedFunctions(module.asyncFunctions, true),
437
343
  newlineIdentifier,
438
- getMockedFunctions(module.functions) as ts.FunctionDeclaration[],
439
- getMockedFunctions(module.asyncFunctions, { async: true }) as ts.FunctionDeclaration[],
344
+ includeTypes && module.view ? getMockedTypes(getTypesToMock(module.view)) : [],
440
345
  newlineIdentifier,
441
- getMockedViews(module.views),
442
- getMockedClasses(module.classes)
346
+ getMockedView(module.view)
443
347
  )
444
348
  .flatMap(separateWithNewlines);
445
349
  }
package/src/types.ts CHANGED
@@ -47,13 +47,11 @@ export type Prop = {
47
47
 
48
48
  export type OutputModuleDefinition = {
49
49
  name: string;
50
- views: OutputNestedClassDefinition[];
51
- classes: OutputNestedClassDefinition[];
50
+ view: OutputViewDefinition | null;
52
51
  events: {
53
52
  name: string;
54
53
  }[];
55
54
  } & Record<'asyncFunctions' | 'functions' | 'properties', Closure[]> &
56
55
  Record<'props', Prop[]>;
57
56
 
58
- // views and classes are a very similar structure, same as module but without more nesting levels
59
- export type OutputNestedClassDefinition = Omit<OutputModuleDefinition, 'views' | 'classes'>;
57
+ export type OutputViewDefinition = Omit<OutputModuleDefinition, 'view'>;