typescript#MapLike TypeScript Examples

The following examples show how to use typescript#MapLike. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ui-jsx-canvas-element-renderer-utils.tsx    From utopia with MIT License 7 votes vote down vote up
function getElementFromScope(jsxElementToLookup: JSXElement, scope: MapLike<any> | null): any {
  if (scope == null) {
    return undefined
  } else {
    if (jsxElementToLookup.name.baseVariable in scope) {
      const fromVar = scope[jsxElementToLookup.name.baseVariable]
      const result = Utils.pathOr(
        undefined,
        PP.getElements(jsxElementToLookup.name.propertyPath),
        fromVar,
      )
      return result
    } else {
      return undefined
    }
  }
}
Example #2
Source File: ui-jsx-canvas.test-utils.tsx    From utopia with MIT License 7 votes vote down vote up
export function testCanvasRenderInlineMultifile(
  possibleProps: PartialCanvasProps | null,
  uiFileCode: string,
  codeFilesString: MapLike<string>,
): string {
  const {
    formattedSpyEnabled,
    formattedSpyDisabled,
    errorsReportedSpyEnabled,
    errorsReportedSpyDisabled,
    spyValues,
  } = renderCanvasReturnResultAndError(possibleProps, uiFileCode, codeFilesString)
  if (errorsReportedSpyEnabled.length > 0) {
    console.error(errorsReportedSpyEnabled)
  }
  if (errorsReportedSpyEnabled.length > 0) {
    throw new Error(`Canvas Tests, Spy Enabled: Errors reported: ${errorsReportedSpyEnabled}`)
  }
  if (errorsReportedSpyDisabled.length > 0) {
    throw new Error(`Canvas Tests, Spy Disabled: Errors reported: ${errorsReportedSpyDisabled}`)
  }

  // Spy enabled or disabled should have no effect on the rendered HTML
  expect(formattedSpyEnabled).toEqual(formattedSpyDisabled)
  expect(formattedSpyEnabled).toBeDefined()

  return formattedSpyEnabled!
}
Example #3
Source File: ui-jsx-canvas.test-utils.tsx    From utopia with MIT License 7 votes vote down vote up
export function testCanvasRenderMultifile(
  possibleProps: PartialCanvasProps | null,
  uiFileCode: string,
  codeFilesString: MapLike<string>,
): void {
  const {
    formattedSpyEnabled,
    formattedSpyDisabled,
    errorsReportedSpyEnabled,
    errorsReportedSpyDisabled,
    spyValues,
  } = renderCanvasReturnResultAndError(possibleProps, uiFileCode, codeFilesString)
  if (errorsReportedSpyEnabled.length > 0) {
    throw new Error(`Canvas Tests, Spy Enabled: Errors reported: ${errorsReportedSpyEnabled}`)
  }
  if (errorsReportedSpyDisabled.length > 0) {
    throw new Error(`Canvas Tests, Spy Disabled: Errors reported: ${errorsReportedSpyDisabled}`)
  }

  // Spy enabled or disabled should have no effect on the rendered HTML
  expect(formattedSpyEnabled).toEqual(formattedSpyDisabled)

  expect(formattedSpyEnabled).toMatchSnapshot()

  const metadataWithoutUIDs = Utils.objectMap(stripUnwantedDataFromMetadata, spyValues.metadata)
  expect(metadataWithoutUIDs).toMatchSnapshot()
}
Example #4
Source File: array-utils.ts    From utopia with MIT License 7 votes vote down vote up
export function addToMapOfArraysUnique<V, M extends MapLike<Array<V>>>(
  map: M,
  key: string,
  value: V,
): M {
  if (key in map) {
    const existing: Array<V> = map[key]
    if (existing.includes(value)) {
      return map
    } else {
      return {
        ...map,
        [key]: [...existing, value],
      }
    }
  } else {
    return {
      ...map,
      [key]: [value],
    }
  }
}
Example #5
Source File: ui-jsx-canvas.test-utils.tsx    From utopia with MIT License 7 votes vote down vote up
export function testCanvasErrorInline(
  possibleProps: PartialCanvasProps | null,
  uiFileCode: string,
  codeFilesString: MapLike<string>,
): TestCanvasError[] {
  const { errorsReportedSpyEnabled, errorsReportedSpyDisabled } = renderCanvasReturnResultAndError(
    possibleProps,
    uiFileCode,
    codeFilesString,
  )

  expect(errorsReportedSpyEnabled.length).toEqual(errorsReportedSpyDisabled.length)
  expect(errorsReportedSpyEnabled.length).toBeGreaterThan(0)
  const errorsToCheck = errorsReportedSpyEnabled.map((error) => {
    let realError = error.error != null ? error.error : (error as unknown as FancyError) // is this conversion needed?
    return {
      name: realError.name,
      message: realError.message,
      stackFrames:
        realError.stackFrames?.map((stackFrame) => {
          return {
            fileName: stackFrame._originalFileName,
            originalCode: stackFrame._originalScriptCode,
            lineNumber: stackFrame._originalLineNumber,
            columnNumber: stackFrame._originalColumnNumber,
          }
        }) ?? [],
    }
  })
  return errorsToCheck
}
Example #6
Source File: ui-jsx-canvas-scope-utils.ts    From utopia with MIT License 7 votes vote down vote up
export function runBlockUpdatingScope(
  filePath: string,
  requireResult: MapLike<any>,
  block: ArbitraryJSBlock,
  currentScope: MapLike<any>,
): void {
  const result = resolveParamsAndRunJsCode(filePath, block, requireResult, currentScope)
  fastForEach(block.definedWithin, (within) => {
    currentScope[within] = result[within]
  })
}
Example #7
Source File: ui-jsx-canvas-element-renderer-utils.tsx    From utopia with MIT License 7 votes vote down vote up
export function renderComponentUsingJsxFactoryFunction(
  inScope: MapLike<any>,
  factoryFunctionName: string | null,
  type: any,
  props: any,
  ...children: Array<any>
): any {
  const fixedProps = fixStyleObjectRemoveCommentOnlyValues(props)
  let factoryFunction = React.createElement
  if (factoryFunctionName != null) {
    if (factoryFunctionName in inScope) {
      if (
        inScope[factoryFunctionName] != null &&
        typeof inScope[factoryFunctionName] === 'function'
      ) {
        factoryFunction = inScope[factoryFunctionName]
      } else {
        // TODO add StackFrame!
        throw new Error(`Factory function ${factoryFunctionName} is undefined or not a function.`)
      }
    } else {
      // TODO add StackFrame!
      throw new Error(`Unable to find factory function ${factoryFunctionName} in scope.`)
    }
  }
  return factoryFunction.call(null, type, fixedProps, ...children)
}
Example #8
Source File: ui-jsx-canvas-element-renderer-utils.tsx    From utopia with MIT License 7 votes vote down vote up
export function utopiaCanvasJSXLookup(
  elementsWithin: ElementsWithin,
  executionScope: MapLike<any>,
  render: (element: JSXElement, inScope: MapLike<any>) => React.ReactChild,
): (uid: string, inScope: MapLike<any>) => React.ReactChild | null {
  return (uid, inScope) => {
    const element = elementsWithin[uid]
    if (element == null) {
      return null
    } else {
      const combinedScope = { ...executionScope, ...inScope }
      return render(element, combinedScope)
    }
  }
}
Example #9
Source File: object-utils.ts    From utopia with MIT License 7 votes vote down vote up
export function omitWithPredicate<T extends MapLike<any>>(
  obj: T,
  pred: <K extends keyof T>(k: K, v: T[K]) => boolean,
): T {
  var result = {} as T

  for (var prop in obj) {
    if (!pred(prop, obj[prop])) {
      result[prop] = obj[prop]
    }
  }
  return result
}
Example #10
Source File: utils.ts    From utopia with MIT License 7 votes vote down vote up
export function objectEquals<T>(
  a: MapLike<T>,
  b: MapLike<T>,
  eq?: (l: T, r: T) => boolean,
): boolean {
  if (a === b) {
    return true
  } else {
    const equals = eq == null ? (l: T, r: T) => l === r : eq
    for (const aKey of Object.keys(a)) {
      if (aKey in b) {
        if (!equals(a[aKey], b[aKey])) {
          // Values in each object for the same key differ.
          return false
        }
      } else {
        // Value for key cannot be found in object 'b'.
        return false
      }
    }
    for (const bKey of Object.keys(b)) {
      if (!(bKey in a)) {
        // This key from 'b' isn't in 'a'.
        return false
      }
    }
    return true
  }
}
Example #11
Source File: parser-printer.test-utils.ts    From utopia with MIT License 7 votes vote down vote up
export function flatObjectArbitrary<V>(
  keys: Arbitrary<string>,
  values: Arbitrary<V>,
): Arbitrary<MapLike<V>> {
  // FastCheck.object is a load of rubbish.
  const pairsArbitrary = FastCheck.array(FastCheck.tuple(keys, values), 3)
  return pairsArbitrary.map((pairs) => {
    return pairs.reduce((working, [key, value]) => {
      return {
        ...working,
        [key]: value,
      }
    }, {})
  })
}
Example #12
Source File: ui-jsx-canvas-element-renderer-utils.tsx    From utopia with MIT License 7 votes vote down vote up
function monkeyUidProp(uid: string | undefined, propsToUpdate: MapLike<any>): MapLike<any> {
  let monkeyedProps: MapLike<any> = {
    ...propsToUpdate,
  }

  const uidFromProps = monkeyedProps[UTOPIA_UID_KEY]
  const uidToPass = uidFromProps ?? uid
  monkeyedProps[UTOPIA_UID_KEY] = uidToPass

  return monkeyedProps
}
Example #13
Source File: value-parser-utils.ts    From utopia with MIT License 7 votes vote down vote up
export function parseObject<V>(
  objectValueParser: (v: unknown, key: string) => ParseResult<V>,
): Parser<MapLike<V>> {
  return (value: unknown) => {
    if (typeof value === 'object' && !Array.isArray(value) && value != null) {
      const valueAsObject: any = value
      const withErrorParser = objectValueParserWithError(objectValueParser)
      return reduceWithEither<string, ParseError, MapLike<V>>(
        (working: MapLike<V>, objectKey: string) => {
          return mapEither((parsedObjectValue) => {
            return {
              ...working,
              [objectKey]: parsedObjectValue,
            }
          }, withErrorParser(valueAsObject[objectKey], objectKey))
        },
        {},
        Object.keys(valueAsObject),
      )
    } else {
      return left(descriptionParseError('Not an object.'))
    }
  }
}
Example #14
Source File: npm-dependency.ts    From utopia with MIT License 6 votes vote down vote up
export function importResultFromImports(
  importOrigin: string,
  imports: Imports,
  requireFn: (origin: string, toImport: string) => any,
): MapLike<any> {
  let result: MapLike<any> = {}
  Utils.fastForEach(Object.keys(imports), (importSource) => {
    const requireResult = requireFn(importOrigin, importSource)
    if (requireResult == null) {
      console.warn(`Could not find ${importSource} with a require call.`)
    } else {
      result = {
        ...result,
        ...importResultFromModule(imports[importSource], requireResult),
      }
    }
  })
  return result
}
Example #15
Source File: dom-walker.ts    From utopia with MIT License 6 votes vote down vote up
function mergeFragmentMetadata(
  metadata: ReadonlyArray<ElementInstanceMetadata>,
): ElementInstanceMetadataMap {
  let working: MapLike<ElementInstanceMetadata> = {}

  fastForEach(metadata, (elementMetadata) => {
    const pathString = EP.toString(elementMetadata.elementPath)
    const existingMetadata = working[pathString]

    if (existingMetadata == null) {
      working[pathString] = elementMetadata
    } else {
      // We've hit a fragment, so remove the style etc., but keep the frames for selection
      const merged = elementInstanceMetadata(
        elementMetadata.elementPath,
        left('fragment'),
        boundingRectangle(
          existingMetadata.globalFrame ?? zeroCanvasRect,
          elementMetadata.globalFrame ?? zeroCanvasRect,
        ),
        boundingRectangle(
          existingMetadata.localFrame ?? zeroLocalRect,
          elementMetadata.localFrame ?? zeroLocalRect,
        ),
        false,
        false,
        emptySpecialSizeMeasurements,
        {},
        {},
        null,
        null,
      )

      working[pathString] = merged
    }
  })

  return working
}
Example #16
Source File: module-resolution.ts    From utopia with MIT License 6 votes vote down vote up
export function parsePartialPackageJsonDefinition(
  value: unknown,
): ParseResult<PartialPackageJsonDefinition> {
  return applicative4Either(
    (name, main, module, browser) => {
      let result: PartialPackageJsonDefinition = {}
      setOptionalProp(result, 'name', name)
      setOptionalProp(result, 'main', main)
      setOptionalProp(result, 'module', module)
      setOptionalProp(result, 'browser', browser)
      return result
    },
    optionalObjectKeyParser(parseString, 'name')(value),
    optionalObjectKeyParser(parseString, 'main')(value),
    optionalObjectKeyParser(parseString, 'module')(value),
    optionalObjectKeyParser(
      parseAlternative<string | MapLike<string | false>>(
        [
          parseString,
          parseObject(
            parseAlternative<string | false>(
              [parseString, parseFalse],
              `package.browser replacement entries must be either string or 'false' for ignoring a package`,
            ),
          ),
        ],
        'package.browser field must either be a string or an object with type {[key: string]: string}',
      ),
      'browser',
    )(value),
  )
}
Example #17
Source File: module-resolution.ts    From utopia with MIT License 6 votes vote down vote up
function processPackageJson(
  potentiallyJsonCode: string,
  containerFolder: string[],
): ResolveResult<Array<string>> {
  let possiblePackageJson: ParseResult<PartialPackageJsonDefinition>
  try {
    const jsonParsed = JSON.parse(potentiallyJsonCode)
    possiblePackageJson = parsePartialPackageJsonDefinition(jsonParsed)
  } catch {
    return resolveNotPresent
  }
  return foldEither(
    (_) => resolveNotPresent,
    (packageJson) => {
      const moduleName: string | null = packageJson.name ?? null
      const browserEntry: string | MapLike<string | false> | null = packageJson.browser ?? null
      const mainEntry: string | null = packageJson.main ?? null
      const moduleEntry: string | null = packageJson.module ?? null

      if (browserEntry != null && typeof browserEntry === 'string') {
        return resolveSuccess(
          normalizePath([...containerFolder, ...getPartsFromPath(browserEntry)]),
        )
      } else if (mainEntry != null) {
        return resolveSuccess(normalizePath([...containerFolder, ...getPartsFromPath(mainEntry)]))
      } else if (moduleEntry != null) {
        return resolveSuccess(normalizePath([...containerFolder, ...getPartsFromPath(moduleEntry)]))
      } else if (moduleName != null) {
        return resolveSuccess(normalizePath([...containerFolder, ...getPartsFromPath(moduleName)]))
      } else if (containerFolder.length > 0) {
        return resolveSuccess(normalizePath(containerFolder))
      }

      return resolveNotPresent
    },
    possiblePackageJson,
  )
}
Example #18
Source File: npm-dependency.ts    From utopia with MIT License 6 votes vote down vote up
export function importResultFromModule(
  importDetails: ImportDetails,
  requireResult: any,
): MapLike<any> {
  let result: MapLike<any> = {}

  if (importDetails.importedWithName !== null) {
    // import name from './place'
    result[importDetails.importedWithName] = importDefault(requireResult)
  }
  if (importDetails.importedAs !== null) {
    // import * as name from './place'
    result[importDetails.importedAs] = importStar(requireResult)
  }
  Utils.fastForEach(importDetails.importedFromWithin, (fromWithin) => {
    result[fromWithin.alias] = requireResult[fromWithin.name]
  })

  return result
}
Example #19
Source File: module-resolution.ts    From utopia with MIT License 6 votes vote down vote up
function applyBrowserFieldReplacements(
  browserField: MapLike<string | false>,
  toImport: string,
): Either<boolean, string> {
  // The pkg.browser field can contain potential substitutions https://github.com/defunctzombie/package-browser-field-spec
  if (toImport in browserField) {
    const replacement = browserField[toImport]
    if (replacement === false) {
      // special case, null substitution means ignoring a module, resolving it as null
      return left(false)
    } else {
      // the browser field is sneaky and supports recursive replacements
      return applyBrowserFieldReplacements(browserField, replacement)
    }
  }

  // we couldn't find any replacements, return the original toImport string
  return right(toImport)
}
Example #20
Source File: javascript-cache.ts    From utopia with MIT License 6 votes vote down vote up
export function resolveParamsAndRunJsCode(
  filePath: string,
  javascriptBlock: JavaScriptContainer,
  requireResult: MapLike<any>,
  currentScope: MapLike<any>,
): any {
  const definedElsewhereInfo = resolveDefinedElsewhere(
    javascriptBlock.definedElsewhere,
    requireResult,
    currentScope,
  )
  const updatedBlock = {
    ...javascriptBlock,
    definedElsewhere: Object.keys(definedElsewhereInfo),
  }
  // NOTE: If the external dependencies of this block of code aren't present when this is first called,
  // we'll cache the block without those keys. This _shouldn't_ be an issue since we replace the unique ID
  // on a new parse, but it means we have to be careful of this when reusing js blocks in tests
  //
  // The reason for us filtering the `definedElsewhere` here is so that we can throw a ReferenceError when
  // actually executing the JS code, rather than an error that would confuse the user
  const result = getOrUpdateFunctionCache(filePath, updatedBlock, requireResult, (e) => {
    throw e
  })(currentScope['callerThis'], ...Object.values(definedElsewhereInfo))
  return result
}
Example #21
Source File: javascript-cache.ts    From utopia with MIT License 6 votes vote down vote up
function getOrUpdateFunctionCache(
  filePath: string,
  javascript: JavaScriptContainer,
  requireResult: MapLike<any>,
  handleError: (error: Error) => void,
): (...args: Array<unknown>) => unknown {
  const fromCache = functionCache[javascript.uniqueID]
  if (fromCache == null) {
    const newCachedFunction = SafeFunctionCurriedErrorHandler(
      false,
      requireResult,
      filePath,
      javascript.transpiledJavascript,
      javascript.sourceMap,
      javascript.definedElsewhere,
    )
    functionCache[javascript.uniqueID] = newCachedFunction
    return newCachedFunction(handleError)
  } else {
    return fromCache(handleError)
  }
}
Example #22
Source File: javascript-cache.ts    From utopia with MIT License 6 votes vote down vote up
function resolveDefinedElsewhere(
  definedElsewhere: Array<string>,
  requireResult: MapLike<any>,
  scope: MapLike<any>,
): { [name: string]: any } {
  let definedElsewhereInfo: { [name: string]: any } = {}

  definedElsewhere.forEach((elsewhere) => {
    const glob: any = global as any
    let possibleValue = glob[elsewhere]
    if (possibleValue != undefined || (glob.hasOwnProperty(elsewhere) as boolean)) {
      definedElsewhereInfo[elsewhere] = possibleValue
    }

    if (elsewhere === 'console') {
      definedElsewhereInfo[elsewhere] = console
    }

    possibleValue = requireResult[elsewhere]
    if (possibleValue != undefined || requireResult.hasOwnProperty(elsewhere)) {
      definedElsewhereInfo[elsewhere] = possibleValue
    }

    possibleValue = scope[elsewhere]
    if (possibleValue != undefined || scope.hasOwnProperty(elsewhere)) {
      definedElsewhereInfo[elsewhere] = possibleValue
    }
  })

  return definedElsewhereInfo
}
Example #23
Source File: jsx-attributes.ts    From utopia with MIT License 6 votes vote down vote up
export function jsxAttributesToProps(
  filePath: string,
  inScope: MapLike<any>,
  attributes: JSXAttributes,
  requireResult: MapLike<any>,
): any {
  let result: any = {}
  for (const entry of attributes) {
    switch (entry.type) {
      case 'JSX_ATTRIBUTES_ENTRY':
        result[entry.key] = jsxAttributeToValue(filePath, inScope, requireResult, entry.value)
        break
      case 'JSX_ATTRIBUTES_SPREAD':
        result = {
          ...result,
          ...jsxAttributeToValue(filePath, inScope, requireResult, entry.spreadValue),
        }
        break
      default:
        const _exhaustiveCheck: never = entry
        throw new Error(`Unhandled entry ${JSON.stringify(entry)}`)
    }
  }
  return result
}
Example #24
Source File: canvas-react-utils.ts    From utopia with MIT License 6 votes vote down vote up
export function filterDataProps(props: MapLike<any>): MapLike<any> {
  return omitWithPredicate(props, (key) => typeof key === 'string' && keyShouldBeExcluded(key))
}
Example #25
Source File: ui-jsx-canvas-element-renderer-utils.tsx    From utopia with MIT License 6 votes vote down vote up
function NoOpLookupRender(element: JSXElement, scope: MapLike<any>): React.ReactChild {
  throw new Error(
    `Utopia Error: createLookupRender was not used properly for element: ${element.name.baseVariable}`,
  )
}
Example #26
Source File: ui-jsx-canvas.test-utils.tsx    From utopia with MIT License 6 votes vote down vote up
export function testCanvasErrorMultifile(
  possibleProps: PartialCanvasProps | null,
  uiFileCode: string,
  codeFilesString: MapLike<string>,
): void {
  const errorsToCheck = testCanvasErrorInline(possibleProps, uiFileCode, codeFilesString)
  expect(errorsToCheck).toMatchSnapshot()
}
Example #27
Source File: ui-jsx-canvas-element-renderer-utils.tsx    From utopia with MIT License 6 votes vote down vote up
function runJSXArbitraryBlock(
  filePath: string,
  requireResult: MapLike<any>,
  block: JSXArbitraryBlock,
  currentScope: MapLike<any>,
): any {
  return resolveParamsAndRunJsCode(filePath, block, requireResult, currentScope)
}
Example #28
Source File: ui-jsx-canvas-element-renderer-utils.tsx    From utopia with MIT License 6 votes vote down vote up
export function createLookupRender(
  elementPath: ElementPath | null,
  rootScope: MapLike<any>,
  parentComponentInputProps: MapLike<any>,
  requireResult: MapLike<any>,
  hiddenInstances: Array<ElementPath>,
  fileBlobs: UIFileBase64Blobs,
  validPaths: Set<ElementPath>,
  reactChildren: React.ReactNode | undefined,
  metadataContext: UiJsxCanvasContextData,
  updateInvalidatedPaths: DomWalkerInvalidatePathsCtxData,
  jsxFactoryFunctionName: string | null,
  shouldIncludeCanvasRootInTheSpy: boolean,
  filePath: string,
  imports: Imports,
  code: string,
  highlightBounds: HighlightBoundsForUids | null,
): (element: JSXElement, scope: MapLike<any>) => React.ReactChild {
  let index = 0

  return (element: JSXElement, scope: MapLike<any>): React.ReactChild => {
    index++
    const innerUID = getUtopiaID(element)
    const generatedUID = createIndexedUid(innerUID, index)
    const withGeneratedUID = setJSXValueAtPath(
      element.props,
      PP.create(['data-uid']),
      jsxAttributeValue(generatedUID, emptyComments),
    )

    // TODO BALAZS should this be here? or should the arbitrary block never have a template path with that last generated element?
    const elementPathWithoutTheLastElementBecauseThatsAWeirdGeneratedUID = optionalMap(
      EP.parentPath,
      elementPath,
    )

    const innerPath = optionalMap(
      (path) => EP.appendToPath(path, generatedUID),
      elementPathWithoutTheLastElementBecauseThatsAWeirdGeneratedUID,
    )

    let augmentedInnerElement = element
    forEachRight(withGeneratedUID, (attrs) => {
      augmentedInnerElement = {
        ...augmentedInnerElement,
        props: attrs,
      }
    })
    return renderCoreElement(
      augmentedInnerElement,
      innerPath,
      rootScope,
      scope,
      parentComponentInputProps,
      requireResult,
      hiddenInstances,
      fileBlobs,
      validPaths,
      generatedUID,
      reactChildren,
      metadataContext,
      updateInvalidatedPaths,
      jsxFactoryFunctionName,
      null,
      shouldIncludeCanvasRootInTheSpy,
      filePath,
      imports,
      code,
      highlightBounds,
    )
  }
}
Example #29
Source File: code-file.spec.ts    From utopia with MIT License 6 votes vote down vote up
function transpileCode(
  rootFilenames: Array<string>,
  files: MapLike<string>,
): MapLike<EmitFileResult> {
  initBrowserFS({}, {})
  const fileVersions: MapLike<FileVersion> = objectMap((_) => {
    return { versionNr: 1, asStringCached: null }
  }, files)
  const services = configureLanguageService(
    rootFilenames,
    fileVersions,
    DefaultLanguageServiceCompilerOptions,
  )
  fastForEach(Object.keys(files), (filename) => {
    const fileContents = files[filename]
    writeFileForTests(filename, fileContents)
  })
  return objectMap((_, filename) => emitFile(services, `${filename}`), files)
}