From 28105c1906f09712f4b5fb79652debc55d330370 Mon Sep 17 00:00:00 2001
From: Oleg Khorsunenko <104910045+okhorsunenko-lula@users.noreply.github.com>
Date: Sat, 4 Feb 2023 02:19:58 +0100
Subject: [PATCH] Installed `fsdocs-tool` instead of legacy
`fsharp.formatting.commandtool`
---
.config/dotnet-tools.json | 2 +-
.github/workflows/publish_ci.yml | 18 +-
.github/workflows/publish_release.yml | 12 +-
FSharp.Data.GraphQL.sln | 155 +-
Prepare template project for packing.ps1 | 1 +
samples/relay-modern-starter-kit/.babelrc | 19 +
.../PATENTS | 2 +-
samples/relay-modern-starter-kit/README.md | 81 +
.../data/schema.json | 418 +-
samples/relay-modern-starter-kit/index.html | 16 +
.../package.json | 15 +-
.../scripts/jsonToGraphql.js | 11 +
samples/relay-modern-starter-kit/server.fsx | 169 +
samples/relay-modern-starter-kit/src/app.jsx | 32 +
.../src/components/user.jsx | 86 +
.../src/relayEnvironment.js | 34 +
.../webpack.config.js | 14 +-
samples/relay-modern-starter-kit/yarn.lock | 3556 ++++++++
samples/relay-starter-kit/.babelrc | 13 -
samples/relay-starter-kit/.gitignore | 5 -
samples/relay-starter-kit/LICENSE | 31 -
samples/relay-starter-kit/README.md | 34 -
samples/relay-starter-kit/index.html | 16 -
samples/relay-starter-kit/index.jsx | 59 -
samples/relay-starter-kit/package-lock.json | 7424 -----------------
samples/relay-starter-kit/server.fsx | 120 -
...rp.Data.GraphQL.Samples.StarWarsApi.fsproj | 6 +
samples/star-wars-api/Schema.fs | 262 +-
.../Connections.fs | 39 +-
.../FSharp.Data.GraphQL.Server.Relay.fsproj | 25 +
.../Node.fs | 2 +-
.../FSharp.Data.GraphQL.Server.fsproj | 3 +-
.../SwapiLocalProviderTests.fs | 135 +-
.../SwapiRemoteProviderTests.fs | 135 +-
.../introspection.json | 1521 +---
.../operation.graphql | 24 +-
.../AbstractionTests.fs | 2 +-
.../FSharp.Data.GraphQL.Tests.fsproj | 1 +
.../PropertyTrackerTests.fs | 2 +-
.../Relay/ConnectionTests.fs | 2 +-
.../Relay/NodeTests.fs | 2 +-
41 files changed, 4756 insertions(+), 9748 deletions(-)
create mode 100644 samples/relay-modern-starter-kit/.babelrc
rename samples/{relay-starter-kit => relay-modern-starter-kit}/PATENTS (98%)
create mode 100644 samples/relay-modern-starter-kit/README.md
rename samples/{relay-starter-kit => relay-modern-starter-kit}/data/schema.json (96%)
create mode 100644 samples/relay-modern-starter-kit/index.html
rename samples/{relay-starter-kit => relay-modern-starter-kit}/package.json (74%)
create mode 100644 samples/relay-modern-starter-kit/scripts/jsonToGraphql.js
create mode 100644 samples/relay-modern-starter-kit/server.fsx
create mode 100644 samples/relay-modern-starter-kit/src/app.jsx
create mode 100644 samples/relay-modern-starter-kit/src/components/user.jsx
create mode 100644 samples/relay-modern-starter-kit/src/relayEnvironment.js
rename samples/{relay-starter-kit => relay-modern-starter-kit}/webpack.config.js (64%)
create mode 100644 samples/relay-modern-starter-kit/yarn.lock
delete mode 100644 samples/relay-starter-kit/.babelrc
delete mode 100644 samples/relay-starter-kit/.gitignore
delete mode 100644 samples/relay-starter-kit/LICENSE
delete mode 100644 samples/relay-starter-kit/README.md
delete mode 100644 samples/relay-starter-kit/index.html
delete mode 100644 samples/relay-starter-kit/index.jsx
delete mode 100644 samples/relay-starter-kit/package-lock.json
delete mode 100644 samples/relay-starter-kit/server.fsx
rename src/{FSharp.Data.GraphQL.Server/Relay => FSharp.Data.GraphQL.Server.Relay}/Connections.fs (75%)
create mode 100644 src/FSharp.Data.GraphQL.Server.Relay/FSharp.Data.GraphQL.Server.Relay.fsproj
rename src/{FSharp.Data.GraphQL.Server/Relay => FSharp.Data.GraphQL.Server.Relay}/Node.fs (98%)
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 4b2d630d2..1a0c5db73 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -9,7 +9,7 @@
]
},
"fantomas": {
- "version": "5.1.4",
+ "version": "5.2.0",
"commands": [
"fantomas"
]
diff --git a/.github/workflows/publish_ci.yml b/.github/workflows/publish_ci.yml
index a098f8654..b2220aadd 100644
--- a/.github/workflows/publish_ci.yml
+++ b/.github/workflows/publish_ci.yml
@@ -7,13 +7,13 @@ on:
jobs:
publish:
-
+
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
-
+
- name: Set Build Version
run: |
$File = (
@@ -24,10 +24,10 @@ jobs:
$File.OwnerDocument.Save((Join-Path $PWD.ProviderPath Directory.Build.targets))
echo "VERSION=$version" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
shell: pwsh
-
+
- name: Install .NET Core
uses: actions/setup-dotnet@v3
-
+
- name: Add the GitHub source
run: dotnet nuget add source --username USERNAME --password ${{secrets.GITHUB_TOKEN}} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/fsprojects/index.json"
@@ -61,6 +61,14 @@ jobs:
run: |
dotnet nuget push nuget/*Server*.nupkg -s "github" -k ${{secrets.GITHUB_TOKEN}}
+ - name: Pack FSharp.Data.GraphQL.Server.Relay project
+ run: |
+ cd src/FSharp.Data.GraphQL.Server.Relay
+ dotnet pack --no-build --nologo --configuration Release /p:IsNuget=true -o ../../nuget
+ - name: Publish FSharp.Data.GraphQL.Server.Relay project to GitHub
+ run: |
+ dotnet nuget push nuget/*Server.Relay*.nupkg -s "github" -k ${{secrets.GITHUB_TOKEN}}
+
- name: Pack FSharp.Data.GraphQL.Server.Middleware project
run: |
cd src/FSharp.Data.GraphQL.Server.Middleware
@@ -82,4 +90,4 @@ jobs:
run: |
$path = "nuget/FSharp.Data.GraphQL.ProjectTemplates.$Env:VERSION.nupkg"
dotnet nuget push $path -s "github" -k ${{secrets.GITHUB_TOKEN}}
- shell: pwsh
\ No newline at end of file
+ shell: pwsh
diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml
index fb690cc91..560ccbd77 100644
--- a/.github/workflows/publish_release.yml
+++ b/.github/workflows/publish_release.yml
@@ -15,7 +15,7 @@ jobs:
with:
# This is necessary so that we have the tags.
fetch-depth: 0
-
+
- name: Set Build Version
run: |
$version = "$env:GITHUB_REF_NAME"
@@ -60,6 +60,14 @@ jobs:
run: |
dotnet nuget push nuget/*Server*.nupkg -k ${{secrets.NUGET_SECRET}}
+ - name: Pack FSharp.Data.GraphQL.Server.Relay project
+ run: |
+ cd src/FSharp.Data.GraphQL.Server.Relay
+ dotnet pack --no-build --nologo --configuration Release /p:IsNuget=true -o ../../nuget
+ - name: Publish FSharp.Data.GraphQL.Server.Relay project to NuGet
+ run: |
+ dotnet nuget push nuget/*Server.Relay*.nupkg -k ${{secrets.NUGET_SECRET}}
+
- name: Pack FSharp.Data.GraphQL.Server.Middleware project
run: |
cd src/FSharp.Data.GraphQL.Server.Middleware
@@ -81,4 +89,4 @@ jobs:
run: |
$path = "nuget/FSharp.Data.GraphQL.ProjectTemplates.$Env:VERSION.nupkg"
dotnet nuget push $path -k ${{secrets.NUGET_SECRET}}
- shell: pwsh
\ No newline at end of file
+ shell: pwsh
diff --git a/FSharp.Data.GraphQL.sln b/FSharp.Data.GraphQL.sln
index e7fda4139..6dbf20471 100644
--- a/FSharp.Data.GraphQL.sln
+++ b/FSharp.Data.GraphQL.sln
@@ -3,10 +3,59 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32811.315
MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E3330910-8B6C-4191-8046-D6D57FBC39B1}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ Directory.Build.targets = Directory.Build.targets
+ global.json = global.json
+ LICENSE.txt = LICENSE.txt
+ Packages.props = Packages.props
+ Prepare template project for packing.ps1 = Prepare template project for packing.ps1
+ README.md = README.md
+ RELEASE_NOTES.md = RELEASE_NOTES.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{313AC7F5-4282-4779-8FEF-1536B4145860}"
+ ProjectSection(SolutionItems) = preProject
+ .github\workflows\publish_ci.yml = .github\workflows\publish_ci.yml
+ .github\workflows\publish_release.yml = .github\workflows\publish_release.yml
+ .github\workflows\pull_request.yml = .github\workflows\pull_request.yml
+ EndProjectSection
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "files", "files", "{56640EAF-82A6-4439-AD14-69F44A90DA99}"
+ ProjectSection(SolutionItems) = preProject
+ docs\files\introspection_query.graphql = docs\files\introspection_query.graphql
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "img", "img", "{78D10788-601D-4D53-808B-36661911EDD1}"
+ ProjectSection(SolutionItems) = preProject
+ docs\files\img\logo-template.pdn = docs\files\img\logo-template.pdn
+ docs\files\img\logo.png = docs\files\img\logo.png
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "star-wars-api", "star-wars-api", "{F66BEE6C-0CB7-4F39-97E4-243F797E8723}"
+EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Samples.StarWarsApi", "samples\star-wars-api\FSharp.Data.GraphQL.Samples.StarWarsApi.fsproj", "{B837B3ED-83CE-446F-A4E5-44CB06AA6505}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BEFD8748-2467-45F9-A4AD-B450B12D5F78}"
+EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Shared", "src\FSharp.Data.GraphQL.Shared\FSharp.Data.GraphQL.Shared.fsproj", "{6768EA38-1335-4B8E-BC09-CCDED1F9AAF6}"
+EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Server", "src\FSharp.Data.GraphQL.Server\FSharp.Data.GraphQL.Server.fsproj", "{474179D3-0090-49E9-88F8-2971C0966077}"
EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Server.Relay", "src\FSharp.Data.GraphQL.Server.Relay\FSharp.Data.GraphQL.Server.Relay.fsproj", "{E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}"
+EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Server.Middleware", "src\FSharp.Data.GraphQL.Server.Middleware\FSharp.Data.GraphQL.Server.Middleware.fsproj", "{8FB23F61-77CB-42C7-8EEC-B22D7C4E4067}"
+EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Client.DesignTime", "src\FSharp.Data.GraphQL.Client.DesignTime\FSharp.Data.GraphQL.Client.DesignTime.fsproj", "{B075CD55-CEA4-4C30-A088-48319AADF070}"
+EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Client", "src\FSharp.Data.GraphQL.Client\FSharp.Data.GraphQL.Client.fsproj", "{F7858DA7-E067-486B-9E9C-697F0A56C620}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B075CD55-CEA4-4C30-A088-48319AADF070} = {B075CD55-CEA4-4C30-A088-48319AADF070}
+ EndProjectSection
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}"
ProjectSection(SolutionItems) = preProject
build.fsx = build.fsx
@@ -32,6 +81,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Tests", "tests\FSharp.Data.GraphQL.Tests\FSharp.Data.GraphQL.Tests.fsproj", "{54AAFE43-FA5F-485A-AD40-0240165FC633}"
EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Benchmarks", "tests\FSharp.Data.GraphQL.Benchmarks\FSharp.Data.GraphQL.Benchmarks.fsproj", "{A6A162DF-9FBB-4C2A-913F-FD5FED35A09B}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B0C25450-74BF-40C2-9E02-09AADBAE2C2F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "graphiql-client", "graphiql-client", "{CAE5916B-1415-4982-B705-7318D77C029C}"
@@ -44,21 +95,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "graphiql-client", "graphiql
samples\graphiql-client\webpack.config.js = samples\graphiql-client\webpack.config.js
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "relay-starter-kit", "relay-starter-kit", "{9B25360F-2CE4-43D2-AFF0-5EAA693E98F7}"
- ProjectSection(SolutionItems) = preProject
- samples\relay-starter-kit\.babelrc = samples\relay-starter-kit\.babelrc
- samples\relay-starter-kit\index.html = samples\relay-starter-kit\index.html
- samples\relay-starter-kit\index.jsx = samples\relay-starter-kit\index.jsx
- samples\relay-starter-kit\package.json = samples\relay-starter-kit\package.json
- samples\relay-starter-kit\server.fsx = samples\relay-starter-kit\server.fsx
- samples\relay-starter-kit\webpack.config.js = samples\relay-starter-kit\webpack.config.js
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{E7139F5F-22CA-4392-8C1C-481A39EEB554}"
- ProjectSection(SolutionItems) = preProject
- samples\relay-starter-kit\data\schema.json = samples\relay-starter-kit\data\schema.json
- EndProjectSection
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{DFA5AAFF-31B8-4203-822C-8ACC4D7A7D74}"
ProjectSection(SolutionItems) = preProject
samples\relay-starter-kit\build\babelRelayPlugin.js = samples\relay-starter-kit\build\babelRelayPlugin.js
@@ -83,36 +119,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client-provider", "client-p
samples\client-provider\using_query_file.fsx = samples\client-provider\using_query_file.fsx
EndProjectSection
EndProject
-Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Shared", "src\FSharp.Data.GraphQL.Shared\FSharp.Data.GraphQL.Shared.fsproj", "{6768EA38-1335-4B8E-BC09-CCDED1F9AAF6}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BEFD8748-2467-45F9-A4AD-B450B12D5F78}"
-EndProject
-Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Server.Middleware", "src\FSharp.Data.GraphQL.Server.Middleware\FSharp.Data.GraphQL.Server.Middleware.fsproj", "{8FB23F61-77CB-42C7-8EEC-B22D7C4E4067}"
-EndProject
-Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Benchmarks", "tests\FSharp.Data.GraphQL.Benchmarks\FSharp.Data.GraphQL.Benchmarks.fsproj", "{A6A162DF-9FBB-4C2A-913F-FD5FED35A09B}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "files", "files", "{56640EAF-82A6-4439-AD14-69F44A90DA99}"
- ProjectSection(SolutionItems) = preProject
- docs\files\introspection_query.graphql = docs\files\introspection_query.graphql
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "img", "img", "{78D10788-601D-4D53-808B-36661911EDD1}"
- ProjectSection(SolutionItems) = preProject
- docs\files\img\logo-template.pdn = docs\files\img\logo-template.pdn
- docs\files\img\logo.png = docs\files\img\logo.png
- EndProjectSection
-EndProject
-Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Client.DesignTime", "src\FSharp.Data.GraphQL.Client.DesignTime\FSharp.Data.GraphQL.Client.DesignTime.fsproj", "{B075CD55-CEA4-4C30-A088-48319AADF070}"
-EndProject
-Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Client", "src\FSharp.Data.GraphQL.Client\FSharp.Data.GraphQL.Client.fsproj", "{F7858DA7-E067-486B-9E9C-697F0A56C620}"
- ProjectSection(ProjectDependencies) = postProject
- {B075CD55-CEA4-4C30-A088-48319AADF070} = {B075CD55-CEA4-4C30-A088-48319AADF070}
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "star-wars-api", "star-wars-api", "{F66BEE6C-0CB7-4F39-97E4-243F797E8723}"
-EndProject
-Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Samples.StarWarsApi", "samples\star-wars-api\FSharp.Data.GraphQL.Samples.StarWarsApi.fsproj", "{B837B3ED-83CE-446F-A4E5-44CB06AA6505}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "file-upload", "file-upload", "{A47968E2-CDD1-4BCF-9093-D0C5225A815B}"
ProjectSection(SolutionItems) = preProject
samples\client-provider\file-upload\multiple_files_upload.fsx = samples\client-provider\file-upload\multiple_files_upload.fsx
@@ -134,23 +140,35 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "server", "server", "{9D5C46
samples\client-provider\file-upload\server\types.mjs = samples\client-provider\file-upload\server\types.mjs
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E3330910-8B6C-4191-8046-D6D57FBC39B1}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "relay-modern-starter-kit", "relay-modern-starter-kit", "{600D4BE2-FCE0-4684-AC6F-2DC829B395BA}"
ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- Directory.Build.targets = Directory.Build.targets
- global.json = global.json
- LICENSE.txt = LICENSE.txt
- Packages.props = Packages.props
- Prepare template project for packing.ps1 = Prepare template project for packing.ps1
- README.md = README.md
- RELEASE_NOTES.md = RELEASE_NOTES.md
+ samples\relay-modern-starter-kit\.babelrc = samples\relay-modern-starter-kit\.babelrc
+ samples\relay-modern-starter-kit\index.html = samples\relay-modern-starter-kit\index.html
+ samples\relay-modern-starter-kit\package.json = samples\relay-modern-starter-kit\package.json
+ samples\relay-modern-starter-kit\server.fsx = samples\relay-modern-starter-kit\server.fsx
+ samples\relay-modern-starter-kit\webpack.config.js = samples\relay-modern-starter-kit\webpack.config.js
+ samples\relay-modern-starter-kit\yarn.lock = samples\relay-modern-starter-kit\yarn.lock
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{313AC7F5-4282-4779-8FEF-1536B4145860}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{E9DACEDD-1166-4142-9726-33CCA56218BA}"
ProjectSection(SolutionItems) = preProject
- .github\workflows\publish_ci.yml = .github\workflows\publish_ci.yml
- .github\workflows\publish_release.yml = .github\workflows\publish_release.yml
- .github\workflows\pull_request.yml = .github\workflows\pull_request.yml
+ samples\relay-modern-starter-kit\data\schema.json = samples\relay-modern-starter-kit\data\schema.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A8F031E0-2BD5-4BAE-830A-60CBA76A047D}"
+ ProjectSection(SolutionItems) = preProject
+ samples\relay-modern-starter-kit\src\app.jsx = samples\relay-modern-starter-kit\src\app.jsx
+ samples\relay-modern-starter-kit\src\relayEnvironment.js = samples\relay-modern-starter-kit\src\relayEnvironment.js
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{6EEA0E79-693F-4D4F-B55B-DB0C64EBDA45}"
+ ProjectSection(SolutionItems) = preProject
+ jsonToGraphql.js = jsonToGraphql.js
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "components", "components", "{7AA3516E-60F5-4969-878F-4E3DCF3E63A3}"
+ ProjectSection(SolutionItems) = preProject
+ user.jsx = user.jsx
EndProjectSection
EndProject
Global
@@ -259,6 +277,18 @@ Global
{B837B3ED-83CE-446F-A4E5-44CB06AA6505}.Release|x64.Build.0 = Release|Any CPU
{B837B3ED-83CE-446F-A4E5-44CB06AA6505}.Release|x86.ActiveCfg = Release|Any CPU
{B837B3ED-83CE-446F-A4E5-44CB06AA6505}.Release|x86.Build.0 = Release|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Debug|x64.Build.0 = Debug|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Debug|x86.Build.0 = Debug|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Release|x64.ActiveCfg = Release|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Release|x64.Build.0 = Release|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Release|x86.ActiveCfg = Release|Any CPU
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -269,9 +299,6 @@ Global
{8E6D5255-776D-4B61-85F9-73C37AA1FB9A} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}
{54AAFE43-FA5F-485A-AD40-0240165FC633} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
{CAE5916B-1415-4982-B705-7318D77C029C} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
- {9B25360F-2CE4-43D2-AFF0-5EAA693E98F7} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
- {E7139F5F-22CA-4392-8C1C-481A39EEB554} = {9B25360F-2CE4-43D2-AFF0-5EAA693E98F7}
- {DFA5AAFF-31B8-4203-822C-8ACC4D7A7D74} = {9B25360F-2CE4-43D2-AFF0-5EAA693E98F7}
{3D948D55-3CD2-496D-A04C-3B4E7BB69140} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
{6768EA38-1335-4B8E-BC09-CCDED1F9AAF6} = {BEFD8748-2467-45F9-A4AD-B450B12D5F78}
{8FB23F61-77CB-42C7-8EEC-B22D7C4E4067} = {BEFD8748-2467-45F9-A4AD-B450B12D5F78}
@@ -284,6 +311,12 @@ Global
{B837B3ED-83CE-446F-A4E5-44CB06AA6505} = {F66BEE6C-0CB7-4F39-97E4-243F797E8723}
{A47968E2-CDD1-4BCF-9093-D0C5225A815B} = {3D948D55-3CD2-496D-A04C-3B4E7BB69140}
{9D5C46E8-0C07-4384-8E58-903F7C2C7171} = {A47968E2-CDD1-4BCF-9093-D0C5225A815B}
+ {600D4BE2-FCE0-4684-AC6F-2DC829B395BA} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
+ {E9DACEDD-1166-4142-9726-33CCA56218BA} = {600D4BE2-FCE0-4684-AC6F-2DC829B395BA}
+ {A8F031E0-2BD5-4BAE-830A-60CBA76A047D} = {600D4BE2-FCE0-4684-AC6F-2DC829B395BA}
+ {6EEA0E79-693F-4D4F-B55B-DB0C64EBDA45} = {600D4BE2-FCE0-4684-AC6F-2DC829B395BA}
+ {7AA3516E-60F5-4969-878F-4E3DCF3E63A3} = {A8F031E0-2BD5-4BAE-830A-60CBA76A047D}
+ {E011A3B2-3D96-48E3-AF5F-DA544FF5C5FE} = {BEFD8748-2467-45F9-A4AD-B450B12D5F78}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C5B9895C-9DF8-4557-8D44-7D0C4C31F86E}
diff --git a/Prepare template project for packing.ps1 b/Prepare template project for packing.ps1
index cb859ffb3..e3abcd8de 100644
--- a/Prepare template project for packing.ps1
+++ b/Prepare template project for packing.ps1
@@ -10,6 +10,7 @@ $version = $dirBuildTargets.SelectSingleNode("//PropertyGroup[@Label='NuGet']/Ve
[xml]$fsharpPackages = @"
+
diff --git a/samples/relay-modern-starter-kit/.babelrc b/samples/relay-modern-starter-kit/.babelrc
new file mode 100644
index 000000000..0afac8c1c
--- /dev/null
+++ b/samples/relay-modern-starter-kit/.babelrc
@@ -0,0 +1,19 @@
+{
+ "passPerPreset": true,
+ "presets": [
+ {
+ "plugins": [
+ ["relay", {
+ "schema": "data/schema.json"}
+ ],
+ "syntax-async-functions",
+ "transform-class-properties",
+ "transform-object-rest-spread",
+ "react-require"
+ ]
+ },
+ "react",
+ "es2015",
+ "stage-0"
+ ]
+}
\ No newline at end of file
diff --git a/samples/relay-starter-kit/PATENTS b/samples/relay-modern-starter-kit/PATENTS
similarity index 98%
rename from samples/relay-starter-kit/PATENTS
rename to samples/relay-modern-starter-kit/PATENTS
index be39fb39a..e59a46f0c 100644
--- a/samples/relay-starter-kit/PATENTS
+++ b/samples/relay-modern-starter-kit/PATENTS
@@ -30,4 +30,4 @@ necessarily infringed by the Software standing alone.
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
or contributory infringement or inducement to infringe any patent, including a
-cross-claim or counterclaim.
+cross-claim or counterclaim.
\ No newline at end of file
diff --git a/samples/relay-modern-starter-kit/README.md b/samples/relay-modern-starter-kit/README.md
new file mode 100644
index 000000000..da33e3c24
--- /dev/null
+++ b/samples/relay-modern-starter-kit/README.md
@@ -0,0 +1,81 @@
+# Relay Modern Starter Kit with Pagination
+
+This kit includes an app server, a GraphQL server, and a transpiler that you can use to get started building an app with Relay. For a walkthrough, see the [Relay tutorial](https://facebook.github.io/relay/docs/tutorial.html).
+
+Few changes have been made to the original starter kit. It is now compatible with the [Relay Modern](https://facebook.github.io/relay/docs/relay-modern.html) API version. It also uses a [PaginationContainer](https://facebook.github.io/relay/docs/PaginationContainer.html) for item retrieving.
+
+## Installation
+
+First install required npm modules:
+
+```
+npm install
+```
+
+Generate JavaScript sources of Relay-wrapped components by executing:
+
+```
+npm run relay
+```
+
+## Running
+
+Start the GraphQL server by executing:
+
+```
+fsharpi server.fsx
+```
+
+Start the Relay application server:
+
+```
+npm start
+```
+
+Visit `localhost:8090` in your browser in order to access the application.
+
+## Developing
+
+### GraphQL Server
+
+Following information supposed to get you started with modification of the GraphQL server.
+
+#### Debugging
+
+The sample contains a `server.fs` copy of the server and an F# project file which can be used for debugging with mono:
+
+```
+xbuild && mono --debug --debugger-agent=transport=dt_socket,server=y,address=127.0.0.1:55555 ./bin/Debug/mono/FSharp.Data.GraphQL.ModernRelay.exe
+```
+
+This will start the server awaiting for the mono debugger to be attached.
+
+#### Uri
+
+By default the server will start on `localhost:8083`. This can be modified by changing `address` and `port` in `server.fsx` or `server.fs` respectively. Changing this settings requires adjustment of `graphqlServerUri` in `./src/relayEnvironment.jsx`.
+
+### Relay Application
+
+#### Schema modification
+
+Each time the schema is modified in the `server.fsx` GraphQL server, a new schema file has to be generated on the Relay application side.
+
+Accessing the `localhost:8083` in your browser will yield an introspection reply containing the schema of the database. Save this response to `./data/schema.json` whenever the schema is getting changed.
+
+Relay API has to know the path to the schema file. `.babelrc` contains this information by setting the `relay` plugin with `schema` option. Adjust this if the path to schema should change.
+
+The generated `./data/schema.json` or `./data/schema.graphql` (see optional below) file is used for the ahead-of-time compilation by Relay Modern compiler. The compilation process should be triggered by executing:
+
+```
+npm run relay
+```
+
+The command checks relevant `.jsx` and `.js` files in `./src` folder and generates their compiled in `__generated__` for defined containers. Those are e.g. [FragmentContainer](https://facebook.github.io/relay/docs/fragment-container.html) or the root Relay tree [QueryRenderer](https://facebook.github.io/relay/docs/query-renderer.html).
+
+#### Optional
+
+There are two accepted schema formats: `.json` and `.graphql`. The conversion to the latter can be done by executing `npm run json-to-graphql`. Input and output files can be adjusted in `./scripts/jsonToGraphql.js`.
+
+## License
+
+Relay Starter Kit is [BSD licensed](./LICENSE). We also provide an additional [patent grant](./PATENTS).
\ No newline at end of file
diff --git a/samples/relay-starter-kit/data/schema.json b/samples/relay-modern-starter-kit/data/schema.json
similarity index 96%
rename from samples/relay-starter-kit/data/schema.json
rename to samples/relay-modern-starter-kit/data/schema.json
index 3d2c5d0d0..cca541efb 100644
--- a/samples/relay-starter-kit/data/schema.json
+++ b/samples/relay-modern-starter-kit/data/schema.json
@@ -1,4 +1,5 @@
{
+ "documentId": 577680162,
"data": {
"__schema": {
"queryType": {
@@ -17,6 +18,16 @@
"enumValues": null,
"possibleTypes": null
},
+ {
+ "kind": "SCALAR",
+ "name": "Date",
+ "description": "The `Date` scalar type represents a Date value with Time component. The Date type appears in a JSON response as a String representation compatible with ISO-8601 format.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
{
"kind": "SCALAR",
"name": "Float",
@@ -90,6 +101,18 @@
"name": "PageInfo",
"description": "Information about pagination in a connection.",
"fields": [
+ {
+ "name": "endCursor",
+ "description": "When paginating forwards, the cursor to continue.",
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "hasNextPage",
"description": "When paginating forwards, are there more items?",
@@ -133,18 +156,6 @@
},
"isDeprecated": false,
"deprecationReason": null
- },
- {
- "name": "endCursor",
- "description": "When paginating forwards, the cursor to continue.",
- "args": [],
- "type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- },
- "isDeprecated": false,
- "deprecationReason": null
}
],
"inputFields": null,
@@ -165,9 +176,13 @@
"name": "id",
"description": "Identifier of an object",
"type": {
- "kind": "SCALAR",
- "name": "ID",
- "ofType": null
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ }
},
"defaultValue": null
}
@@ -212,6 +227,16 @@
"enumValues": null,
"possibleTypes": null
},
+ {
+ "kind": "SCALAR",
+ "name": "URI",
+ "description": "The `URI` scalar type represents a string resource identifier compatible with URI standard. The URI type appears in a JSON response as a String.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
{
"kind": "OBJECT",
"name": "User",
@@ -295,13 +320,9 @@
}
],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "OBJECT",
- "name": "WidgetConnection",
- "ofType": null
- }
+ "kind": "OBJECT",
+ "name": "WidgetConnection",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -373,13 +394,24 @@
"description": "A connection from an object to a list of objects of type Widget",
"fields": [
{
- "name": "totalCount",
- "description": "A count of the total number of objects in this connection, ignoring pagination. This allows a client to fetch the first five objects by passing \\\"5\\\" as the argument to `first`, then fetch the total count so it could display \\\"5 of 83\\\", for example. In cases where we employ infinite scrolling or don't have an exact count of entries, this field will return `null`.",
+ "name": "edges",
+ "description": "Information to aid in pagination.",
"args": [],
"type": {
- "kind": "SCALAR",
- "name": "Int",
- "ofType": null
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "WidgetEdge"
+ }
+ }
+ }
},
"isDeprecated": false,
"deprecationReason": null
@@ -401,24 +433,13 @@
"deprecationReason": null
},
{
- "name": "edges",
- "description": "Information to aid in pagination.",
+ "name": "totalCount",
+ "description": "A count of the total number of objects in this connection, ignoring pagination. This allows a client to fetch the first five objects by passing \\\"5\\\" as the argument to `first`, then fetch the total count so it could display \\\"5 of 83\\\", for example. In cases where we employ infinite scrolling or don't have an exact count of entries, this field will return `null`.",
"args": [],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "LIST",
- "name": null,
- "ofType": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "OBJECT",
- "name": "WidgetEdge"
- }
- }
- }
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -475,19 +496,26 @@
{
"kind": "OBJECT",
"name": "__Directive",
- "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document. In some cases, you need to provide options to alter GraphQLâ\u0080\u0099s execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.",
+ "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document. In some cases, you need to provide options to alter GraphQL’s execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.",
"fields": [
{
- "name": "name",
+ "name": "args",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "__InputValue"
+ }
+ }
}
},
"isDeprecated": false,
@@ -529,30 +557,23 @@
"deprecationReason": null
},
{
- "name": "args",
+ "name": "name",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "LIST",
- "name": null,
- "ofType": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "OBJECT",
- "name": "__InputValue"
- }
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
- "name": "onOperation",
+ "name": "onField",
"description": null,
"args": [],
"type": {
@@ -584,7 +605,7 @@
"deprecationReason": null
},
{
- "name": "onField",
+ "name": "onOperation",
"description": null,
"args": [],
"type": {
@@ -664,17 +685,13 @@
"description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.",
"fields": [
{
- "name": "name",
+ "name": "deprecationReason",
"description": null,
"args": [],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -708,13 +725,17 @@
"deprecationReason": null
},
{
- "name": "deprecationReason",
+ "name": "name",
"description": null,
"args": [],
"type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
},
"isDeprecated": false,
"deprecationReason": null
@@ -731,23 +752,30 @@
"description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.",
"fields": [
{
- "name": "name",
+ "name": "args",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "__InputValue"
+ }
+ }
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
- "name": "description",
+ "name": "deprecationReason",
"description": null,
"args": [],
"type": {
@@ -759,38 +787,27 @@
"deprecationReason": null
},
{
- "name": "args",
+ "name": "description",
"description": null,
"args": [],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "LIST",
- "name": null,
- "ofType": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "OBJECT",
- "name": "__InputValue"
- }
- }
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
- "name": "type",
+ "name": "isDeprecated",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "OBJECT",
- "name": "__Type",
+ "kind": "SCALAR",
+ "name": "Boolean",
"ofType": null
}
},
@@ -798,7 +815,7 @@
"deprecationReason": null
},
{
- "name": "isDeprecated",
+ "name": "name",
"description": null,
"args": [],
"type": {
@@ -806,7 +823,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
- "name": "Boolean",
+ "name": "String",
"ofType": null
}
},
@@ -814,13 +831,17 @@
"deprecationReason": null
},
{
- "name": "deprecationReason",
+ "name": "type",
"description": null,
"args": [],
"type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "__Type",
+ "ofType": null
+ }
},
"isDeprecated": false,
"deprecationReason": null
@@ -837,17 +858,13 @@
"description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.",
"fields": [
{
- "name": "name",
+ "name": "defaultValue",
"description": null,
"args": [],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -865,15 +882,15 @@
"deprecationReason": null
},
{
- "name": "type",
+ "name": "name",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "OBJECT",
- "name": "__Type",
+ "kind": "SCALAR",
+ "name": "String",
"ofType": null
}
},
@@ -881,13 +898,17 @@
"deprecationReason": null
},
{
- "name": "defaultValue",
+ "name": "type",
"description": null,
"args": [],
"type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "__Type",
+ "ofType": null
+ }
},
"isDeprecated": false,
"deprecationReason": null
@@ -904,8 +925,8 @@
"description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.",
"fields": [
{
- "name": "types",
- "description": "A list of all types supported by this server.",
+ "name": "directives",
+ "description": "A list of all directives supported by this server.",
"args": [],
"type": {
"kind": "NON_NULL",
@@ -918,7 +939,7 @@
"name": null,
"ofType": {
"kind": "OBJECT",
- "name": "__Type"
+ "name": "__Directive"
}
}
}
@@ -926,6 +947,18 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "mutationType",
+ "description": "If this server supports mutation, the type that mutation operations will be rooted at.",
+ "args": [],
+ "type": {
+ "kind": "OBJECT",
+ "name": "__Type",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "queryType",
"description": "The type that query operations will be rooted at.",
@@ -942,18 +975,6 @@
"isDeprecated": false,
"deprecationReason": null
},
- {
- "name": "mutationType",
- "description": "If this server supports mutation, the type that mutation operations will be rooted at.",
- "args": [],
- "type": {
- "kind": "OBJECT",
- "name": "__Type",
- "ofType": null
- },
- "isDeprecated": false,
- "deprecationReason": null
- },
{
"name": "subscriptionType",
"description": "If this server support subscription, the type that subscription operations will be rooted at.",
@@ -967,8 +988,8 @@
"deprecationReason": null
},
{
- "name": "directives",
- "description": "A list of all directives supported by this server.",
+ "name": "types",
+ "description": "A list of all types supported by this server.",
"args": [],
"type": {
"kind": "NON_NULL",
@@ -981,7 +1002,7 @@
"name": null,
"ofType": {
"kind": "OBJECT",
- "name": "__Directive"
+ "name": "__Type"
}
}
}
@@ -1000,34 +1021,6 @@
"name": "__Type",
"description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum. Depending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.",
"fields": [
- {
- "name": "kind",
- "description": null,
- "args": [],
- "type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "ENUM",
- "name": "__TypeKind",
- "ofType": null
- }
- },
- "isDeprecated": false,
- "deprecationReason": null
- },
- {
- "name": "name",
- "description": null,
- "args": [],
- "type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- },
- "isDeprecated": false,
- "deprecationReason": null
- },
{
"name": "description",
"description": null,
@@ -1041,7 +1034,7 @@
"deprecationReason": null
},
{
- "name": "fields",
+ "name": "enumValues",
"description": null,
"args": [
{
@@ -1067,7 +1060,7 @@
"name": null,
"ofType": {
"kind": "OBJECT",
- "name": "__Field",
+ "name": "__EnumValue",
"ofType": null
}
}
@@ -1076,9 +1069,24 @@
"deprecationReason": null
},
{
- "name": "interfaces",
+ "name": "fields",
"description": null,
- "args": [],
+ "args": [
+ {
+ "name": "includeDeprecated",
+ "description": null,
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "defaultValue": "False"
+ }
+ ],
"type": {
"kind": "LIST",
"name": null,
@@ -1087,7 +1095,7 @@
"name": null,
"ofType": {
"kind": "OBJECT",
- "name": "__Type",
+ "name": "__Field",
"ofType": null
}
}
@@ -1096,7 +1104,7 @@
"deprecationReason": null
},
{
- "name": "possibleTypes",
+ "name": "inputFields",
"description": null,
"args": [],
"type": {
@@ -1107,7 +1115,7 @@
"name": null,
"ofType": {
"kind": "OBJECT",
- "name": "__Type",
+ "name": "__InputValue",
"ofType": null
}
}
@@ -1116,24 +1124,9 @@
"deprecationReason": null
},
{
- "name": "enumValues",
+ "name": "interfaces",
"description": null,
- "args": [
- {
- "name": "includeDeprecated",
- "description": null,
- "type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "Boolean",
- "ofType": null
- }
- },
- "defaultValue": "False"
- }
- ],
+ "args": [],
"type": {
"kind": "LIST",
"name": null,
@@ -1142,7 +1135,7 @@
"name": null,
"ofType": {
"kind": "OBJECT",
- "name": "__EnumValue",
+ "name": "__Type",
"ofType": null
}
}
@@ -1151,25 +1144,33 @@
"deprecationReason": null
},
{
- "name": "inputFields",
+ "name": "kind",
"description": null,
"args": [],
"type": {
- "kind": "LIST",
+ "kind": "NON_NULL",
"name": null,
"ofType": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "OBJECT",
- "name": "__InputValue",
- "ofType": null
- }
+ "kind": "ENUM",
+ "name": "__TypeKind",
+ "ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "name",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "ofType",
"description": null,
@@ -1181,6 +1182,26 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "possibleTypes",
+ "description": null,
+ "args": [],
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "__Type",
+ "ofType": null
+ }
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
@@ -1301,6 +1322,5 @@
}
]
}
- },
- "errors": null
+ }
}
diff --git a/samples/relay-modern-starter-kit/index.html b/samples/relay-modern-starter-kit/index.html
new file mode 100644
index 000000000..0f7ec9cbf
--- /dev/null
+++ b/samples/relay-modern-starter-kit/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/relay-starter-kit/package.json b/samples/relay-modern-starter-kit/package.json
similarity index 74%
rename from samples/relay-starter-kit/package.json
rename to samples/relay-modern-starter-kit/package.json
index cfc0b8ed2..9e690d8df 100644
--- a/samples/relay-starter-kit/package.json
+++ b/samples/relay-modern-starter-kit/package.json
@@ -1,21 +1,22 @@
{
- "name": "relay-starter-kit",
+ "name": "modern-relay-starter-kit",
"private": true,
"description": "A quick way to get up and running with Relay",
"repository": "facebook/relay-starter-kit",
"version": "0.1.0",
"scripts": {
"start": "npm run serve | npm run dev",
- "update-schema": "babel-node ./scripts/updateSchema.js",
"serve": "./node_modules/.bin/http-server -p 8080",
- "dev": "webpack-dev-server --progress --colors --port 8090"
+ "dev": "webpack-dev-server --progress --colors --port 8090",
+ "relay": "relay-compiler --src ./src --schema data/schema.graphql --extensions jsx js",
+ "json-to-graphql": "babel-node ./scripts/jsonToGraphql.js"
},
"dependencies": {
"graphql": "^0.6.0",
- "graphql-relay": "0.4.1",
+ "graphql-relay": "0.6.0",
"react": "^15.0.2",
"react-dom": "^15.0.2",
- "react-relay": "0.8.1"
+ "react-relay": "dev"
},
"peerDependencies": {},
"devDependencies": {
@@ -23,11 +24,12 @@
"babel-core": "^6.8.0",
"babel-eslint": "6.0.2",
"babel-loader": "^6.2.4",
- "babel-polyfill": "6.7.4",
"babel-plugin-react-require": "^2.1.0",
+ "babel-plugin-relay": "dev",
"babel-plugin-syntax-async-functions": "6.5.0",
"babel-plugin-transform-class-properties": "^6.8.0",
"babel-plugin-transform-object-rest-spread": "^6.6.5",
+ "babel-polyfill": "6.7.4",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "6.5.0",
@@ -36,6 +38,7 @@
"jsx-loader": "^0.13.2",
"react": "^15.0.2",
"react-dom": "^15.0.2",
+ "relay-compiler": "dev",
"webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1"
}
diff --git a/samples/relay-modern-starter-kit/scripts/jsonToGraphql.js b/samples/relay-modern-starter-kit/scripts/jsonToGraphql.js
new file mode 100644
index 000000000..22ecbf336
--- /dev/null
+++ b/samples/relay-modern-starter-kit/scripts/jsonToGraphql.js
@@ -0,0 +1,11 @@
+var fs = require('fs');
+
+const {
+ buildClientSchema,
+ printSchema
+} = require('graphql/utilities');
+
+fs.readFile('./data/schema.json', "utf8", (err, str) => {
+ if (err) throw err;
+ fs.writeFileSync('./data/schema.graphql', printSchema(buildClientSchema(JSON.parse(str).data)));
+})
\ No newline at end of file
diff --git a/samples/relay-modern-starter-kit/server.fsx b/samples/relay-modern-starter-kit/server.fsx
new file mode 100644
index 000000000..eb9ec8982
--- /dev/null
+++ b/samples/relay-modern-starter-kit/server.fsx
@@ -0,0 +1,169 @@
+#r "nuget: Suave, 2.6.2"
+#r "nuget: Newtonsoft.Json, 13.0.1"
+#r "../../src/FSharp.Data.GraphQL.Server/bin/Debug/net461/FSharp.Data.GraphQL.Shared.dll"
+#r "../../src/FSharp.Data.GraphQL.Server/bin/Debug/net461/FSharp.Data.GraphQL.Server.dll"
+#r "../../src/FSharp.Data.GraphQL.Server.Relay/bin/Debug/net461/FSharp.Data.GraphQL.Server.Relay.dll"
+
+open System
+
+// Data
+
+type Widget = { Id : string; Name : string }
+
+type User = { Id : string; Name : string; Widgets : Widget list }
+
+let viewer =
+ { Id = "1"
+ Name = "Anonymous"
+ Widgets =
+ [ { Id = "1"; Name = "What's it" }
+ { Id = "2"; Name = "Who's it" }
+ { Id = "3"; Name = "How's it" } ] }
+
+let getUser id = if viewer.Id = id then Some viewer else None
+let getWidget id = viewer.Widgets |> List.tryFind (fun w -> w.Id = id)
+
+// Schema definition
+open FSharp.Data.GraphQL
+open FSharp.Data.GraphQL.Types
+open FSharp.Data.GraphQL.Server.Relay
+
+let rec Widget =
+ Define.Object (
+ name = "Widget",
+ description = "A shiny widget",
+ interfaces = [ Node ],
+ fields =
+ [ Define.GlobalIdField (fun _ w -> w.Id)
+ Define.Field ("name", String, (fun _ w -> w.Name)) ]
+ )
+
+and User =
+ Define.Object (
+ name = "User",
+ description = "A person who uses our app",
+ interfaces = [ Node ],
+ fields =
+ [ Define.GlobalIdField (fun _ w -> w.Id)
+ Define.Field ("name", String, (fun _ w -> w.Name))
+ Define.Field (
+ "widgets",
+ ConnectionOf Widget,
+ "A person's collection of widgets",
+ Connection.allArgs,
+ fun ctx user ->
+ let totalCount = user.Widgets.Length
+
+ let widgets, hasNextPage =
+ match ctx with
+ | SliceInfo (Forward (n, after)) ->
+ match after with
+ | Some (GlobalId ("Widget", id)) ->
+ let i =
+ user.Widgets
+ |> List.indexed
+ |> List.pick (fun (i, e) -> if e.Id = id then Some i else None)
+
+ user.Widgets |> List.skip (i + 1) |> List.take n, i + 1 + n < totalCount
+ | None -> user.Widgets |> List.take n, n < totalCount
+ | _ -> failwithf "Cursor %A is not 'Widget' global id" after
+ | _ -> user.Widgets, false
+
+ let edges =
+ widgets
+ |> Seq.map (fun b -> { Cursor = toGlobalId "Widget" (string b.Id); Node = b })
+ |> Seq.toArray
+
+ let headCursor =
+ edges
+ |> Array.tryHead
+ |> Option.map (fun edge -> edge.Cursor)
+
+ let pi =
+ { HasNextPage = hasNextPage
+ EndCursor = headCursor
+ StartCursor = None
+ HasPreviousPage = false }
+
+ let con = { TotalCount = Some totalCount; PageInfo = pi; Edges = edges }
+ con
+ ) ]
+ )
+
+and Node = Define.Node (fun () -> [ User; Widget ])
+
+let Query =
+ Define.Object (
+ "Query",
+ [ Define.NodeField (
+ Node,
+ fun ctx () id ->
+ match id with
+ | GlobalId ("User", i) -> getUser i |> Option.map box
+ | GlobalId ("Widget", i) -> getWidget i |> Option.map box
+ | _ -> None
+ )
+ Define.Field ("viewer", User, (fun _ () -> viewer)) ]
+ )
+
+let schema = Schema (query = Query, config = { SchemaConfig.Default with Types = [ User; Widget ] })
+let ex = Executor (schema)
+
+// server initialization
+open Suave
+open Suave.Operators
+open Newtonsoft.Json
+open FSharp.Data.GraphQL.Execution
+
+let settings = JsonSerializerSettings ()
+settings.ContractResolver <- Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver ()
+let json o = JsonConvert.SerializeObject (o, settings)
+
+let tryParse fieldName data =
+ let raw = Text.Encoding.UTF8.GetString data
+
+ if raw <> null && raw <> ""
+ then
+ let map = JsonConvert.DeserializeObject