diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
index 2431f00..0b38dc8 100644
--- a/.github/workflows/ci-cd.yml
+++ b/.github/workflows/ci-cd.yml
@@ -68,7 +68,8 @@ jobs:
dotnet build samples/ContractApi --configuration Release
dotnet run --project JsonApiToolkit.TypeGen --configuration Release --no-build -- \
--assembly samples/ContractApi/bin/Release/net10.0/ContractApi.dll \
- --out samples/ContractApi/api-types.gen.ts --check
+ --out samples/ContractApi/api-types.gen.ts \
+ --client-import ../../clients/typescript/src/index.ts --check
status:
name: Build and Test
@@ -83,11 +84,11 @@ jobs:
exit 1
publish:
- if: github.event_name == 'release'
+ if: github.event_name == 'release' && !startsWith(github.event.release.tag_name, 'typescript-')
runs-on: ubuntu-latest
permissions:
contents: read
- id-token: write # OIDC token for NuGet trusted publishing
+ id-token: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -100,10 +101,14 @@ jobs:
- name: Restore
run: dotnet restore --locked-mode
- - name: Build and Pack
+ - name: Build and Pack JsonApiToolkit
+ if: ${{ !startsWith(github.event.release.tag_name, 'typegen-') }}
run: dotnet pack JsonApiToolkit/JsonApiToolkit.csproj -c Release --no-restore
- # Exchange OIDC token for a short-lived NuGet API key
+ - name: Build and Pack JsonApiToolkit.TypeGen
+ if: startsWith(github.event.release.tag_name, 'typegen-')
+ run: dotnet pack JsonApiToolkit.TypeGen/JsonApiToolkit.TypeGen.csproj -c Release --no-restore
+
- name: NuGet login
id: login
uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0
@@ -111,7 +116,7 @@ jobs:
user: ${{ secrets.NUGET_USER }}
- name: Publish to NuGet.org
- run: dotnet nuget push "JsonApiToolkit/bin/Release/*.nupkg"
+ run: dotnet nuget push "JsonApiToolkit*/bin/Release/*.nupkg"
--source https://api.nuget.org/v3/index.json
--api-key ${{ steps.login.outputs.NUGET_API_KEY }}
--skip-duplicate
diff --git a/.github/workflows/next-snapshot.yml b/.github/workflows/next-snapshot.yml
new file mode 100644
index 0000000..6ebd26b
--- /dev/null
+++ b/.github/workflows/next-snapshot.yml
@@ -0,0 +1,120 @@
+name: Next Snapshot
+
+on:
+ push:
+ branches:
+ - next
+
+concurrency:
+ group: next-snapshot
+ cancel-in-progress: false
+
+jobs:
+ changes:
+ name: Detect changes
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ outputs:
+ toolkit: ${{ steps.filter.outputs.toolkit }}
+ typegen: ${{ steps.filter.outputs.typegen }}
+ typescript: ${{ steps.filter.outputs.typescript }}
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+
+ - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
+ id: filter
+ with:
+ base: ${{ github.ref_name }}
+ filters: |
+ toolkit:
+ - 'JsonApiToolkit/**'
+ - 'Directory.Build.props'
+ typegen:
+ - 'JsonApiToolkit.TypeGen/**'
+ - 'Directory.Build.props'
+ typescript:
+ - 'clients/typescript/**'
+
+ dotnet:
+ name: Publish .NET Snapshot
+ needs: changes
+ if: needs.changes.outputs.toolkit == 'true' || needs.changes.outputs.typegen == 'true'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ id-token: write
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
+ with:
+ dotnet-version: 10.0.x
+
+ - name: Restore
+ run: dotnet restore --locked-mode
+
+ - name: Test
+ run: dotnet test --configuration Release --verbosity normal --no-restore
+
+ - name: Pack JsonApiToolkit
+ if: needs.changes.outputs.toolkit == 'true'
+ run: |
+ BASE=$(sed -n 's:.*\(.*\).*:\1:p' JsonApiToolkit/JsonApiToolkit.csproj)
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"
+ dotnet pack JsonApiToolkit/JsonApiToolkit.csproj -c Release --no-restore \
+ -p:Version="$MAJOR.$MINOR.$((PATCH + 1))-next.${{ github.run_number }}"
+
+ - name: Pack JsonApiToolkit.TypeGen
+ if: needs.changes.outputs.typegen == 'true'
+ run: |
+ BASE=$(sed -n 's:.*\(.*\).*:\1:p' JsonApiToolkit.TypeGen/JsonApiToolkit.TypeGen.csproj)
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"
+ dotnet pack JsonApiToolkit.TypeGen/JsonApiToolkit.TypeGen.csproj -c Release --no-restore \
+ -p:Version="$MAJOR.$MINOR.$((PATCH + 1))-next.${{ github.run_number }}"
+
+ - name: NuGet login
+ id: login
+ uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0
+ with:
+ user: ${{ secrets.NUGET_USER }}
+
+ - name: Publish to NuGet.org
+ run: dotnet nuget push "JsonApiToolkit*/bin/Release/*.nupkg"
+ --source https://api.nuget.org/v3/index.json
+ --api-key ${{ steps.login.outputs.NUGET_API_KEY }}
+ --skip-duplicate
+
+ typescript:
+ name: Publish TypeScript Snapshot
+ needs: changes
+ if: needs.changes.outputs.typescript == 'true'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ id-token: write
+ defaults:
+ run:
+ working-directory: clients/typescript
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+
+ - name: Setup Deno
+ uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2
+ with:
+ deno-version: v2.x
+
+ - name: Test
+ run: deno task test
+
+ - name: Set Snapshot Version
+ run: |
+ BASE=$(jq -r .version deno.json)
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE"
+ jq --arg v "$MAJOR.$MINOR.$((PATCH + 1))-next.${{ github.run_number }}" \
+ '.version = $v' deno.json > deno.json.tmp
+ mv deno.json.tmp deno.json
+
+ - name: Publish to JSR
+ run: deno publish --allow-dirty
diff --git a/.github/workflows/typescript-release.yml b/.github/workflows/typescript-release.yml
new file mode 100644
index 0000000..57a8918
--- /dev/null
+++ b/.github/workflows/typescript-release.yml
@@ -0,0 +1,35 @@
+name: TypeScript Release
+
+on:
+ release:
+ types: [published]
+
+concurrency:
+ group: ts-release-${{ github.ref }}
+ cancel-in-progress: false
+
+defaults:
+ run:
+ working-directory: clients/typescript
+
+jobs:
+ publish:
+ if: startsWith(github.event.release.tag_name, 'typescript-v')
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ id-token: write
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+
+ - name: Setup Deno
+ uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2
+ with:
+ deno-version: v2.x
+
+ - name: Test
+ run: deno task test
+
+ - name: Publish to JSR
+ run: deno publish
diff --git a/JsonApiToolkit.TypeGen.Tests/CliIntegrationTests.cs b/JsonApiToolkit.TypeGen.Tests/CliIntegrationTests.cs
index ff78c48..9fe43cb 100644
--- a/JsonApiToolkit.TypeGen.Tests/CliIntegrationTests.cs
+++ b/JsonApiToolkit.TypeGen.Tests/CliIntegrationTests.cs
@@ -26,9 +26,11 @@ public void Run_resolves_JsonApiResource_types_from_a_separately_built_assembly(
Assert.Contains("export interface Author", generated);
Assert.Contains("export interface Comment", generated);
Assert.Contains(
- "Article: { type: \"articles\", relationships: [\"author\", \"comments\"] }",
+ "export const Article: JsonApiResourceDescriptor = {",
generated
);
+ Assert.Contains(" toOne: [\"author\"],", generated);
+ Assert.Contains(" toMany: [\"comments\"],", generated);
// --check passes right after generation...
Assert.Equal(
diff --git a/JsonApiToolkit.TypeGen.Tests/TypeScriptEmitterTests.cs b/JsonApiToolkit.TypeGen.Tests/TypeScriptEmitterTests.cs
index ddf15de..3f09fa1 100644
--- a/JsonApiToolkit.TypeGen.Tests/TypeScriptEmitterTests.cs
+++ b/JsonApiToolkit.TypeGen.Tests/TypeScriptEmitterTests.cs
@@ -51,15 +51,27 @@ public void Generate_maps_attributes_and_relationships_and_skips_unmapped_types(
(typeof(Part), "parts"),
};
- var ts = TypeScriptEmitter.Generate(resources);
+ var ts = TypeScriptEmitter.Generate(resources, "@intility/json-api-client");
+ Assert.Contains(
+ "import type { JsonApiResourceDescriptor } from \"@intility/json-api-client\";",
+ ts
+ );
Assert.Contains("description: string | null;", ts);
Assert.Contains("retiredAt: string | null;", ts);
Assert.Contains("tags: string[];", ts);
Assert.Contains("ownerId: number;", ts);
Assert.Contains("owner: Owner | null;", ts);
Assert.Contains("parts: Part[];", ts);
- Assert.Contains("Widget: { type: \"widgets\", relationships: [\"owner\", \"parts\"] }", ts);
+
+ Assert.Contains("export const Widget: JsonApiResourceDescriptor = {", ts);
+ Assert.Contains(" type: \"widgets\",", ts);
+ Assert.Contains(
+ " attributes: [\"name\", \"description\", \"retiredAt\", \"tags\", \"ownerId\"],",
+ ts
+ );
+ Assert.Contains(" toOne: [\"owner\"],", ts);
+ Assert.Contains(" toMany: [\"parts\"],", ts);
// UnmappedThing has no [JsonApiResource]: the property is dropped, not guessed at.
Assert.DoesNotContain("extra", ts);
diff --git a/JsonApiToolkit.TypeGen/Cli.cs b/JsonApiToolkit.TypeGen/Cli.cs
index b128c8d..f615e59 100644
--- a/JsonApiToolkit.TypeGen/Cli.cs
+++ b/JsonApiToolkit.TypeGen/Cli.cs
@@ -14,6 +14,7 @@ public static int Run(string[] args)
{
string? assemblyPath = null;
string? outPath = null;
+ string clientImport = "@intility/json-api-client";
bool check = false;
for (int i = 0; i < args.Length; i++)
@@ -26,6 +27,9 @@ public static int Run(string[] args)
case "--out":
outPath = args[++i];
break;
+ case "--client-import":
+ clientImport = args[++i];
+ break;
case "--check":
check = true;
break;
@@ -38,7 +42,8 @@ public static int Run(string[] args)
if (assemblyPath is null || outPath is null)
{
Console.Error.WriteLine(
- "Usage: jsonapi-typegen --assembly --out [--check]"
+ "Usage: jsonapi-typegen --assembly --out "
+ + "[--client-import ] [--check]"
);
return 1;
}
@@ -61,7 +66,7 @@ public static int Run(string[] args)
return 1;
}
- string generated = TypeScriptEmitter.Generate(resources);
+ string generated = TypeScriptEmitter.Generate(resources, clientImport);
if (check)
{
diff --git a/JsonApiToolkit.TypeGen/JsonApiToolkit.TypeGen.csproj b/JsonApiToolkit.TypeGen/JsonApiToolkit.TypeGen.csproj
index 0bab50d..d3b4df2 100644
--- a/JsonApiToolkit.TypeGen/JsonApiToolkit.TypeGen.csproj
+++ b/JsonApiToolkit.TypeGen/JsonApiToolkit.TypeGen.csproj
@@ -9,12 +9,22 @@
jsonapi-typegen
Intility.JsonApiToolkit.TypeGen
JsonApiToolkit TypeGen
- 2.1.8
+ 0.1.0
Intility
Intility
Generates TypeScript resource types from [JsonApiResource]-attributed C# models.
+ jsonapi;json-api;typescript;codegen;dotnet-tool
+ https://github.com/intility/json-api-toolkit
+ git
+ https://github.com/intility/json-api-toolkit
+ intility-logo.png
+ README.md
MIT
+
+
+
+