chromium/tools/typescript/ts_library.gni

# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/chromeos/ui_mode.gni")
import("//third_party/node/node.gni")

template("ts_library") {
  node(target_name) {
    script = "//tools/typescript/ts_library.py"

    forward_variables_from(invoker,
                           [
                             "deps",
                             "extra_deps",
                             "in_files",
                             "tsconfig_base",
                             "path_mappings_file",
                             "manifest_excludes",
                             "testonly",
                             "visibility",
                           ])

    inputs = [
      "//tools/typescript/path_utils.py",
      "//tools/typescript/tsconfig_base.json",
      "//tools/typescript/validate_tsconfig.py",
    ]
    outputs = [ "$target_gen_dir/tsconfig_$target_name.json" ]

    assert(defined(in_files) || defined(invoker.definitions))

    root_dir = "."
    if (defined(invoker.root_dir)) {
      root_dir = invoker.root_dir
    }

    out_dir = target_gen_dir
    if (defined(invoker.out_dir)) {
      out_dir = invoker.out_dir
    }

    composite = false
    if (defined(invoker.composite)) {
      composite = invoker.composite
    }

    if (defined(in_files)) {
      outputs += [ "$target_gen_dir/${target_name}_manifest.json" ]
      foreach(_source, in_files) {
        inputs += [ "$root_dir/$_source" ]
        _dirname =
            rebase_path(get_path_info(_source, "gen_dir"), target_gen_dir)
        _filename = get_path_info(_source, "name")
        outputs += [ "$out_dir/$_dirname/$_filename.js" ]

        if (composite) {
          outputs += [ "$out_dir/$_dirname/$_filename.d.ts" ]
        }
      }
    }

    args = [
      "--root_gen_dir",
      rebase_path(root_gen_dir, target_gen_dir),
      "--root_src_dir",
      rebase_path("//", target_gen_dir),

      "--root_dir",
      rebase_path(root_dir, root_build_dir),
      "--gen_dir",
      rebase_path(target_gen_dir, root_build_dir),
      "--out_dir",
      rebase_path(out_dir, root_build_dir),
      "--output_suffix",
      target_name,
    ]

    if (defined(in_files)) {
      args += [ "--in_files" ] + in_files
    }

    if (defined(path_mappings_file)) {
      args += [
        "--path_mappings_file",
        rebase_path(path_mappings_file, target_gen_dir),
      ]
      inputs += [ path_mappings_file ]
    }

    if (defined(manifest_excludes)) {
      assert(defined(in_files))
      args += [ "--manifest_excludes" ] + manifest_excludes
    }

    if (defined(invoker.definitions)) {
      inputs += invoker.definitions
      definitions = []
      foreach(_definition, invoker.definitions) {
        definitions += [ rebase_path(_definition, target_gen_dir) ]
      }
      args += [ "--definitions" ] + definitions
    }

    if (defined(deps)) {
      args += [ "--deps" ]
      foreach(dep, deps) {
        name = get_label_info(dep, "name")
        args += [ rebase_path(get_label_info(dep, "dir"), ".") +
                  "/tsconfig_$name.json" ]
      }
    }

    if (defined(tsconfig_base)) {
      inputs += [ tsconfig_base ]
      args += [
        "--tsconfig_base",
        rebase_path(tsconfig_base, target_gen_dir),
      ]
    }

    if (composite) {
      args += [ "--composite" ]
    }

    if (defined(invoker.enable_source_maps) && invoker.enable_source_maps) {
      args += [ "--enable_source_maps" ]
    }

    if (defined(extra_deps)) {
      # ts_library() targets are conventionally named with "build_ts" or
      # "library". These should always be listed in deps and not extra_deps
      foreach(_extra_dep, extra_deps) {
        assert(get_label_info(_extra_dep, "name") != "build_ts" &&
                   get_label_info(_extra_dep, "name") != "library",
               "Did you mean to list ${_extra_dep} in deps instead of " +
                   "extra_deps? extra_deps should not hold any ts_library() " +
                   "targets.")
      }
      if (!defined(deps)) {
        deps = []
      }
      deps += extra_deps
    }

    path_mappings = [
      "/tools/typescript/definitions/*|" +
          rebase_path("//tools/typescript/definitions/*", target_gen_dir),
      # NOTE: path_mappings corresponding to files generated by
      # other ts_library() deps are automatically inferred from |deps| in
      # path_mappings.py. Don't add any such mappings here.
    ]

    # The |platform| flag is used in path_mappings.py and validate_tsconfig.py,
    # to limit some logic to certain platforms, like preventing special iOS
    # exceptions being abused on other platforms.
    if (is_ios) {
      platform = "ios"
      args += [
        "--platform",
        platform,
      ]
    } else if (is_chromeos_ash) {
      platform = "chromeos_ash"
      args += [
        "--platform",
        platform,
      ]
    }

    args += [ "--path_mappings" ] + path_mappings
    if (defined(invoker.path_mappings)) {
      args += invoker.path_mappings
    }
  }
}