summaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/ty/typespec/package.nix
blob: 45ba2f5853f317a388d5dec8803d0832483a772d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
{
  lib,
  stdenvNoCC,
  fetchFromGitHub,
  makeWrapper,
  nix-update-script,
  nodejs,
  fetchPnpmDeps,
  pnpmConfigHook,
  pnpm_10,
  versionCheckHook,
}:

let
  workspace = "@typespec/compiler...";

  pnpm = pnpm_10;
in
stdenvNoCC.mkDerivation (finalAttrs: {
  pname = "typespec";
  version = "1.4.0";

  src = fetchFromGitHub {
    owner = "microsoft";
    repo = "typespec";
    tag = "typespec-stable@${finalAttrs.version}";
    hash = "sha256-huyEQA+XhlGVxnxUzQH1aIZUE4EbCN6HakitzuDyR18=";
  };

  nativeBuildInputs = [
    makeWrapper
    nodejs
    pnpmConfigHook
    pnpm
  ];

  pnpmWorkspaces = [ workspace ];
  pnpmDeps = fetchPnpmDeps {
    inherit (finalAttrs)
      pname
      version
      src
      pnpmWorkspaces
      postPatch
      ;
    inherit pnpm;
    fetcherVersion = 3;
    hash = "sha256-wZvnRSALrupyhpSN8zNL3b6SZnVPXX3BdHrbzHUNtUg=";
  };

  postPatch = ''
    # The `packageManager` attribute matches the version _exactly_, which makes
    # the build fail if it doesn't match exactly.
    substituteInPlace package.json \
      --replace-fail '"packageManager": "pnpm@10.11.0"' '"packageManager": "pnpm"'
    # `fetchFromGitHub` doesn't clone via git and thus installing would otherwise fail.
    substituteInPlace packages/compiler/scripts/generate-manifest.js \
      --replace-fail 'execSync("git rev-parse HEAD").toString().trim()' '"${finalAttrs.src.rev}"'
  '';

  buildPhase = ''
    runHook preBuild

    pnpm -r --filter ${workspace} build

    runHook postBuild
  '';

  preInstall = ''
    # Remove unnecessary files.
    find -name node_modules -type d -exec rm -rf {} \; || true
    pnpm config set hoist=false
    pnpm install --offline --ignore-scripts --frozen-lockfile --filter="@typespec/compiler" --prod --no-optional
  '';

  installPhase = ''
    runHook preInstall

    mkdir -p "$out/bin" "$out/lib/typespec"
    cp -r --parents \
      node_modules/ \
      package.json \
      packages/compiler/cmd \
      packages/compiler/dist \
      packages/compiler/entrypoints \
      packages/compiler/lib \
      packages/compiler/node_modules \
      packages/compiler/templates \
      packages/compiler/package.json \
      "$out/lib/typespec"

    makeWrapper "${lib.getExe nodejs}" "$out/bin/tsp" \
      --add-flags "$out/lib/typespec/packages/compiler/cmd/tsp.js"
    makeWrapper "${lib.getExe nodejs}" "$out/bin/tsp-server" \
      --add-flags "$out/lib/typespec/packages/compiler/cmd/tsp-server.js"

    runHook postInstall
  '';

  nativeInstallCheckInputs = [
    versionCheckHook
  ];
  doInstallCheck = true;

  passthru.updateScript = nix-update-script {
    extraArgs = [ ''--version-regex=typespec-stable@(\d+\.\d+\.\d+)'' ];
  };

  meta = {
    description = "Language for defining cloud service APIs and shapes";
    longDescription = ''
      TypeSpec is a highly extensible language with primitives that can describe
      API shapes common among REST, OpenAPI, gRPC, and other protocols.

      TypeSpec is excellent for generating many different API description
      formats, client and service code, documentation, and many other assets.
      All this while keeping your TypeSpec definition as a single source of truth.
    '';
    homepage = "https://typespec.io/";
    changelog = "https://github.com/microsoft/typespec/releases/tag/typespec-stable@${finalAttrs.version}";
    license = lib.licenses.mit;
    maintainers = with lib.maintainers; [ paukaifler ];
    mainProgram = "tsp";
  };
})