diff --git a/.github/workflows/ci-pr-dotnet.yml b/.github/workflows/ci-pr-dotnet.yml
index 655b74d90..523b8d7e5 100644
--- a/.github/workflows/ci-pr-dotnet.yml
+++ b/.github/workflows/ci-pr-dotnet.yml
@@ -22,9 +22,9 @@ jobs:
- name: Check out source
uses: actions/checkout@v3
- name: Set up .NET
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.0.x
+ dotnet-version: 10.0.x
- name: Set up Node.js
uses: actions/setup-node@v3
with:
@@ -38,5 +38,11 @@ jobs:
run: dotnet restore
- name: Build .NET solution
run: dotnet build --no-restore
+ - name: Install React dependencies
+ run: npm ci
+ working-directory: src/caretogether-pwa
+ - name: Install Playwright browsers
+ run: npx playwright install --with-deps
+ working-directory: src/caretogether-pwa
- name: Test .NET solution
run: dotnet test --no-build --verbosity normal
diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml
new file mode 100644
index 000000000..8fa96dda2
--- /dev/null
+++ b/.github/workflows/playwright.yml
@@ -0,0 +1,60 @@
+name: Playwright Tests
+
+on:
+ push:
+ branches: [main, master]
+ paths:
+ - "src/CareTogether.Api/**"
+ - "src/CareTogether.AppHost/**"
+ - "src/CareTogether.ServiceDefaults/**"
+ - "src/caretogether-pwa/**"
+ - "test/CareTogether.AppHost.Tests/**"
+ - ".github/workflows/playwright.yml"
+ pull_request:
+ branches: [main, master]
+ paths:
+ - "src/CareTogether.Api/**"
+ - "src/CareTogether.AppHost/**"
+ - "src/CareTogether.ServiceDefaults/**"
+ - "src/caretogether-pwa/**"
+ - "test/CareTogether.AppHost.Tests/**"
+ - ".github/workflows/playwright.yml"
+
+jobs:
+ test:
+ timeout-minutes: 60
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: 10.0.x
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 24.x
+ cache: npm
+ cache-dependency-path: src/caretogether-pwa/package-lock.json
+ - name: Install Azurite storage emulator
+ run: npm install -g azurite
+ - name: Start Azurite storage emulator
+ shell: bash
+ run: azurite &
+ - name: Restore .NET dependencies
+ run: dotnet restore
+ - name: Build .NET solution
+ run: dotnet build --no-restore
+ - name: Install dependencies
+ run: npm ci
+ working-directory: src/caretogether-pwa
+ - name: Install Playwright browsers
+ run: npx playwright install --with-deps
+ working-directory: src/caretogether-pwa
+ - name: Run Playwright tests
+ run: dotnet test test/CareTogether.AppHost.Tests/CareTogether.AppHost.Tests.csproj --no-build --verbosity normal
+ - uses: actions/upload-artifact@v4
+ if: ${{ !cancelled() }}
+ with:
+ name: playwright-report
+ path: src/caretogether-pwa/playwright-report/
+ retention-days: 30
diff --git a/.gitignore b/.gitignore
index b72356aec..72dade936 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,11 @@ Generated\ Files/
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
+# Playwright
+test-results/
+playwright-report/
+playwright/.auth/
+
# NUnit
*.VisualState.xml
TestResult.xml
diff --git a/CareTogetherCMS.sln b/CareTogetherCMS.sln
index 6574f6fa2..c467297eb 100644
--- a/CareTogetherCMS.sln
+++ b/CareTogetherCMS.sln
@@ -5,13 +5,14 @@ VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deploy", "deploy", "{B04053C5-CA17-41B1-BC52-8B5393090D45}"
ProjectSection(SolutionItems) = preProject
- .github\workflows\cd-prod-dotnet.yml = .github\workflows\cd-prod-dotnet.yml
- .github\workflows\cd-prod-react.yml = .github\workflows\cd-prod-react.yml
- .github\workflows\ci-pr-dotnet.yml = .github\workflows\ci-pr-dotnet.yml
- .github\workflows\ci-pr-react.yml = .github\workflows\ci-pr-react.yml
- .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
- EndProjectSection
-EndProject
+ .github\workflows\cd-prod-dotnet.yml = .github\workflows\cd-prod-dotnet.yml
+ .github\workflows\cd-prod-react.yml = .github\workflows\cd-prod-react.yml
+ .github\workflows\ci-pr-dotnet.yml = .github\workflows\ci-pr-dotnet.yml
+ .github\workflows\ci-pr-react.yml = .github\workflows\ci-pr-react.yml
+ .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
+ .github\workflows\playwright.yml = .github\workflows\playwright.yml
+ EndProjectSection
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CareTogether.Api", "src\CareTogether.Api\CareTogether.Api.csproj", "{67F0E369-C927-4278-A7D0-DDFBE029003F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{465BA74E-CEF3-4608-8809-8C7A2E979DAC}"
@@ -60,36 +61,130 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Timelines", "src\Timelines\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Timelines.Test", "test\Timelines.Test\Timelines.Test.csproj", "{3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CareTogether.AppHost", "src\CareTogether.AppHost\CareTogether.AppHost.csproj", "{7AB05778-70B4-4B95-BE67-D07802D0B57B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CareTogether.ServiceDefaults", "src\CareTogether.ServiceDefaults\CareTogether.ServiceDefaults.csproj", "{3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CareTogether.AppHost.Tests", "test\CareTogether.AppHost.Tests\CareTogether.AppHost.Tests.csproj", "{E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{67F0E369-C927-4278-A7D0-DDFBE029003F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67F0E369-C927-4278-A7D0-DDFBE029003F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Debug|x64.Build.0 = Debug|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Debug|x86.Build.0 = Debug|Any CPU
{67F0E369-C927-4278-A7D0-DDFBE029003F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67F0E369-C927-4278-A7D0-DDFBE029003F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Release|x64.ActiveCfg = Release|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Release|x64.Build.0 = Release|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Release|x86.ActiveCfg = Release|Any CPU
+ {67F0E369-C927-4278-A7D0-DDFBE029003F}.Release|x86.Build.0 = Release|Any CPU
{82B69D6F-DA25-452B-883D-71B9AE91DF23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82B69D6F-DA25-452B-883D-71B9AE91DF23}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Debug|x64.Build.0 = Debug|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Debug|x86.Build.0 = Debug|Any CPU
{82B69D6F-DA25-452B-883D-71B9AE91DF23}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82B69D6F-DA25-452B-883D-71B9AE91DF23}.Release|Any CPU.Build.0 = Release|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Release|x64.ActiveCfg = Release|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Release|x64.Build.0 = Release|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Release|x86.ActiveCfg = Release|Any CPU
+ {82B69D6F-DA25-452B-883D-71B9AE91DF23}.Release|x86.Build.0 = Release|Any CPU
{B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Debug|x64.Build.0 = Debug|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Debug|x86.Build.0 = Debug|Any CPU
{B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Release|x64.ActiveCfg = Release|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Release|x64.Build.0 = Release|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Release|x86.ActiveCfg = Release|Any CPU
+ {B2CA1F10-216E-404E-A3C2-70423D5BCF5D}.Release|x86.Build.0 = Release|Any CPU
{7DC7327F-6F01-4561-943D-D385FB5637E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7DC7327F-6F01-4561-943D-D385FB5637E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Debug|x64.Build.0 = Debug|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Debug|x86.Build.0 = Debug|Any CPU
{7DC7327F-6F01-4561-943D-D385FB5637E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DC7327F-6F01-4561-943D-D385FB5637E1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Release|x64.ActiveCfg = Release|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Release|x64.Build.0 = Release|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Release|x86.ActiveCfg = Release|Any CPU
+ {7DC7327F-6F01-4561-943D-D385FB5637E1}.Release|x86.Build.0 = Release|Any CPU
{97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Debug|x64.Build.0 = Debug|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Debug|x86.Build.0 = Debug|Any CPU
{97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Release|x64.ActiveCfg = Release|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Release|x64.Build.0 = Release|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Release|x86.ActiveCfg = Release|Any CPU
+ {97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9}.Release|x86.Build.0 = Release|Any CPU
{3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Debug|x64.Build.0 = Debug|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Debug|x86.Build.0 = Debug|Any CPU
{3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Release|x64.ActiveCfg = Release|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Release|x64.Build.0 = Release|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Release|x86.ActiveCfg = Release|Any CPU
+ {3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA}.Release|x86.Build.0 = Release|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Debug|x64.Build.0 = Debug|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Debug|x86.Build.0 = Debug|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Release|x64.ActiveCfg = Release|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Release|x64.Build.0 = Release|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Release|x86.ActiveCfg = Release|Any CPU
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B}.Release|x86.Build.0 = Release|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Debug|x64.Build.0 = Debug|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Debug|x86.Build.0 = Debug|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Release|x64.ActiveCfg = Release|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Release|x64.Build.0 = Release|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Release|x86.ActiveCfg = Release|Any CPU
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4}.Release|x86.Build.0 = Release|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Debug|x64.Build.0 = Debug|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Debug|x86.Build.0 = Debug|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Release|x64.ActiveCfg = Release|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Release|x64.Build.0 = Release|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Release|x86.ActiveCfg = Release|Any CPU
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -105,6 +200,9 @@ Global
{7DC7327F-6F01-4561-943D-D385FB5637E1} = {42D43EAF-EE89-479A-B304-3B5DF56A3494}
{97B1250A-5BD6-4C12-8D9B-63EEBAFB8DC9} = {465BA74E-CEF3-4608-8809-8C7A2E979DAC}
{3C0F8F56-17BB-4BF7-8D59-51D8A5F635CA} = {42D43EAF-EE89-479A-B304-3B5DF56A3494}
+ {7AB05778-70B4-4B95-BE67-D07802D0B57B} = {465BA74E-CEF3-4608-8809-8C7A2E979DAC}
+ {3C6180D9-8BFB-45CE-AD0F-967EBDE7C0F4} = {465BA74E-CEF3-4608-8809-8C7A2E979DAC}
+ {E0AB6E03-C1C4-490F-A56A-8EE45C0C7220} = {42D43EAF-EE89-479A-B304-3B5DF56A3494}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E09CB79A-6E5B-4BAD-B356-64D949892A7E}
diff --git a/mise.toml b/mise.toml
new file mode 100644
index 000000000..df386ef77
--- /dev/null
+++ b/mise.toml
@@ -0,0 +1,2 @@
+[tools]
+dotnet = "10"
diff --git a/src/CareTogether.Api/CareTogether.Api.csproj b/src/CareTogether.Api/CareTogether.Api.csproj
index ea120e083..e7d37f8ba 100644
--- a/src/CareTogether.Api/CareTogether.Api.csproj
+++ b/src/CareTogether.Api/CareTogether.Api.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
enable
aspnet-CareTogether.Api-0706AF60-30BE-4CB4-868D-366CBB379CA7
Linux
@@ -21,8 +21,8 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -38,8 +38,8 @@
-
-
+
+
diff --git a/src/CareTogether.Api/Dockerfile b/src/CareTogether.Api/Dockerfile
index 25659bccf..acb901734 100644
--- a/src/CareTogether.Api/Dockerfile
+++ b/src/CareTogether.Api/Dockerfile
@@ -1,11 +1,11 @@
# See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
# More info at https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/building-net-docker-images?view=aspnetcore-6.0
-FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine-amd64 AS base
+FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine-amd64 AS base
RUN apk add --no-cache tzdata
WORKDIR /app
-FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine-amd64 AS build
+FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine-amd64 AS build
WORKDIR /src
COPY ["src/CareTogether.Api/CareTogether.Api.csproj", "src/CareTogether.Api/"]
COPY ["test/CareTogether.TestData/CareTogether.TestData.csproj", "test/CareTogether.TestData/"]
@@ -22,4 +22,4 @@ RUN dotnet publish "CareTogether.Api.csproj" -c Release -o /app/publish -r linux
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
-ENTRYPOINT ["dotnet", "CareTogether.Api.dll"]
\ No newline at end of file
+ENTRYPOINT ["dotnet", "CareTogether.Api.dll"]
diff --git a/src/CareTogether.Api/Startup.cs b/src/CareTogether.Api/Startup.cs
index 175322dd8..2318d89aa 100644
--- a/src/CareTogether.Api/Startup.cs
+++ b/src/CareTogether.Api/Startup.cs
@@ -27,14 +27,15 @@
using CareTogether.Utilities.Identity;
using CareTogether.Utilities.ObjectStore;
using CareTogether.Utilities.Telephony;
-using idunno.Authentication.Basic;
-using LazyCache;
-using LazyCache.Providers;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
+using idunno.Authentication.Basic;
+using LazyCache;
+using LazyCache.Providers;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.OData;
using Microsoft.AspNetCore.OData.NewtonsoftJson;
using Microsoft.Extensions.Caching.Memory;
@@ -42,10 +43,11 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
-using Microsoft.FeatureManagement;
-using Microsoft.FeatureManagement.FeatureFilters;
-using Microsoft.Identity.Web;
-using Microsoft.IdentityModel.Logging;
+using Microsoft.FeatureManagement;
+using Microsoft.FeatureManagement.FeatureFilters;
+using Microsoft.Identity.Web;
+using Microsoft.IdentityModel.Logging;
+using Microsoft.IdentityModel.Tokens;
namespace CareTogether.Api
{
@@ -330,10 +332,10 @@ public void ConfigureServices(IServiceCollection services)
)
);
- services
- .AddAuthentication("Basic")
- .AddBasic(
- "Basic",
+ var authenticationBuilder = services
+ .AddAuthentication("Basic")
+ .AddBasic(
+ "Basic",
options =>
{
options.AllowInsecureProtocol = true; // Azure Front Door handles SSL termination.
@@ -443,10 +445,30 @@ await policiesResource.GetOrganizationSecretsAsync(
context.Fail("The API key is invalid.");
return;
},
- };
- }
- )
- .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C"));
+ };
+ }
+ );
+
+ if (UseLocalKeycloakAuthentication())
+ {
+ authenticationBuilder.AddJwtBearer(options =>
+ {
+ options.Authority =
+ Configuration["Keycloak:Authority"]
+ ?? "http://localhost:8080/realms/caretogether-local";
+ options.RequireHttpsMetadata = false;
+ options.TokenValidationParameters = new TokenValidationParameters
+ {
+ ValidAudience = "caretogether-api",
+ };
+ });
+ }
+ else
+ {
+ authenticationBuilder.AddMicrosoftIdentityWebApi(
+ Configuration.GetSection("AzureAdB2C")
+ );
+ }
services.AddTransient();
@@ -519,7 +541,7 @@ out var locId
});
}
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
@@ -566,7 +588,15 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
// Accommodating the Azure App Service liveness check mechanism described here:
// https://learn.microsoft.com/en-us/azure/app-service/configure-language-dotnetcore?pivots=platform-linux#robots933456-in-logs
endpoints.MapHealthChecks("/robots933456.txt").AllowAnonymous();
- });
- }
- }
-}
+ });
+ }
+
+ private bool UseLocalKeycloakAuthentication() =>
+ HostEnvironment.IsDevelopment()
+ && string.Equals(
+ Configuration["Authentication:Provider"],
+ "Keycloak",
+ StringComparison.OrdinalIgnoreCase
+ );
+ }
+}
diff --git a/src/CareTogether.AppHost/AppHost.cs b/src/CareTogether.AppHost/AppHost.cs
new file mode 100644
index 000000000..deaca0a5b
--- /dev/null
+++ b/src/CareTogether.AppHost/AppHost.cs
@@ -0,0 +1,31 @@
+using Aspire.Hosting.ApplicationModel;
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+var keycloak = builder.AddKeycloak("keycloak", 8080).WithRealmImport("./Realms");
+var keycloakAuthority = ReferenceExpression.Create(
+ $"{keycloak.GetEndpoint("http")}/realms/caretogether-local"
+);
+
+var api = builder
+ .AddProject("api")
+ .WithEnvironment("Authentication__Provider", "Keycloak")
+ .WithEnvironment("Keycloak__Authority", keycloakAuthority)
+ .WithReference(keycloak)
+ .WaitFor(keycloak);
+
+var web = builder
+ .AddJavaScriptApp("web", "../caretogether-pwa")
+ .WithHttpEndpoint(targetPort: 3000, port: 3000, env: "PORT", isProxied: false)
+ .WithReference(api)
+ .WithReference(keycloak)
+ .WaitFor(keycloak);
+
+web.WithEnvironment("VITE_APP_API_HOST", api.GetEndpoint("http"));
+web.WithEnvironment("VITE_APP_AUTH_PROVIDER", "keycloak");
+web.WithEnvironment("VITE_APP_AUTH_CLIENT_ID", "caretogether-pwa");
+web.WithEnvironment("VITE_APP_AUTH_AUTHORITY", keycloakAuthority);
+web.WithEnvironment("VITE_APP_AUTH_SCOPES", "openid profile email");
+web.WithEnvironment("VITE_APP_AUTH_REDIRECT_URI", web.GetEndpoint("http"));
+
+builder.Build().Run();
diff --git a/src/CareTogether.AppHost/CareTogether.AppHost.csproj b/src/CareTogether.AppHost/CareTogether.AppHost.csproj
new file mode 100644
index 000000000..d0cd6e4e3
--- /dev/null
+++ b/src/CareTogether.AppHost/CareTogether.AppHost.csproj
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+ b426decf-214e-45dd-9adc-36b0f26c9372
+
+
+
diff --git a/src/CareTogether.AppHost/Properties/launchSettings.json b/src/CareTogether.AppHost/Properties/launchSettings.json
new file mode 100644
index 000000000..ce6fc42ac
--- /dev/null
+++ b/src/CareTogether.AppHost/Properties/launchSettings.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:17139;http://localhost:15087",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21053",
+ "ASPIRE_DASHBOARD_MCP_ENDPOINT_URL": "https://localhost:23072",
+ "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22069"
+ }
+ },
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:15087",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19276",
+ "ASPIRE_DASHBOARD_MCP_ENDPOINT_URL": "http://localhost:18015",
+ "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20179"
+ }
+ }
+ }
+}
diff --git a/src/CareTogether.AppHost/Realms/caretogether-local-realm.json b/src/CareTogether.AppHost/Realms/caretogether-local-realm.json
new file mode 100644
index 000000000..4df1a6eb6
--- /dev/null
+++ b/src/CareTogether.AppHost/Realms/caretogether-local-realm.json
@@ -0,0 +1,105 @@
+{
+ "realm": "caretogether-local",
+ "enabled": true,
+ "registrationAllowed": false,
+ "loginWithEmailAllowed": true,
+ "duplicateEmailsAllowed": false,
+ "resetPasswordAllowed": false,
+ "clients": [
+ {
+ "clientId": "caretogether-pwa",
+ "name": "CareTogether PWA",
+ "enabled": true,
+ "rootUrl": "http://localhost:3000",
+ "baseUrl": "/",
+ "adminUrl": "http://localhost:3000",
+ "publicClient": true,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": true,
+ "protocol": "openid-connect",
+ "defaultClientScopes": [
+ "web-origins",
+ "acr",
+ "profile",
+ "roles",
+ "basic",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ],
+ "redirectUris": [
+ "http://localhost:3000",
+ "http://localhost:3000/*"
+ ],
+ "webOrigins": [
+ "+"
+ ],
+ "attributes": {
+ "pkce.code.challenge.method": "S256"
+ },
+ "protocolMappers": [
+ {
+ "name": "CareTogether User ID",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-hardcoded-claim-mapper",
+ "consentRequired": false,
+ "config": {
+ "claim.name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
+ "claim.value": "2b87864a-63e3-4406-bcbc-c0068a13ac05",
+ "jsonType.label": "String",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "true"
+ }
+ },
+ {
+ "name": "CareTogether API Audience",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-mapper",
+ "consentRequired": false,
+ "config": {
+ "included.client.audience": "caretogether-api",
+ "id.token.claim": "false",
+ "access.token.claim": "true"
+ }
+ }
+ ]
+ },
+ {
+ "clientId": "caretogether-api",
+ "name": "CareTogether API",
+ "enabled": true,
+ "publicClient": false,
+ "bearerOnly": true,
+ "protocol": "openid-connect"
+ }
+ ],
+ "users": [
+ {
+ "id": "2b87864a-63e3-4406-bcbc-c0068a13ac05",
+ "username": "test@bynalogic.com",
+ "email": "test@bynalogic.com",
+ "firstName": "Administrator",
+ "lastName": "McTester",
+ "enabled": true,
+ "emailVerified": true,
+ "attributes": {
+ "caretogether_user_id": [
+ "2b87864a-63e3-4406-bcbc-c0068a13ac05"
+ ]
+ },
+ "credentials": [
+ {
+ "type": "password",
+ "value": "P@ssw0rd",
+ "temporary": false
+ }
+ ]
+ }
+ ]
+}
diff --git a/src/CareTogether.AppHost/appsettings.Development.json b/src/CareTogether.AppHost/appsettings.Development.json
new file mode 100644
index 000000000..0c208ae91
--- /dev/null
+++ b/src/CareTogether.AppHost/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/src/CareTogether.AppHost/appsettings.json b/src/CareTogether.AppHost/appsettings.json
new file mode 100644
index 000000000..31c092aa4
--- /dev/null
+++ b/src/CareTogether.AppHost/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Aspire.Hosting.Dcp": "Warning"
+ }
+ }
+}
diff --git a/src/CareTogether.AppHost/aspire.config.json b/src/CareTogether.AppHost/aspire.config.json
new file mode 100644
index 000000000..2fdb09434
--- /dev/null
+++ b/src/CareTogether.AppHost/aspire.config.json
@@ -0,0 +1,5 @@
+{
+ "appHost": {
+ "path": "CareTogether.AppHost.csproj"
+ }
+}
diff --git a/src/CareTogether.Core/CareTogether.Core.csproj b/src/CareTogether.Core/CareTogether.Core.csproj
index bf57e2a31..639ce023c 100644
--- a/src/CareTogether.Core/CareTogether.Core.csproj
+++ b/src/CareTogether.Core/CareTogether.Core.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
CareTogether
enable
@@ -15,7 +15,6 @@
-
diff --git a/src/CareTogether.ServiceDefaults/CareTogether.ServiceDefaults.csproj b/src/CareTogether.ServiceDefaults/CareTogether.ServiceDefaults.csproj
new file mode 100644
index 000000000..4502460ed
--- /dev/null
+++ b/src/CareTogether.ServiceDefaults/CareTogether.ServiceDefaults.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net10.0
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/CareTogether.ServiceDefaults/Extensions.cs b/src/CareTogether.ServiceDefaults/Extensions.cs
new file mode 100644
index 000000000..b72c8753c
--- /dev/null
+++ b/src/CareTogether.ServiceDefaults/Extensions.cs
@@ -0,0 +1,127 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Diagnostics.HealthChecks;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.ServiceDiscovery;
+using OpenTelemetry;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace Microsoft.Extensions.Hosting;
+
+// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
+// This project should be referenced by each service project in your solution.
+// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
+public static class Extensions
+{
+ private const string HealthEndpointPath = "/health";
+ private const string AlivenessEndpointPath = "/alive";
+
+ public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder
+ {
+ builder.ConfigureOpenTelemetry();
+
+ builder.AddDefaultHealthChecks();
+
+ builder.Services.AddServiceDiscovery();
+
+ builder.Services.ConfigureHttpClientDefaults(http =>
+ {
+ // Turn on resilience by default
+ http.AddStandardResilienceHandler();
+
+ // Turn on service discovery by default
+ http.AddServiceDiscovery();
+ });
+
+ // Uncomment the following to restrict the allowed schemes for service discovery.
+ // builder.Services.Configure(options =>
+ // {
+ // options.AllowedSchemes = ["https"];
+ // });
+
+ return builder;
+ }
+
+ public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) where TBuilder : IHostApplicationBuilder
+ {
+ builder.Logging.AddOpenTelemetry(logging =>
+ {
+ logging.IncludeFormattedMessage = true;
+ logging.IncludeScopes = true;
+ });
+
+ builder.Services.AddOpenTelemetry()
+ .WithMetrics(metrics =>
+ {
+ metrics.AddAspNetCoreInstrumentation()
+ .AddHttpClientInstrumentation()
+ .AddRuntimeInstrumentation();
+ })
+ .WithTracing(tracing =>
+ {
+ tracing.AddSource(builder.Environment.ApplicationName)
+ .AddAspNetCoreInstrumentation(tracing =>
+ // Exclude health check requests from tracing
+ tracing.Filter = context =>
+ !context.Request.Path.StartsWithSegments(HealthEndpointPath)
+ && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
+ )
+ // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
+ //.AddGrpcClientInstrumentation()
+ .AddHttpClientInstrumentation();
+ });
+
+ builder.AddOpenTelemetryExporters();
+
+ return builder;
+ }
+
+ private static TBuilder AddOpenTelemetryExporters(this TBuilder builder) where TBuilder : IHostApplicationBuilder
+ {
+ var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
+
+ if (useOtlpExporter)
+ {
+ builder.Services.AddOpenTelemetry().UseOtlpExporter();
+ }
+
+ // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
+ //if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
+ //{
+ // builder.Services.AddOpenTelemetry()
+ // .UseAzureMonitor();
+ //}
+
+ return builder;
+ }
+
+ public static TBuilder AddDefaultHealthChecks(this TBuilder builder) where TBuilder : IHostApplicationBuilder
+ {
+ builder.Services.AddHealthChecks()
+ // Add a default liveness check to ensure app is responsive
+ .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
+
+ return builder;
+ }
+
+ public static WebApplication MapDefaultEndpoints(this WebApplication app)
+ {
+ // Adding health checks endpoints to applications in non-development environments has security implications.
+ // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.
+ if (app.Environment.IsDevelopment())
+ {
+ // All health checks must pass for app to be considered ready to accept traffic after starting
+ app.MapHealthChecks(HealthEndpointPath);
+
+ // Only health checks tagged with the "live" tag must pass for app to be considered alive
+ app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions
+ {
+ Predicate = r => r.Tags.Contains("live")
+ });
+ }
+
+ return app;
+ }
+}
diff --git a/src/Timelines/Timelines.csproj b/src/Timelines/Timelines.csproj
index fa71b7ae6..b76014470 100644
--- a/src/Timelines/Timelines.csproj
+++ b/src/Timelines/Timelines.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
enable
enable
diff --git a/src/caretogether-pwa/.gitignore b/src/caretogether-pwa/.gitignore
index 800f3a80c..356497a36 100644
--- a/src/caretogether-pwa/.gitignore
+++ b/src/caretogether-pwa/.gitignore
@@ -22,3 +22,11 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+
+# Playwright
+node_modules/
+/test-results/
+/playwright-report/
+/blob-report/
+/playwright/.cache/
+/playwright/.auth/
diff --git a/src/caretogether-pwa/package-lock.json b/src/caretogether-pwa/package-lock.json
index 6803f540d..a2b3584b0 100644
--- a/src/caretogether-pwa/package-lock.json
+++ b/src/caretogether-pwa/package-lock.json
@@ -46,8 +46,9 @@
"devDependencies": {
"@eslint/eslintrc": "^3.0.0",
"@eslint/js": "^9.0.0",
+ "@playwright/test": "^1.59.1",
"@types/jest": "^29.5.12",
- "@types/node": "^20.14.10",
+ "@types/node": "^20.19.39",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-lazyload": "^3.2.3",
@@ -1875,6 +1876,22 @@
"url": "https://github.com/sponsors/Boshen"
}
},
+ "node_modules/@playwright/test": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz",
+ "integrity": "sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright": "1.59.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
@@ -5624,6 +5641,53 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/playwright": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.1.tgz",
+ "integrity": "sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.59.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.59.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.1.tgz",
+ "integrity": "sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/playwright/node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
diff --git a/src/caretogether-pwa/package.json b/src/caretogether-pwa/package.json
index 56a675968..28977c58c 100644
--- a/src/caretogether-pwa/package.json
+++ b/src/caretogether-pwa/package.json
@@ -40,10 +40,11 @@
"zod": "^4.3.5"
},
"devDependencies": {
+ "@playwright/test": "^1.59.1",
"@eslint/eslintrc": "^3.0.0",
"@eslint/js": "^9.0.0",
"@types/jest": "^29.5.12",
- "@types/node": "^20.14.10",
+ "@types/node": "^20.19.39",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-lazyload": "^3.2.3",
diff --git a/src/caretogether-pwa/playwright.config.ts b/src/caretogether-pwa/playwright.config.ts
new file mode 100644
index 000000000..fbb9f505c
--- /dev/null
+++ b/src/caretogether-pwa/playwright.config.ts
@@ -0,0 +1,37 @@
+import { defineConfig, devices } from '@playwright/test';
+
+const BASE_URL = process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3000';
+const AUTH_FILE = 'playwright/.auth/admin.json';
+
+export default defineConfig({
+ testDir: './playwright_test',
+ fullyParallel: false,
+ forbidOnly: !!process.env.CI,
+ retries: process.env.CI ? 2 : 0,
+ workers: process.env.CI ? 1 : undefined,
+ reporter: [['html'], ['list']],
+ use: {
+ baseURL: BASE_URL,
+ trace: 'on-first-retry',
+ screenshot: 'only-on-failure',
+ video: 'retain-on-failure',
+ },
+ projects: [
+ {
+ name: 'setup',
+ testMatch: /.*\.setup\.ts/,
+ use: {
+ ...devices['Desktop Chrome'],
+ video: 'off',
+ },
+ },
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome'],
+ storageState: AUTH_FILE,
+ },
+ dependencies: ['setup'],
+ },
+ ],
+});
diff --git a/src/caretogether-pwa/playwright_test/auth.setup.ts b/src/caretogether-pwa/playwright_test/auth.setup.ts
new file mode 100644
index 000000000..113e451a1
--- /dev/null
+++ b/src/caretogether-pwa/playwright_test/auth.setup.ts
@@ -0,0 +1,257 @@
+import { test, expect, APIRequestContext, Page } from '@playwright/test';
+import fs from 'node:fs';
+import path from 'node:path';
+
+const AUTH_FILE = path.resolve('playwright/.auth/admin.json');
+const ATLANTIS_ROUTE =
+ '/org/11111111-1111-1111-1111-111111111111/22222222-2222-2222-2222-222222222222/';
+const KEYCLOAK_TOKEN_STORAGE_KEY = 'caretogether.keycloak.tokens';
+const KEYCLOAK_PKCE_STORAGE_KEY = 'caretogether.keycloak.pkce';
+
+const adminEmail = process.env.CT_ADMIN_EMAIL;
+const adminPassword = process.env.CT_ADMIN_PASSWORD;
+
+type KeycloakPkceState = {
+ codeVerifier: string;
+ state: string;
+};
+
+async function completeLocalKeycloakSignInAsync(
+ request: APIRequestContext,
+ page: Page,
+ baseURL: string,
+ keycloakSignInUrl: string
+) {
+ await page.waitForURL(
+ (url) => url.toString().startsWith(baseURL) && url.searchParams.has('code'),
+ { timeout: 60_000 }
+ );
+
+ const callbackUrl = new URL(page.url());
+ const code = callbackUrl.searchParams.get('code');
+ const state = callbackUrl.searchParams.get('state');
+ if (!code || !state) {
+ throw new Error(`Missing Keycloak callback code or state: ${callbackUrl}`);
+ }
+
+ const storedPkceState = await page.evaluate((storageKey) => {
+ return sessionStorage.getItem(storageKey);
+ }, KEYCLOAK_PKCE_STORAGE_KEY);
+ if (!storedPkceState) {
+ throw new Error('Missing Keycloak PKCE state in session storage.');
+ }
+
+ const pkceState = JSON.parse(storedPkceState) as KeycloakPkceState;
+ if (pkceState.state !== state) {
+ throw new Error('The Keycloak callback state did not match the PKCE state.');
+ }
+
+ const authorizationUrl = new URL(keycloakSignInUrl);
+ const tokenUrl = `${authorizationUrl.origin}/realms/caretogether-local/protocol/openid-connect/token`;
+ const redirectUri = authorizationUrl.searchParams.get('redirect_uri');
+ if (!redirectUri) {
+ throw new Error('Missing Keycloak redirect URI.');
+ }
+
+ const tokenResponse = await request.post(tokenUrl, {
+ form: {
+ client_id: 'caretogether-pwa',
+ code,
+ code_verifier: pkceState.codeVerifier,
+ grant_type: 'authorization_code',
+ redirect_uri: redirectUri,
+ },
+ });
+
+ if (!tokenResponse.ok()) {
+ throw new Error(
+ `Keycloak token exchange failed with ${tokenResponse.status()}: ${await tokenResponse.text()}`
+ );
+ }
+
+ const tokenPayload = await tokenResponse.json();
+ const storedTokens = {
+ accessToken: tokenPayload.access_token,
+ idToken: tokenPayload.id_token,
+ refreshToken: tokenPayload.refresh_token,
+ expiresAt: Date.now() + (tokenPayload.expires_in ?? 300) * 1000,
+ };
+
+ await page.addInitScript(
+ ([storageKey, storageValue]) => {
+ localStorage.setItem(storageKey, storageValue);
+ },
+ [KEYCLOAK_TOKEN_STORAGE_KEY, JSON.stringify(storedTokens)]
+ );
+
+ await page.goto(ATLANTIS_ROUTE);
+}
+
+test('login as administrator', async ({ page, baseURL, request }) => {
+ test.setTimeout(420_000);
+
+ if (!adminEmail || !adminPassword) {
+ throw new Error('Missing CT_ADMIN_EMAIL or CT_ADMIN_PASSWORD');
+ }
+
+ if (!baseURL) {
+ throw new Error('Missing Playwright baseURL');
+ }
+
+ fs.mkdirSync(path.dirname(AUTH_FILE), { recursive: true });
+
+ const sideNavigation = page.getByRole('list', {
+ name: /secondary navigation/i,
+ });
+
+ const usernameField = page
+ .locator('#username')
+ .or(page.locator('input[name="username"]'))
+ .or(page.getByPlaceholder(/email address/i))
+ .or(page.locator('input[type="email"]'))
+ .or(page.locator('input[name*="email" i]'))
+ .or(page.locator('input[id*="email" i]'))
+ .or(page.locator('input[name*="user" i]'))
+ .or(page.locator('input[id*="user" i]'));
+
+ const passwordField = page
+ .getByPlaceholder(/password/i)
+ .or(page.locator('input[type="password"]'));
+
+ const signInButton = page
+ .getByRole('button', { name: /^sign in$/i })
+ .or(page.locator('input[type="submit"]'))
+ .or(page.locator('#kc-login'));
+
+ const temporaryError = page.getByText(
+ /something went wrong|failed to fetch/i
+ );
+
+ await page.goto(ATLANTIS_ROUTE);
+ await page.waitForLoadState('domcontentloaded');
+
+ await page
+ .waitForURL(/b2clogin\.com|\/realms\/caretogether-local\//, {
+ timeout: 30_000,
+ })
+ .catch(() => {});
+
+ await expect
+ .poll(
+ async () => {
+ const url = page.url();
+
+ if (await sideNavigation.isVisible().catch(() => false)) {
+ return 'authenticated';
+ }
+
+ if (
+ url.includes('b2clogin.com') ||
+ url.includes('/realms/caretogether-local/') ||
+ (await usernameField
+ .first()
+ .isVisible()
+ .catch(() => false))
+ ) {
+ return 'identity-provider';
+ }
+
+ if (
+ await temporaryError
+ .first()
+ .isVisible()
+ .catch(() => false)
+ ) {
+ return 'temporary-error';
+ }
+
+ return 'loading';
+ },
+ {
+ timeout: 180_000,
+ intervals: [1000, 2000, 5000],
+ }
+ )
+ .toMatch(/authenticated|identity-provider/);
+
+ const onIdentityProviderPage =
+ page.url().includes('b2clogin.com') ||
+ page.url().includes('/realms/caretogether-local/') ||
+ (await usernameField
+ .first()
+ .isVisible()
+ .catch(() => false));
+ const keycloakSignInUrl = page.url().includes('/realms/caretogether-local/')
+ ? page.url()
+ : null;
+
+ if (onIdentityProviderPage) {
+ await expect(usernameField.first()).toBeVisible({ timeout: 60_000 });
+ await usernameField.first().fill(adminEmail);
+
+ await expect(passwordField.first()).toBeVisible({ timeout: 60_000 });
+ await passwordField.first().fill(adminPassword);
+
+ await expect(signInButton.first()).toBeVisible({ timeout: 60_000 });
+ if (keycloakSignInUrl) {
+ await page.route(
+ '**/realms/caretogether-local/protocol/openid-connect/token',
+ async (route) => {
+ await route.abort('blockedbyclient');
+ }
+ );
+ }
+
+ await signInButton.first().click();
+
+ if (keycloakSignInUrl) {
+ await completeLocalKeycloakSignInAsync(
+ request,
+ page,
+ baseURL,
+ keycloakSignInUrl
+ );
+ await page.unroute(
+ '**/realms/caretogether-local/protocol/openid-connect/token'
+ );
+ } else {
+ await expect
+ .poll(
+ async () => {
+ if (await sideNavigation.isVisible().catch(() => false)) {
+ return 'authenticated';
+ }
+
+ if (
+ await temporaryError
+ .first()
+ .isVisible()
+ .catch(() => false)
+ ) {
+ return 'temporary-error';
+ }
+
+ return 'loading';
+ },
+ {
+ timeout: 240_000,
+ intervals: [1000, 2000, 5000],
+ }
+ )
+ .toBe('authenticated');
+ }
+ }
+
+ if (
+ await temporaryError
+ .first()
+ .isVisible()
+ .catch(() => false)
+ ) {
+ await temporaryError.first().waitFor({ state: 'hidden', timeout: 240_000 });
+ }
+
+ await expect(sideNavigation).toBeVisible({ timeout: 240_000 });
+
+ await page.context().storageState({ path: AUTH_FILE });
+});
diff --git a/src/caretogether-pwa/playwright_test/referral-workflow.spec.ts b/src/caretogether-pwa/playwright_test/referral-workflow.spec.ts
new file mode 100644
index 000000000..24b7aa40b
--- /dev/null
+++ b/src/caretogether-pwa/playwright_test/referral-workflow.spec.ts
@@ -0,0 +1,79 @@
+import { expect, Page, test } from '@playwright/test';
+
+const ATLANTIS_ROUTE =
+ '/org/11111111-1111-1111-1111-111111111111/22222222-2222-2222-2222-222222222222/';
+
+async function openAppHome(page: Page): Promise {
+ await page.goto(ATLANTIS_ROUTE);
+ await page.waitForLoadState('domcontentloaded');
+}
+
+async function openReferralsFromSideNavigation(page: Page): Promise {
+ const sideNavigation = page.getByRole('list', {
+ name: /secondary navigation/i,
+ });
+
+ await expect(sideNavigation).toBeVisible();
+ await sideNavigation.getByRole('button', { name: /referrals/i }).click();
+ await expect(
+ page.getByRole('button', { name: /add new referral/i })
+ ).toBeVisible();
+}
+
+test.describe('referral workflow', () => {
+ test('creates a referral, client family, and case', async ({ page }) => {
+ test.setTimeout(180_000);
+
+ const timestamp = Date.now();
+ const referralTitle = `Playwright Referral ${timestamp}`;
+ const referralComment = `Created by Playwright referral workflow ${timestamp}`;
+ const adultFirstName = 'Playwright';
+ const adultLastName = `Client ${timestamp}`;
+ const familyName = `${adultFirstName} ${adultLastName}`;
+
+ await openAppHome(page);
+ await openReferralsFromSideNavigation(page);
+
+ await page.getByRole('button', { name: /add new referral/i }).click();
+ await expect(
+ page.getByRole('heading', { name: /open new referral/i })
+ ).toBeVisible();
+ await page.getByLabel(/referral title/i).fill(referralTitle);
+ await page.getByLabel(/referral comment/i).fill(referralComment);
+ await page.getByRole('button', { name: /^save$/i }).click();
+
+ await expect(
+ page.getByRole('heading', { name: referralTitle })
+ ).toBeVisible({
+ timeout: 60_000,
+ });
+ await expect(page.getByText(referralComment)).toBeVisible();
+
+ await page.getByRole('button', { name: /add new client family/i }).click();
+ await expect(
+ page.getByRole('heading', {
+ name: /create partnering family - first adult/i,
+ })
+ ).toBeVisible();
+ await page.getByLabel(/first name/i).fill(adultFirstName);
+ await page.getByLabel(/last name/i).fill(adultLastName);
+ await page.getByRole('button', { name: /create family/i }).click();
+
+ await expect(page.getByRole('button', { name: familyName })).toBeVisible({
+ timeout: 60_000,
+ });
+
+ await page.getByRole('button', { name: /^open case$/i }).click();
+ await expect(
+ page.getByRole('heading', { name: /open a new case/i })
+ ).toBeVisible();
+ await page.getByRole('button', { name: /^save$/i }).click();
+
+ await expect(page.getByText(/status:\s*accepted/i)).toBeVisible({
+ timeout: 60_000,
+ });
+ await expect(
+ page.getByRole('button', { name: /^open case$/i })
+ ).toBeVisible();
+ });
+});
diff --git a/src/caretogether-pwa/playwright_test/smoke.spec.ts b/src/caretogether-pwa/playwright_test/smoke.spec.ts
new file mode 100644
index 000000000..fb7cc1d36
--- /dev/null
+++ b/src/caretogether-pwa/playwright_test/smoke.spec.ts
@@ -0,0 +1,103 @@
+import { test, expect, Page } from '@playwright/test';
+
+type BrowserFailure = {
+ type: 'console' | 'pageerror';
+ message: string;
+};
+
+type FailureCollector = {
+ getFailures: () => BrowserFailure[];
+};
+
+function createFailureCollector(page: Page): FailureCollector {
+ const failures: BrowserFailure[] = [];
+
+ page.on('console', (msg) => {
+ if (msg.type() !== 'error') {
+ return;
+ }
+
+ const message = msg.text();
+
+ if (
+ /favicon|Failed to load resource: the server responded with a status of 404/i.test(
+ message
+ )
+ ) {
+ return;
+ }
+
+ failures.push({ type: 'console', message });
+ });
+
+ page.on('pageerror', (error) => {
+ failures.push({ type: 'pageerror', message: error.message });
+ });
+
+ return {
+ getFailures: () => failures,
+ };
+}
+
+async function openHome(page: Page): Promise {
+ await page.goto('/');
+ await page.waitForLoadState('domcontentloaded');
+}
+
+async function expectNoFatalErrorUi(page: Page): Promise {
+ await expect(page.locator('body')).toBeVisible();
+ await expect(
+ page.getByText(
+ /unexpected error|something went wrong|application error|monitor_window_timeout/i
+ )
+ ).toHaveCount(0);
+ await expect(page.getByText(/not found|404/i)).toHaveCount(0);
+}
+
+async function expectNoBrowserFailures(
+ collector: FailureCollector
+): Promise {
+ expect(collector.getFailures()).toEqual([]);
+}
+
+test.describe('frontend smoke', () => {
+ test('home route loads without fatal frontend errors', async ({ page }) => {
+ const collector = createFailureCollector(page);
+
+ await openHome(page);
+ await expectNoFatalErrorUi(page);
+ await expectNoBrowserFailures(collector);
+ });
+
+ test('side navigation shows core menu items', async ({ page }) => {
+ const collector = createFailureCollector(page);
+
+ await openHome(page);
+
+ const sideNavigation = page.getByRole('list', {
+ name: /secondary navigation/i,
+ });
+
+ await expect(sideNavigation).toBeVisible();
+ await expect(sideNavigation.getByText('Dashboard')).toBeVisible();
+ await expect(sideNavigation.getByText('Inbox')).toBeVisible();
+
+ await expectNoFatalErrorUi(page);
+ await expectNoBrowserFailures(collector);
+ });
+
+ test('dashboard reaches a usable state', async ({ page }) => {
+ const collector = createFailureCollector(page);
+
+ await openHome(page);
+
+ await expect(
+ page
+ .getByText(/loading dashboard\.\.\./i)
+ .or(page.getByText(/dashboard/i).first())
+ ).toBeVisible();
+
+ await expectNoFatalErrorUi(page);
+ await expectNoBrowserFailures(collector);
+ });
+});
diff --git a/src/caretogether-pwa/src/ApplicationInsightsService.tsx b/src/caretogether-pwa/src/ApplicationInsightsService.tsx
index af6c530bd..9e35de87c 100644
--- a/src/caretogether-pwa/src/ApplicationInsightsService.tsx
+++ b/src/caretogether-pwa/src/ApplicationInsightsService.tsx
@@ -33,6 +33,8 @@ const appInsights = new ApplicationInsights({
// ['*.auth0.com'] to exclude correlation headers from requests sent to the
// Auth0 identity provider.
correlationHeaderExcludedDomains: [
+ 'localhost',
+ '127.0.0.1',
'*.featurebase.app',
'do.featurebase.app',
'featurebase.app',
diff --git a/src/caretogether-pwa/src/Authentication/Auth.ts b/src/caretogether-pwa/src/Authentication/Auth.ts
index c7b698488..c5de891e3 100644
--- a/src/caretogether-pwa/src/Authentication/Auth.ts
+++ b/src/caretogether-pwa/src/Authentication/Auth.ts
@@ -56,13 +56,43 @@ function displayableError(error: Error | unknown) {
//"Something went wrong during sign-in. Try clearing your browser cache and cookies, and report this as a bug if the issue persists."
}
+const keycloakAuthEnabled =
+ import.meta.env.VITE_APP_AUTH_PROVIDER?.toLowerCase() === 'keycloak';
+
function withDefaultScopes(scopes: string[]) {
+ const defaultScopes = keycloakAuthEnabled
+ ? ['openid', 'profile', 'email']
+ : ['openid', 'profile', 'offline_access', 'email'];
+
// Add the default OpenID Connect scopes and then deduplicate the resulting entries.
- return [
- ...new Set(scopes.concat(['openid', 'profile', 'offline_access', 'email'])),
- ];
+ return [...new Set(scopes.concat(defaultScopes))];
}
-const scopes = withDefaultScopes([import.meta.env.VITE_APP_AUTH_SCOPES]);
+
+function parseScopes(scopes: string | undefined) {
+ if (!scopes) {
+ return [];
+ }
+
+ return scopes.split(/\s+/).filter((scope) => scope.length > 0);
+}
+
+const scopes = withDefaultScopes(parseScopes(import.meta.env.VITE_APP_AUTH_SCOPES));
+const keycloakTokenStorageKey = 'caretogether.keycloak.tokens';
+const keycloakPkceStorageKey = 'caretogether.keycloak.pkce';
+const keycloakClockSkewMs = 60_000;
+
+type KeycloakTokens = {
+ accessToken: string;
+ idToken?: string;
+ refreshToken?: string;
+ expiresAt: number;
+};
+
+type KeycloakPkceState = {
+ codeVerifier: string;
+ state: string;
+ returnUrl: string;
+};
type AccountInfo = {
userId: string;
@@ -70,7 +100,251 @@ type AccountInfo = {
name?: string;
};
+function keycloakEndpoint(path: string) {
+ return `${import.meta.env.VITE_APP_AUTH_AUTHORITY}/protocol/openid-connect/${path}`;
+}
+
+function encodeBase64Url(bytes: ArrayBuffer) {
+ const binary = String.fromCharCode(...new Uint8Array(bytes));
+ return btoa(binary)
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_')
+ .replace(/=+$/g, '');
+}
+
+function decodeBase64UrlJson(value: string): T {
+ const base64 = value.replace(/-/g, '+').replace(/_/g, '/');
+ const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, '=');
+ const json = decodeURIComponent(
+ atob(padded)
+ .split('')
+ .map((character) =>
+ `%${character.charCodeAt(0).toString(16).padStart(2, '0')}`
+ )
+ .join('')
+ );
+
+ return JSON.parse(json) as T;
+}
+
+function decodeJwtClaims(token: string): Record {
+ const [, claims] = token.split('.');
+ if (!claims) {
+ throw new Error('The token is not a valid JWT.');
+ }
+
+ return decodeBase64UrlJson>(claims);
+}
+
+function readStoredKeycloakTokens(): KeycloakTokens | null {
+ const storedTokens = localStorage.getItem(keycloakTokenStorageKey);
+ if (!storedTokens) {
+ return null;
+ }
+
+ try {
+ return JSON.parse(storedTokens) as KeycloakTokens;
+ } catch {
+ localStorage.removeItem(keycloakTokenStorageKey);
+ return null;
+ }
+}
+
+function storeKeycloakTokens(response: {
+ access_token: string;
+ id_token?: string;
+ refresh_token?: string;
+ expires_in?: number;
+}) {
+ const tokens: KeycloakTokens = {
+ accessToken: response.access_token,
+ idToken: response.id_token,
+ refreshToken: response.refresh_token,
+ expiresAt: Date.now() + (response.expires_in ?? 300) * 1000,
+ };
+
+ localStorage.setItem(keycloakTokenStorageKey, JSON.stringify(tokens));
+ return tokens;
+}
+
+function keycloakTokensAreCurrent(tokens: KeycloakTokens) {
+ return tokens.expiresAt - keycloakClockSkewMs > Date.now();
+}
+
+function keycloakAccountFromTokens(tokens: KeycloakTokens): AccountInfo {
+ const claims = decodeJwtClaims(tokens.idToken ?? tokens.accessToken);
+ const userIdClaim =
+ claims[
+ 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'
+ ] ??
+ claims.caretogether_user_id ??
+ claims.sub;
+
+ if (typeof userIdClaim !== 'string') {
+ throw new Error('The Keycloak token does not include a valid user ID claim.');
+ }
+
+ return {
+ userId: userIdClaim,
+ email: typeof claims.email === 'string' ? claims.email : undefined,
+ name: typeof claims.name === 'string' ? claims.name : undefined,
+ };
+}
+
+async function createCodeChallenge(codeVerifier: string) {
+ const digest = await crypto.subtle.digest(
+ 'SHA-256',
+ new TextEncoder().encode(codeVerifier)
+ );
+
+ return encodeBase64Url(digest);
+}
+
+function createRandomBase64Url(byteLength: number) {
+ const bytes = new Uint8Array(byteLength);
+ crypto.getRandomValues(bytes);
+ return encodeBase64Url(bytes.buffer);
+}
+
+async function redirectToKeycloakLoginAsync(): Promise {
+ const codeVerifier = createRandomBase64Url(64);
+ const state = createRandomBase64Url(32);
+ const codeChallenge = await createCodeChallenge(codeVerifier);
+ const returnUrl = `${window.location.pathname}${window.location.search}${window.location.hash}`;
+ const pkceState: KeycloakPkceState = {
+ codeVerifier,
+ state,
+ returnUrl,
+ };
+
+ sessionStorage.setItem(keycloakPkceStorageKey, JSON.stringify(pkceState));
+
+ const authorizationUrl = new URL(keycloakEndpoint('auth'));
+ authorizationUrl.searchParams.set(
+ 'client_id',
+ import.meta.env.VITE_APP_AUTH_CLIENT_ID
+ );
+ authorizationUrl.searchParams.set(
+ 'redirect_uri',
+ import.meta.env.VITE_APP_AUTH_REDIRECT_URI
+ );
+ authorizationUrl.searchParams.set('response_type', 'code');
+ authorizationUrl.searchParams.set('scope', scopes.join(' '));
+ authorizationUrl.searchParams.set('state', state);
+ authorizationUrl.searchParams.set('code_challenge', codeChallenge);
+ authorizationUrl.searchParams.set('code_challenge_method', 'S256');
+
+ setTimeout(() => {
+ window.location.assign(authorizationUrl.toString());
+ }, 0);
+
+ return await new Promise(() => {});
+}
+
+function readKeycloakPkceState(): KeycloakPkceState {
+ const storedState = sessionStorage.getItem(keycloakPkceStorageKey);
+ if (!storedState) {
+ throw new Error('Missing Keycloak sign-in state.');
+ }
+
+ return JSON.parse(storedState) as KeycloakPkceState;
+}
+
+async function exchangeKeycloakCodeAsync(code: string, codeVerifier: string) {
+ const response = await fetch(keycloakEndpoint('token'), {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ body: new URLSearchParams({
+ client_id: import.meta.env.VITE_APP_AUTH_CLIENT_ID,
+ code,
+ code_verifier: codeVerifier,
+ grant_type: 'authorization_code',
+ redirect_uri: import.meta.env.VITE_APP_AUTH_REDIRECT_URI,
+ }),
+ });
+
+ if (!response.ok) {
+ throw new Error(`Keycloak token exchange failed with ${response.status}.`);
+ }
+
+ return storeKeycloakTokens(await response.json());
+}
+
+async function handleKeycloakRedirectAsync(): Promise {
+ const query = new URLSearchParams(window.location.search);
+ const code = query.get('code');
+ const state = query.get('state');
+ if (!code || !state) {
+ return null;
+ }
+
+ const pkceState = readKeycloakPkceState();
+ if (pkceState.state !== state) {
+ throw new Error('The Keycloak sign-in state did not match.');
+ }
+
+ const tokens = await exchangeKeycloakCodeAsync(code, pkceState.codeVerifier);
+ sessionStorage.removeItem(keycloakPkceStorageKey);
+ window.history.replaceState({}, document.title, pkceState.returnUrl || '/');
+
+ return keycloakAccountFromTokens(tokens);
+}
+
+async function refreshKeycloakTokensAsync(tokens: KeycloakTokens) {
+ if (!tokens.refreshToken) {
+ return null;
+ }
+
+ const response = await fetch(keycloakEndpoint('token'), {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ body: new URLSearchParams({
+ client_id: import.meta.env.VITE_APP_AUTH_CLIENT_ID,
+ grant_type: 'refresh_token',
+ refresh_token: tokens.refreshToken,
+ }),
+ });
+
+ if (!response.ok) {
+ localStorage.removeItem(keycloakTokenStorageKey);
+ return null;
+ }
+
+ return storeKeycloakTokens(await response.json());
+}
+
+async function loginAndSetActiveKeycloakAccountAsync(): Promise {
+ trace(`Login`, `Checking for a Keycloak redirect response...`);
+ const redirectedAccount = await handleKeycloakRedirectAsync();
+ if (redirectedAccount) {
+ return redirectedAccount;
+ }
+
+ const storedTokens = readStoredKeycloakTokens();
+ if (storedTokens && keycloakTokensAreCurrent(storedTokens)) {
+ return keycloakAccountFromTokens(storedTokens);
+ }
+
+ if (storedTokens) {
+ const refreshedTokens = await refreshKeycloakTokensAsync(storedTokens);
+ if (refreshedTokens) {
+ return keycloakAccountFromTokens(refreshedTokens);
+ }
+ }
+
+ await redirectToKeycloakLoginAsync();
+ throw new Error('Redirecting to Keycloak for sign-in.');
+}
+
async function loginAndSetActiveAccountAsync(): Promise {
+ if (keycloakAuthEnabled) {
+ return await loginAndSetActiveKeycloakAccountAsync();
+ }
+
// The ultimate objective of this function is to obtain an AuthenticationResult from Azure AD via MSAL.js
// and return the local account ID of the authenticated account.
let result: AuthenticationResult | null = null;
@@ -217,6 +491,20 @@ export const accountInfoState = atom({
});
export async function tryAcquireAccessToken(): Promise {
+ if (keycloakAuthEnabled) {
+ const storedTokens = readStoredKeycloakTokens();
+ if (!storedTokens) {
+ return null;
+ }
+
+ if (keycloakTokensAreCurrent(storedTokens)) {
+ return storedTokens.accessToken;
+ }
+
+ const refreshedTokens = await refreshKeycloakTokensAsync(storedTokens);
+ return refreshedTokens?.accessToken ?? null;
+ }
+
// This function attempts to return a current access token for the authenticated account using MSAL.js and,
// if it can't due to required interaction, informs the caller by returning null.
// https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/acquire-token.md
@@ -263,6 +551,24 @@ export async function tryAcquireAccessToken(): Promise {
}
export async function logoutAsync(): Promise {
+ if (keycloakAuthEnabled) {
+ const storedTokens = readStoredKeycloakTokens();
+ localStorage.removeItem(keycloakTokenStorageKey);
+
+ const logoutUrl = new URL(keycloakEndpoint('logout'));
+ logoutUrl.searchParams.set(
+ 'post_logout_redirect_uri',
+ import.meta.env.VITE_APP_AUTH_REDIRECT_URI
+ );
+
+ if (storedTokens?.idToken) {
+ logoutUrl.searchParams.set('id_token_hint', storedTokens.idToken);
+ }
+
+ window.location.assign(logoutUrl.toString());
+ return;
+ }
+
trace(`Logout`, `Signing out the active account...`);
await globalMsalInstance.logoutRedirect({
diff --git a/src/caretogether-pwa/src/GeneratedClient.ts b/src/caretogether-pwa/src/GeneratedClient.ts
index 81b4323b0..83a0d18ec 100644
--- a/src/caretogether-pwa/src/GeneratedClient.ts
+++ b/src/caretogether-pwa/src/GeneratedClient.ts
@@ -1,10 +1,9 @@
//----------------------
//
-// Generated using the NSwag toolchain v14.0.8.0 (NJsonSchema v11.0.1.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org)
+// Generated using the NSwag toolchain v14.7.1.0 (NJsonSchema v11.6.1.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org)
//
//----------------------
-/* tslint:disable */
/* eslint-disable */
// ReSharper disable InconsistentNaming
@@ -21,10 +20,10 @@ export class CommunicationsClient {
sendSmsToFamilyPrimaryContacts(organizationId: string, locationId: string, request: SendSmsToFamilyPrimaryContactsRequest): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Communications/sendSmsToFamilyPrimaryContacts";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
url_ = url_.replace(/[?&]$/, "");
@@ -57,7 +56,7 @@ export class CommunicationsClient {
result200!.push(ValueTupleOfGuidAndSmsMessageResult.fromJS(item));
}
else {
- result200 = null;
+ result200 = null as any;
}
return result200;
});
@@ -83,7 +82,7 @@ export class ConfigurationClient {
getOrganizationConfiguration(organizationId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/Configuration";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
url_ = url_.replace(/[?&]$/, "");
@@ -120,7 +119,7 @@ export class ConfigurationClient {
putLocationDefinition(organizationId: string, newLocationPayload: PutLocationPayload): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/Configuration";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
url_ = url_.replace(/[?&]$/, "");
@@ -161,10 +160,10 @@ export class ConfigurationClient {
putRoleDefinition(organizationId: string, roleName: string, role: RoleDefinition): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/Configuration/roles/{roleName}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (roleName === undefined || roleName === null)
- throw new Error("The parameter 'roleName' must be defined.");
+ throw new globalThis.Error("The parameter 'roleName' must be defined.");
url_ = url_.replace("{roleName}", encodeURIComponent("" + roleName));
url_ = url_.replace(/[?&]$/, "");
@@ -205,10 +204,10 @@ export class ConfigurationClient {
deleteRoleDefinition(organizationId: string, roleName: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/Configuration/roles/{roleName}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (roleName === undefined || roleName === null)
- throw new Error("The parameter 'roleName' must be defined.");
+ throw new globalThis.Error("The parameter 'roleName' must be defined.");
url_ = url_.replace("{roleName}", encodeURIComponent("" + roleName));
url_ = url_.replace(/[?&]$/, "");
@@ -245,10 +244,10 @@ export class ConfigurationClient {
getEffectiveLocationPolicy(organizationId: string, locationId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Configuration/policy";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
url_ = url_.replace(/[?&]$/, "");
@@ -285,10 +284,10 @@ export class ConfigurationClient {
getLocationFlags(organizationId: string, locationId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Configuration/flags";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
url_ = url_.replace(/[?&]$/, "");
@@ -336,16 +335,16 @@ export class FilesClient {
getFamilyDocumentReadValetUrl(organizationId: string, locationId: string, familyId: string, documentId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Files/family/{familyId}/{documentId}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
if (familyId === undefined || familyId === null)
- throw new Error("The parameter 'familyId' must be defined.");
+ throw new globalThis.Error("The parameter 'familyId' must be defined.");
url_ = url_.replace("{familyId}", encodeURIComponent("" + familyId));
if (documentId === undefined || documentId === null)
- throw new Error("The parameter 'documentId' must be defined.");
+ throw new globalThis.Error("The parameter 'documentId' must be defined.");
url_ = url_.replace("{documentId}", encodeURIComponent("" + documentId));
url_ = url_.replace(/[?&]$/, "");
@@ -368,7 +367,7 @@ export class FilesClient {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
- result200 = resultData200 !== undefined ? resultData200 : null;
+ result200 = resultData200 !== undefined ? resultData200 : null as any;
return result200;
});
@@ -383,16 +382,16 @@ export class FilesClient {
generateFamilyDocumentUploadValetUrl(organizationId: string, locationId: string, familyId: string, documentId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Files/upload/family/{familyId}/{documentId}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
if (familyId === undefined || familyId === null)
- throw new Error("The parameter 'familyId' must be defined.");
+ throw new globalThis.Error("The parameter 'familyId' must be defined.");
url_ = url_.replace("{familyId}", encodeURIComponent("" + familyId));
if (documentId === undefined || documentId === null)
- throw new Error("The parameter 'documentId' must be defined.");
+ throw new globalThis.Error("The parameter 'documentId' must be defined.");
url_ = url_.replace("{documentId}", encodeURIComponent("" + documentId));
url_ = url_.replace(/[?&]$/, "");
@@ -429,16 +428,16 @@ export class FilesClient {
getCommunityDocumentReadValetUrl(organizationId: string, locationId: string, communityId: string, documentId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Files/community/{communityId}/{documentId}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
if (communityId === undefined || communityId === null)
- throw new Error("The parameter 'communityId' must be defined.");
+ throw new globalThis.Error("The parameter 'communityId' must be defined.");
url_ = url_.replace("{communityId}", encodeURIComponent("" + communityId));
if (documentId === undefined || documentId === null)
- throw new Error("The parameter 'documentId' must be defined.");
+ throw new globalThis.Error("The parameter 'documentId' must be defined.");
url_ = url_.replace("{documentId}", encodeURIComponent("" + documentId));
url_ = url_.replace(/[?&]$/, "");
@@ -461,7 +460,7 @@ export class FilesClient {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
- result200 = resultData200 !== undefined ? resultData200 : null;
+ result200 = resultData200 !== undefined ? resultData200 : null as any;
return result200;
});
@@ -476,16 +475,16 @@ export class FilesClient {
generateCommunityDocumentUploadValetUrl(organizationId: string, locationId: string, communityId: string, documentId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Files/upload/community/{communityId}/{documentId}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
if (communityId === undefined || communityId === null)
- throw new Error("The parameter 'communityId' must be defined.");
+ throw new globalThis.Error("The parameter 'communityId' must be defined.");
url_ = url_.replace("{communityId}", encodeURIComponent("" + communityId));
if (documentId === undefined || documentId === null)
- throw new Error("The parameter 'documentId' must be defined.");
+ throw new globalThis.Error("The parameter 'documentId' must be defined.");
url_ = url_.replace("{documentId}", encodeURIComponent("" + documentId));
url_ = url_.replace(/[?&]$/, "");
@@ -522,16 +521,16 @@ export class FilesClient {
getV1ReferralDocumentReadValetUrl(organizationId: string, locationId: string, referralId: string, documentId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Files/v1referral/{referralId}/{documentId}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
if (referralId === undefined || referralId === null)
- throw new Error("The parameter 'referralId' must be defined.");
+ throw new globalThis.Error("The parameter 'referralId' must be defined.");
url_ = url_.replace("{referralId}", encodeURIComponent("" + referralId));
if (documentId === undefined || documentId === null)
- throw new Error("The parameter 'documentId' must be defined.");
+ throw new globalThis.Error("The parameter 'documentId' must be defined.");
url_ = url_.replace("{documentId}", encodeURIComponent("" + documentId));
url_ = url_.replace(/[?&]$/, "");
@@ -554,7 +553,7 @@ export class FilesClient {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
- result200 = resultData200 !== undefined ? resultData200 : null;
+ result200 = resultData200 !== undefined ? resultData200 : null as any;
return result200;
});
@@ -569,16 +568,16 @@ export class FilesClient {
generateV1ReferralDocumentUploadValetUrl(organizationId: string, locationId: string, referralId: string, documentId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Files/upload/v1referral/{referralId}/{documentId}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
if (referralId === undefined || referralId === null)
- throw new Error("The parameter 'referralId' must be defined.");
+ throw new globalThis.Error("The parameter 'referralId' must be defined.");
url_ = url_.replace("{referralId}", encodeURIComponent("" + referralId));
if (documentId === undefined || documentId === null)
- throw new Error("The parameter 'documentId' must be defined.");
+ throw new globalThis.Error("The parameter 'documentId' must be defined.");
url_ = url_.replace("{documentId}", encodeURIComponent("" + documentId));
url_ = url_.replace(/[?&]$/, "");
@@ -626,10 +625,10 @@ export class RecordsClient {
listVisibleAggregates(organizationId: string, locationId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Records";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
url_ = url_.replace(/[?&]$/, "");
@@ -658,7 +657,7 @@ export class RecordsClient {
result200!.push(RecordsAggregate.fromJS(item));
}
else {
- result200 = null;
+ result200 = null as any;
}
return result200;
});
@@ -673,10 +672,10 @@ export class RecordsClient {
submitAtomicRecordsCommand(organizationId: string, locationId: string, command: AtomicRecordsCommand): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Records/atomicRecordsCommand";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
url_ = url_.replace(/[?&]$/, "");
@@ -709,7 +708,7 @@ export class RecordsClient {
result200!.push(RecordsAggregate.fromJS(item));
}
else {
- result200 = null;
+ result200 = null as any;
}
return result200;
});
@@ -724,10 +723,10 @@ export class RecordsClient {
submitCompositeRecordsCommand(organizationId: string, locationId: string, command: CompositeRecordsCommand): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Records/compositeRecordsCommand";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
url_ = url_.replace(/[?&]$/, "");
@@ -760,7 +759,7 @@ export class RecordsClient {
result200!.push(RecordsAggregate.fromJS(item));
}
else {
- result200 = null;
+ result200 = null as any;
}
return result200;
});
@@ -775,10 +774,10 @@ export class RecordsClient {
getEmbedInfo(organizationId: string, locationId: string): Promise {
let url_ = this.baseUrl + "/api/{organizationId}/{locationId}/Records/getEmbedInfo";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
url_ = url_.replace(/[?&]$/, "");
@@ -880,7 +879,7 @@ export class UsersClient {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
- result200 = resultData200 !== undefined ? resultData200 : null;
+ result200 = resultData200 !== undefined ? resultData200 : null as any;
return result200;
});
@@ -895,13 +894,13 @@ export class UsersClient {
getPersonLoginInfo(organizationId: string, locationId: string, personId: string): Promise {
let url_ = this.baseUrl + "/api/Users/loginInfo/{organizationId}/{locationId}/{personId}";
if (organizationId === undefined || organizationId === null)
- throw new Error("The parameter 'organizationId' must be defined.");
+ throw new globalThis.Error("The parameter 'organizationId' must be defined.");
url_ = url_.replace("{organizationId}", encodeURIComponent("" + organizationId));
if (locationId === undefined || locationId === null)
- throw new Error("The parameter 'locationId' must be defined.");
+ throw new globalThis.Error("The parameter 'locationId' must be defined.");
url_ = url_.replace("{locationId}", encodeURIComponent("" + locationId));
if (personId === undefined || personId === null)
- throw new Error("The parameter 'personId' must be defined.");
+ throw new globalThis.Error("The parameter 'personId' must be defined.");
url_ = url_.replace("{personId}", encodeURIComponent("" + personId));
url_ = url_.replace(/[?&]$/, "");
@@ -938,15 +937,15 @@ export class UsersClient {
changePersonRoles(organizationId: string | undefined, locationId: string | undefined, personId: string | undefined, roles: string[]): Promise {
let url_ = this.baseUrl + "/api/Users/personRoles?";
if (organizationId === null)
- throw new Error("The parameter 'organizationId' cannot be null.");
+ throw new globalThis.Error("The parameter 'organizationId' cannot be null.");
else if (organizationId !== undefined)
url_ += "organizationId=" + encodeURIComponent("" + organizationId) + "&";
if (locationId === null)
- throw new Error("The parameter 'locationId' cannot be null.");
+ throw new globalThis.Error("The parameter 'locationId' cannot be null.");
else if (locationId !== undefined)
url_ += "locationId=" + encodeURIComponent("" + locationId) + "&";
if (personId === null)
- throw new Error("The parameter 'personId' cannot be null.");
+ throw new globalThis.Error("The parameter 'personId' cannot be null.");
else if (personId !== undefined)
url_ += "personId=" + encodeURIComponent("" + personId) + "&";
url_ = url_.replace(/[?&]$/, "");
@@ -988,15 +987,15 @@ export class UsersClient {
generatePersonInviteLink(organizationId: string | undefined, locationId: string | undefined, personId: string | undefined): Promise {
let url_ = this.baseUrl + "/api/Users/personInviteLink?";
if (organizationId === null)
- throw new Error("The parameter 'organizationId' cannot be null.");
+ throw new globalThis.Error("The parameter 'organizationId' cannot be null.");
else if (organizationId !== undefined)
url_ += "organizationId=" + encodeURIComponent("" + organizationId) + "&";
if (locationId === null)
- throw new Error("The parameter 'locationId' cannot be null.");
+ throw new globalThis.Error("The parameter 'locationId' cannot be null.");
else if (locationId !== undefined)
url_ += "locationId=" + encodeURIComponent("" + locationId) + "&";
if (personId === null)
- throw new Error("The parameter 'personId' cannot be null.");
+ throw new globalThis.Error("The parameter 'personId' cannot be null.");
else if (personId !== undefined)
url_ += "personId=" + encodeURIComponent("" + personId) + "&";
url_ = url_.replace(/[?&]$/, "");
@@ -1020,7 +1019,7 @@ export class UsersClient {
return response.text().then((_responseText) => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
- result200 = resultData200 !== undefined ? resultData200 : null;
+ result200 = resultData200 !== undefined ? resultData200 : null as any;
return result200;
});
@@ -1035,15 +1034,15 @@ export class UsersClient {
initiatePersonInviteRedemptionSession(organizationId: string | undefined, locationId: string | undefined, inviteNonce: string | undefined): Promise {
let url_ = this.baseUrl + "/api/Users/personInvite?";
if (organizationId === null)
- throw new Error("The parameter 'organizationId' cannot be null.");
+ throw new globalThis.Error("The parameter 'organizationId' cannot be null.");
else if (organizationId !== undefined)
url_ += "organizationId=" + encodeURIComponent("" + organizationId) + "&";
if (locationId === null)
- throw new Error("The parameter 'locationId' cannot be null.");
+ throw new globalThis.Error("The parameter 'locationId' cannot be null.");
else if (locationId !== undefined)
url_ += "locationId=" + encodeURIComponent("" + locationId) + "&";
if (inviteNonce === null)
- throw new Error("The parameter 'inviteNonce' cannot be null.");
+ throw new globalThis.Error("The parameter 'inviteNonce' cannot be null.");
else if (inviteNonce !== undefined)
url_ += "inviteNonce=" + encodeURIComponent("" + inviteNonce) + "&";
url_ = url_.replace(/[?&]$/, "");
@@ -1085,7 +1084,7 @@ export class UsersClient {
examinePersonInviteRedemptionSession(redemptionSessionId: string | undefined): Promise {
let url_ = this.baseUrl + "/api/Users/reviewInvite?";
if (redemptionSessionId === null)
- throw new Error("The parameter 'redemptionSessionId' cannot be null.");
+ throw new globalThis.Error("The parameter 'redemptionSessionId' cannot be null.");
else if (redemptionSessionId !== undefined)
url_ += "redemptionSessionId=" + encodeURIComponent("" + redemptionSessionId) + "&";
url_ = url_.replace(/[?&]$/, "");
@@ -1123,7 +1122,7 @@ export class UsersClient {
completePersonInviteRedemptionSession(redemptionSessionId: string | undefined): Promise {
let url_ = this.baseUrl + "/api/Users/confirmInvite?";
if (redemptionSessionId === null)
- throw new Error("The parameter 'redemptionSessionId' cannot be null.");
+ throw new globalThis.Error("The parameter 'redemptionSessionId' cannot be null.");
else if (redemptionSessionId !== undefined)
url_ += "redemptionSessionId=" + encodeURIComponent("" + redemptionSessionId) + "&";
url_ = url_.replace(/[?&]$/, "");
@@ -1167,7 +1166,7 @@ export class ValueTupleOfGuidAndSmsMessageResult implements IValueTupleOfGuidAnd
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -1192,7 +1191,7 @@ export class ValueTupleOfGuidAndSmsMessageResult implements IValueTupleOfGuidAnd
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["item1"] = this.item1;
- data["item2"] = this.item2 ? this.item2.toJSON() : undefined;
+ data["item2"] = this.item2 ? this.item2.toJSON() : undefined as any;
return data;
}
}
@@ -1210,7 +1209,7 @@ export class SmsMessageResult implements ISmsMessageResult {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -1258,7 +1257,7 @@ export class SendSmsToFamilyPrimaryContactsRequest implements ISendSmsToFamilyPr
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -1315,7 +1314,7 @@ export class OrganizationConfiguration implements IOrganizationConfiguration {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -1364,12 +1363,12 @@ export class OrganizationConfiguration implements IOrganizationConfiguration {
if (Array.isArray(this.locations)) {
data["locations"] = [];
for (let item of this.locations)
- data["locations"].push(item.toJSON());
+ data["locations"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.roles)) {
data["roles"] = [];
for (let item of this.roles)
- data["roles"].push(item.toJSON());
+ data["roles"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.communityRoles)) {
data["communityRoles"] = [];
@@ -1407,7 +1406,7 @@ export class LocationConfiguration implements ILocationConfiguration {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -1446,7 +1445,7 @@ export class LocationConfiguration implements ILocationConfiguration {
for (let item of _data["accessLevels"])
this.accessLevels!.push(AccessLevel.fromJS(item));
}
- this.timeZone = _data["timeZone"] ? TimeZoneInfo.fromJS(_data["timeZone"]) : undefined;
+ this.timeZone = _data["timeZone"] ? TimeZoneInfo.fromJS(_data["timeZone"]) : undefined as any;
}
}
@@ -1479,14 +1478,14 @@ export class LocationConfiguration implements ILocationConfiguration {
if (Array.isArray(this.smsSourcePhoneNumbers)) {
data["smsSourcePhoneNumbers"] = [];
for (let item of this.smsSourcePhoneNumbers)
- data["smsSourcePhoneNumbers"].push(item.toJSON());
+ data["smsSourcePhoneNumbers"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.accessLevels)) {
data["accessLevels"] = [];
for (let item of this.accessLevels)
- data["accessLevels"].push(item.toJSON());
+ data["accessLevels"].push(item ? item.toJSON() : undefined as any);
}
- data["timeZone"] = this.timeZone ? this.timeZone.toJSON() : undefined;
+ data["timeZone"] = this.timeZone ? this.timeZone.toJSON() : undefined as any;
return data;
}
}
@@ -1510,7 +1509,7 @@ export class SourcePhoneNumberConfiguration implements ISourcePhoneNumberConfigu
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -1552,7 +1551,7 @@ export class AccessLevel implements IAccessLevel {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -1623,7 +1622,7 @@ export class TimeZoneInfo implements ITimeZoneInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -1679,7 +1678,7 @@ export class RoleDefinition implements IRoleDefinition {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -1713,7 +1712,7 @@ export class RoleDefinition implements IRoleDefinition {
if (Array.isArray(this.permissionSets)) {
data["permissionSets"] = [];
for (let item of this.permissionSets)
- data["permissionSets"].push(item.toJSON());
+ data["permissionSets"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -1733,7 +1732,7 @@ export class ContextualPermissionSet implements IContextualPermissionSet {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -1743,7 +1742,7 @@ export class ContextualPermissionSet implements IContextualPermissionSet {
init(_data?: any) {
if (_data) {
- this.context = _data["context"] ? PermissionContext.fromJS(_data["context"]) : undefined;
+ this.context = _data["context"] ? PermissionContext.fromJS(_data["context"]) : undefined as any;
if (Array.isArray(_data["permissions"])) {
this.permissions = [] as any;
for (let item of _data["permissions"])
@@ -1761,7 +1760,7 @@ export class ContextualPermissionSet implements IContextualPermissionSet {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["context"] = this.context ? this.context.toJSON() : undefined;
+ data["context"] = this.context ? this.context.toJSON() : undefined as any;
if (Array.isArray(this.permissions)) {
data["permissions"] = [];
for (let item of this.permissions)
@@ -1784,7 +1783,7 @@ export abstract class PermissionContext implements IPermissionContext {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
this._discriminator = "PermissionContext";
@@ -1870,18 +1869,18 @@ export class AllPartneringFamiliesPermissionContext extends PermissionContext im
this._discriminator = "AllPartneringFamiliesPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
}
- static fromJS(data: any): AllPartneringFamiliesPermissionContext {
+ static override fromJS(data: any): AllPartneringFamiliesPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new AllPartneringFamiliesPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
super.toJSON(data);
return data;
@@ -1898,18 +1897,18 @@ export class AllVolunteerFamiliesPermissionContext extends PermissionContext imp
this._discriminator = "AllVolunteerFamiliesPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
}
- static fromJS(data: any): AllVolunteerFamiliesPermissionContext {
+ static override fromJS(data: any): AllVolunteerFamiliesPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new AllVolunteerFamiliesPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
super.toJSON(data);
return data;
@@ -1929,7 +1928,7 @@ export class AssignedFunctionsInReferralCoAssigneeFamiliesPermissionContext exte
this._discriminator = "AssignedFunctionsInReferralCoAssigneeFamiliesPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.whenReferralIsOpen = _data["whenReferralIsOpen"];
@@ -1946,14 +1945,14 @@ export class AssignedFunctionsInReferralCoAssigneeFamiliesPermissionContext exte
}
}
- static fromJS(data: any): AssignedFunctionsInReferralCoAssigneeFamiliesPermissionContext {
+ static override fromJS(data: any): AssignedFunctionsInReferralCoAssigneeFamiliesPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new AssignedFunctionsInReferralCoAssigneeFamiliesPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["whenReferralIsOpen"] = this.whenReferralIsOpen;
if (Array.isArray(this.whenOwnFunctionIsIn)) {
@@ -1986,7 +1985,7 @@ export class AssignedFunctionsInReferralPartneringFamilyPermissionContext extend
this._discriminator = "AssignedFunctionsInReferralPartneringFamilyPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.whenReferralIsOpen = _data["whenReferralIsOpen"];
@@ -1998,14 +1997,14 @@ export class AssignedFunctionsInReferralPartneringFamilyPermissionContext extend
}
}
- static fromJS(data: any): AssignedFunctionsInReferralPartneringFamilyPermissionContext {
+ static override fromJS(data: any): AssignedFunctionsInReferralPartneringFamilyPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new AssignedFunctionsInReferralPartneringFamilyPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["whenReferralIsOpen"] = this.whenReferralIsOpen;
if (Array.isArray(this.whenOwnFunctionIsIn)) {
@@ -2031,7 +2030,7 @@ export class CommunityCoMemberFamiliesAssignedFunctionsInReferralCoAssignedFamil
this._discriminator = "CommunityCoMemberFamiliesAssignedFunctionsInReferralCoAssignedFamiliesPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
if (Array.isArray(_data["whenOwnCommunityRoleIsIn"])) {
@@ -2042,14 +2041,14 @@ export class CommunityCoMemberFamiliesAssignedFunctionsInReferralCoAssignedFamil
}
}
- static fromJS(data: any): CommunityCoMemberFamiliesAssignedFunctionsInReferralCoAssignedFamiliesPermissionContext {
+ static override fromJS(data: any): CommunityCoMemberFamiliesAssignedFunctionsInReferralCoAssignedFamiliesPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new CommunityCoMemberFamiliesAssignedFunctionsInReferralCoAssignedFamiliesPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.whenOwnCommunityRoleIsIn)) {
data["whenOwnCommunityRoleIsIn"] = [];
@@ -2073,7 +2072,7 @@ export class CommunityCoMemberFamiliesAssignedFunctionsInReferralPartneringFamil
this._discriminator = "CommunityCoMemberFamiliesAssignedFunctionsInReferralPartneringFamilyPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
if (Array.isArray(_data["whenOwnCommunityRoleIsIn"])) {
@@ -2084,14 +2083,14 @@ export class CommunityCoMemberFamiliesAssignedFunctionsInReferralPartneringFamil
}
}
- static fromJS(data: any): CommunityCoMemberFamiliesAssignedFunctionsInReferralPartneringFamilyPermissionContext {
+ static override fromJS(data: any): CommunityCoMemberFamiliesAssignedFunctionsInReferralPartneringFamilyPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new CommunityCoMemberFamiliesAssignedFunctionsInReferralPartneringFamilyPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.whenOwnCommunityRoleIsIn)) {
data["whenOwnCommunityRoleIsIn"] = [];
@@ -2115,7 +2114,7 @@ export class CommunityCoMemberFamiliesPermissionContext extends PermissionContex
this._discriminator = "CommunityCoMemberFamiliesPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
if (Array.isArray(_data["whenOwnCommunityRoleIsIn"])) {
@@ -2126,14 +2125,14 @@ export class CommunityCoMemberFamiliesPermissionContext extends PermissionContex
}
}
- static fromJS(data: any): CommunityCoMemberFamiliesPermissionContext {
+ static override fromJS(data: any): CommunityCoMemberFamiliesPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new CommunityCoMemberFamiliesPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.whenOwnCommunityRoleIsIn)) {
data["whenOwnCommunityRoleIsIn"] = [];
@@ -2157,7 +2156,7 @@ export class CommunityMemberPermissionContext extends PermissionContext implemen
this._discriminator = "CommunityMemberPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
if (Array.isArray(_data["whenOwnCommunityRoleIsIn"])) {
@@ -2168,14 +2167,14 @@ export class CommunityMemberPermissionContext extends PermissionContext implemen
}
}
- static fromJS(data: any): CommunityMemberPermissionContext {
+ static override fromJS(data: any): CommunityMemberPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new CommunityMemberPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.whenOwnCommunityRoleIsIn)) {
data["whenOwnCommunityRoleIsIn"] = [];
@@ -2198,18 +2197,18 @@ export class GlobalPermissionContext extends PermissionContext implements IGloba
this._discriminator = "GlobalPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
}
- static fromJS(data: any): GlobalPermissionContext {
+ static override fromJS(data: any): GlobalPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new GlobalPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
super.toJSON(data);
return data;
@@ -2226,18 +2225,18 @@ export class OwnFamilyPermissionContext extends PermissionContext implements IOw
this._discriminator = "OwnFamilyPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
}
- static fromJS(data: any): OwnFamilyPermissionContext {
+ static override fromJS(data: any): OwnFamilyPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new OwnFamilyPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
super.toJSON(data);
return data;
@@ -2256,7 +2255,7 @@ export class OwnReferralAssigneeFamiliesPermissionContext extends PermissionCont
this._discriminator = "OwnReferralAssigneeFamiliesPermissionContext";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.whenReferralIsOpen = _data["whenReferralIsOpen"];
@@ -2268,14 +2267,14 @@ export class OwnReferralAssigneeFamiliesPermissionContext extends PermissionCont
}
}
- static fromJS(data: any): OwnReferralAssigneeFamiliesPermissionContext {
+ static override fromJS(data: any): OwnReferralAssigneeFamiliesPermissionContext {
data = typeof data === 'object' ? data : {};
let result = new OwnReferralAssigneeFamiliesPermissionContext();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["whenReferralIsOpen"] = this.whenReferralIsOpen;
if (Array.isArray(this.whenAssigneeFunctionIsIn)) {
@@ -2380,7 +2379,7 @@ export class PutLocationPayload implements IPutLocationPayload {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -2404,7 +2403,7 @@ export class PutLocationPayload implements IPutLocationPayload {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["locationConfiguration"] = this.locationConfiguration ? this.locationConfiguration.toJSON() : undefined;
+ data["locationConfiguration"] = this.locationConfiguration ? this.locationConfiguration.toJSON() : undefined as any;
data["copyPoliciesFromLocationId"] = this.copyPoliciesFromLocationId;
return data;
}
@@ -2425,7 +2424,7 @@ export class EffectiveLocationPolicy implements IEffectiveLocationPolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -2442,7 +2441,7 @@ export class EffectiveLocationPolicy implements IEffectiveLocationPolicy {
this.actionDefinitions = {} as any;
for (let key in _data["actionDefinitions"]) {
if (_data["actionDefinitions"].hasOwnProperty(key))
- (this.actionDefinitions)![key] = _data["actionDefinitions"][key] ? ActionRequirement.fromJS(_data["actionDefinitions"][key]) : new ActionRequirement();
+ (this.actionDefinitions as any)![key] = _data["actionDefinitions"][key] ? ActionRequirement.fromJS(_data["actionDefinitions"][key]) : new ActionRequirement();
}
}
if (Array.isArray(_data["customFamilyFields"])) {
@@ -2468,16 +2467,16 @@ export class EffectiveLocationPolicy implements IEffectiveLocationPolicy {
data["actionDefinitions"] = {};
for (let key in this.actionDefinitions) {
if (this.actionDefinitions.hasOwnProperty(key))
- (data["actionDefinitions"])[key] = this.actionDefinitions[key] ? this.actionDefinitions[key].toJSON() : undefined;
+ (data["actionDefinitions"] as any)[key] = this.actionDefinitions[key] ? this.actionDefinitions[key].toJSON() : undefined as any;
}
}
if (Array.isArray(this.customFamilyFields)) {
data["customFamilyFields"] = [];
for (let item of this.customFamilyFields)
- data["customFamilyFields"].push(item.toJSON());
+ data["customFamilyFields"].push(item ? item.toJSON() : undefined as any);
}
- data["referralPolicy"] = this.referralPolicy ? this.referralPolicy.toJSON() : undefined;
- data["volunteerPolicy"] = this.volunteerPolicy ? this.volunteerPolicy.toJSON() : undefined;
+ data["referralPolicy"] = this.referralPolicy ? this.referralPolicy.toJSON() : undefined as any;
+ data["volunteerPolicy"] = this.volunteerPolicy ? this.volunteerPolicy.toJSON() : undefined as any;
return data;
}
}
@@ -2503,7 +2502,7 @@ export class ActionRequirement implements IActionRequirement {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -2583,7 +2582,7 @@ export class CustomField implements ICustomField {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -2650,7 +2649,7 @@ export class V1CasePolicy implements IV1CasePolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -2708,7 +2707,7 @@ export class V1CasePolicy implements IV1CasePolicy {
if (Array.isArray(this.intakeRequirements_PRE_MIGRATION)) {
data["intakeRequirements_PRE_MIGRATION"] = [];
for (let item of this.intakeRequirements_PRE_MIGRATION)
- data["intakeRequirements_PRE_MIGRATION"].push(item.toJSON());
+ data["intakeRequirements_PRE_MIGRATION"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredIntakeActionNames)) {
data["requiredIntakeActionNames"] = [];
@@ -2718,22 +2717,22 @@ export class V1CasePolicy implements IV1CasePolicy {
if (Array.isArray(this.customFields)) {
data["customFields"] = [];
for (let item of this.customFields)
- data["customFields"].push(item.toJSON());
+ data["customFields"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.arrangementPolicies)) {
data["arrangementPolicies"] = [];
for (let item of this.arrangementPolicies)
- data["arrangementPolicies"].push(item.toJSON());
+ data["arrangementPolicies"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.functionPolicies)) {
data["functionPolicies"] = [];
for (let item of this.functionPolicies)
- data["functionPolicies"].push(item.toJSON());
+ data["functionPolicies"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.intakeRequirements)) {
data["intakeRequirements"] = [];
for (let item of this.intakeRequirements)
- data["intakeRequirements"].push(item.toJSON());
+ data["intakeRequirements"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -2756,7 +2755,7 @@ export class RequirementDefinition implements IRequirementDefinition {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -2806,7 +2805,7 @@ export class ArrangementPolicy implements IArrangementPolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -2889,24 +2888,24 @@ export class ArrangementPolicy implements IArrangementPolicy {
if (Array.isArray(this.requiredSetupActions_PRE_MIGRATION)) {
data["requiredSetupActions_PRE_MIGRATION"] = [];
for (let item of this.requiredSetupActions_PRE_MIGRATION)
- data["requiredSetupActions_PRE_MIGRATION"].push(item.toJSON());
+ data["requiredSetupActions_PRE_MIGRATION"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredMonitoringActions_PRE_MIGRATION)) {
data["requiredMonitoringActions_PRE_MIGRATION"] = [];
for (let item of this.requiredMonitoringActions_PRE_MIGRATION)
- data["requiredMonitoringActions_PRE_MIGRATION"].push(item.toJSON());
+ data["requiredMonitoringActions_PRE_MIGRATION"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredCloseoutActionNames_PRE_MIGRATION)) {
data["requiredCloseoutActionNames_PRE_MIGRATION"] = [];
for (let item of this.requiredCloseoutActionNames_PRE_MIGRATION)
- data["requiredCloseoutActionNames_PRE_MIGRATION"].push(item.toJSON());
+ data["requiredCloseoutActionNames_PRE_MIGRATION"].push(item ? item.toJSON() : undefined as any);
}
data["arrangementType"] = this.arrangementType;
data["childInvolvement"] = this.childInvolvement;
if (Array.isArray(this.arrangementFunctions)) {
data["arrangementFunctions"] = [];
for (let item of this.arrangementFunctions)
- data["arrangementFunctions"].push(item.toJSON());
+ data["arrangementFunctions"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredSetupActionNames)) {
data["requiredSetupActionNames"] = [];
@@ -2916,7 +2915,7 @@ export class ArrangementPolicy implements IArrangementPolicy {
if (Array.isArray(this.requiredMonitoringActions)) {
data["requiredMonitoringActions"] = [];
for (let item of this.requiredMonitoringActions)
- data["requiredMonitoringActions"].push(item.toJSON());
+ data["requiredMonitoringActions"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredCloseoutActionNames)) {
data["requiredCloseoutActionNames"] = [];
@@ -2926,17 +2925,17 @@ export class ArrangementPolicy implements IArrangementPolicy {
if (Array.isArray(this.requiredSetupActions)) {
data["requiredSetupActions"] = [];
for (let item of this.requiredSetupActions)
- data["requiredSetupActions"].push(item.toJSON());
+ data["requiredSetupActions"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredMonitoringActionsNew)) {
data["requiredMonitoringActionsNew"] = [];
for (let item of this.requiredMonitoringActionsNew)
- data["requiredMonitoringActionsNew"].push(item.toJSON());
+ data["requiredMonitoringActionsNew"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredCloseoutActions)) {
data["requiredCloseoutActions"] = [];
for (let item of this.requiredCloseoutActions)
- data["requiredCloseoutActions"].push(item.toJSON());
+ data["requiredCloseoutActions"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -2965,7 +2964,7 @@ export class MonitoringRequirement implements IMonitoringRequirement {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -2976,7 +2975,7 @@ export class MonitoringRequirement implements IMonitoringRequirement {
init(_data?: any) {
if (_data) {
this.action = _data["action"] ? RequirementDefinition.fromJS(_data["action"]) : new RequirementDefinition();
- this.recurrence = _data["recurrence"] ? RecurrencePolicy.fromJS(_data["recurrence"]) : undefined;
+ this.recurrence = _data["recurrence"] ? RecurrencePolicy.fromJS(_data["recurrence"]) : undefined as any;
}
}
@@ -2989,8 +2988,8 @@ export class MonitoringRequirement implements IMonitoringRequirement {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["action"] = this.action ? this.action.toJSON() : undefined;
- data["recurrence"] = this.recurrence ? this.recurrence.toJSON() : undefined;
+ data["action"] = this.action ? this.action.toJSON() : undefined as any;
+ data["recurrence"] = this.recurrence ? this.recurrence.toJSON() : undefined as any;
return data;
}
}
@@ -3008,7 +3007,7 @@ export abstract class RecurrencePolicy implements IRecurrencePolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
this._discriminator = "RecurrencePolicy";
@@ -3063,7 +3062,7 @@ export class ChildCareOccurrenceBasedRecurrencePolicy extends RecurrencePolicy i
this._discriminator = "ChildCareOccurrenceBasedRecurrencePolicy";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.delay = _data["delay"];
@@ -3073,14 +3072,14 @@ export class ChildCareOccurrenceBasedRecurrencePolicy extends RecurrencePolicy i
}
}
- static fromJS(data: any): ChildCareOccurrenceBasedRecurrencePolicy {
+ static override fromJS(data: any): ChildCareOccurrenceBasedRecurrencePolicy {
data = typeof data === 'object' ? data : {};
let result = new ChildCareOccurrenceBasedRecurrencePolicy();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["delay"] = this.delay;
data["frequency"] = this.frequency;
@@ -3109,7 +3108,7 @@ export class DurationStagesPerChildLocationRecurrencePolicy extends RecurrencePo
this._discriminator = "DurationStagesPerChildLocationRecurrencePolicy";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
if (Array.isArray(_data["stages"])) {
@@ -3120,19 +3119,19 @@ export class DurationStagesPerChildLocationRecurrencePolicy extends RecurrencePo
}
}
- static fromJS(data: any): DurationStagesPerChildLocationRecurrencePolicy {
+ static override fromJS(data: any): DurationStagesPerChildLocationRecurrencePolicy {
data = typeof data === 'object' ? data : {};
let result = new DurationStagesPerChildLocationRecurrencePolicy();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.stages)) {
data["stages"] = [];
for (let item of this.stages)
- data["stages"].push(item.toJSON());
+ data["stages"].push(item ? item.toJSON() : undefined as any);
}
super.toJSON(data);
return data;
@@ -3151,7 +3150,7 @@ export class RecurrencePolicyStage implements IRecurrencePolicyStage {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -3194,7 +3193,7 @@ export class DurationStagesRecurrencePolicy extends RecurrencePolicy implements
this._discriminator = "DurationStagesRecurrencePolicy";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
if (Array.isArray(_data["stages"])) {
@@ -3205,19 +3204,19 @@ export class DurationStagesRecurrencePolicy extends RecurrencePolicy implements
}
}
- static fromJS(data: any): DurationStagesRecurrencePolicy {
+ static override fromJS(data: any): DurationStagesRecurrencePolicy {
data = typeof data === 'object' ? data : {};
let result = new DurationStagesRecurrencePolicy();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.stages)) {
data["stages"] = [];
for (let item of this.stages)
- data["stages"].push(item.toJSON());
+ data["stages"].push(item ? item.toJSON() : undefined as any);
}
super.toJSON(data);
return data;
@@ -3236,21 +3235,21 @@ export class OneTimeRecurrencePolicy extends RecurrencePolicy implements IOneTim
this._discriminator = "OneTimeRecurrencePolicy";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.delay = _data["delay"];
}
}
- static fromJS(data: any): OneTimeRecurrencePolicy {
+ static override fromJS(data: any): OneTimeRecurrencePolicy {
data = typeof data === 'object' ? data : {};
let result = new OneTimeRecurrencePolicy();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["delay"] = this.delay;
super.toJSON(data);
@@ -3281,7 +3280,7 @@ export class ArrangementFunction implements IArrangementFunction {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3345,7 +3344,7 @@ export class ArrangementFunction implements IArrangementFunction {
if (Array.isArray(this.variants)) {
data["variants"] = [];
for (let item of this.variants)
- data["variants"].push(item.toJSON());
+ data["variants"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -3382,7 +3381,7 @@ export class ArrangementFunctionVariant implements IArrangementFunctionVariant {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3458,17 +3457,17 @@ export class ArrangementFunctionVariant implements IArrangementFunctionVariant {
if (Array.isArray(this.requiredSetupActionNames_PRE_MIGRATION)) {
data["requiredSetupActionNames_PRE_MIGRATION"] = [];
for (let item of this.requiredSetupActionNames_PRE_MIGRATION)
- data["requiredSetupActionNames_PRE_MIGRATION"].push(item.toJSON());
+ data["requiredSetupActionNames_PRE_MIGRATION"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredMonitoringActions_PRE_MIGRATION)) {
data["requiredMonitoringActions_PRE_MIGRATION"] = [];
for (let item of this.requiredMonitoringActions_PRE_MIGRATION)
- data["requiredMonitoringActions_PRE_MIGRATION"].push(item.toJSON());
+ data["requiredMonitoringActions_PRE_MIGRATION"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredCloseoutActionNames_PRE_MIGRATION)) {
data["requiredCloseoutActionNames_PRE_MIGRATION"] = [];
for (let item of this.requiredCloseoutActionNames_PRE_MIGRATION)
- data["requiredCloseoutActionNames_PRE_MIGRATION"].push(item.toJSON());
+ data["requiredCloseoutActionNames_PRE_MIGRATION"].push(item ? item.toJSON() : undefined as any);
}
data["variantName"] = this.variantName;
if (Array.isArray(this.requiredSetupActionNames)) {
@@ -3479,7 +3478,7 @@ export class ArrangementFunctionVariant implements IArrangementFunctionVariant {
if (Array.isArray(this.requiredMonitoringActions)) {
data["requiredMonitoringActions"] = [];
for (let item of this.requiredMonitoringActions)
- data["requiredMonitoringActions"].push(item.toJSON());
+ data["requiredMonitoringActions"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredCloseoutActionNames)) {
data["requiredCloseoutActionNames"] = [];
@@ -3489,17 +3488,17 @@ export class ArrangementFunctionVariant implements IArrangementFunctionVariant {
if (Array.isArray(this.requiredSetupActions)) {
data["requiredSetupActions"] = [];
for (let item of this.requiredSetupActions)
- data["requiredSetupActions"].push(item.toJSON());
+ data["requiredSetupActions"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredMonitoringActionsNew)) {
data["requiredMonitoringActionsNew"] = [];
for (let item of this.requiredMonitoringActionsNew)
- data["requiredMonitoringActionsNew"].push(item.toJSON());
+ data["requiredMonitoringActionsNew"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.requiredCloseoutActions)) {
data["requiredCloseoutActions"] = [];
for (let item of this.requiredCloseoutActions)
- data["requiredCloseoutActions"].push(item.toJSON());
+ data["requiredCloseoutActions"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -3526,7 +3525,7 @@ export class MonitoringRequirementOld implements IMonitoringRequirementOld {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -3534,7 +3533,7 @@ export class MonitoringRequirementOld implements IMonitoringRequirementOld {
init(_data?: any) {
if (_data) {
this.actionName = _data["actionName"];
- this.recurrence = _data["recurrence"] ? RecurrencePolicy.fromJS(_data["recurrence"]) : undefined;
+ this.recurrence = _data["recurrence"] ? RecurrencePolicy.fromJS(_data["recurrence"]) : undefined as any;
}
}
@@ -3548,7 +3547,7 @@ export class MonitoringRequirementOld implements IMonitoringRequirementOld {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["actionName"] = this.actionName;
- data["recurrence"] = this.recurrence ? this.recurrence.toJSON() : undefined;
+ data["recurrence"] = this.recurrence ? this.recurrence.toJSON() : undefined as any;
return data;
}
}
@@ -3566,7 +3565,7 @@ export class FunctionPolicy implements IFunctionPolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3591,7 +3590,7 @@ export class FunctionPolicy implements IFunctionPolicy {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["functionName"] = this.functionName;
- data["eligibility"] = this.eligibility ? this.eligibility.toJSON() : undefined;
+ data["eligibility"] = this.eligibility ? this.eligibility.toJSON() : undefined as any;
return data;
}
}
@@ -3610,7 +3609,7 @@ export class FunctionEligibility implements IFunctionEligibility {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3682,7 +3681,7 @@ export class VolunteerPolicy implements IVolunteerPolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3697,14 +3696,14 @@ export class VolunteerPolicy implements IVolunteerPolicy {
this.volunteerRoles = {} as any;
for (let key in _data["volunteerRoles"]) {
if (_data["volunteerRoles"].hasOwnProperty(key))
- (this.volunteerRoles)![key] = _data["volunteerRoles"][key] ? VolunteerRolePolicy.fromJS(_data["volunteerRoles"][key]) : new VolunteerRolePolicy();
+ (this.volunteerRoles as any)![key] = _data["volunteerRoles"][key] ? VolunteerRolePolicy.fromJS(_data["volunteerRoles"][key]) : new VolunteerRolePolicy();
}
}
if (_data["volunteerFamilyRoles"]) {
this.volunteerFamilyRoles = {} as any;
for (let key in _data["volunteerFamilyRoles"]) {
if (_data["volunteerFamilyRoles"].hasOwnProperty(key))
- (this.volunteerFamilyRoles)![key] = _data["volunteerFamilyRoles"][key] ? VolunteerFamilyRolePolicy.fromJS(_data["volunteerFamilyRoles"][key]) : new VolunteerFamilyRolePolicy();
+ (this.volunteerFamilyRoles as any)![key] = _data["volunteerFamilyRoles"][key] ? VolunteerFamilyRolePolicy.fromJS(_data["volunteerFamilyRoles"][key]) : new VolunteerFamilyRolePolicy();
}
}
}
@@ -3723,14 +3722,14 @@ export class VolunteerPolicy implements IVolunteerPolicy {
data["volunteerRoles"] = {};
for (let key in this.volunteerRoles) {
if (this.volunteerRoles.hasOwnProperty(key))
- (data["volunteerRoles"])[key] = this.volunteerRoles[key] ? this.volunteerRoles[key].toJSON() : undefined;
+ (data["volunteerRoles"] as any)[key] = this.volunteerRoles[key] ? this.volunteerRoles[key].toJSON() : undefined as any;
}
}
if (this.volunteerFamilyRoles) {
data["volunteerFamilyRoles"] = {};
for (let key in this.volunteerFamilyRoles) {
if (this.volunteerFamilyRoles.hasOwnProperty(key))
- (data["volunteerFamilyRoles"])[key] = this.volunteerFamilyRoles[key] ? this.volunteerFamilyRoles[key].toJSON() : undefined;
+ (data["volunteerFamilyRoles"] as any)[key] = this.volunteerFamilyRoles[key] ? this.volunteerFamilyRoles[key].toJSON() : undefined as any;
}
}
return data;
@@ -3750,7 +3749,7 @@ export class VolunteerRolePolicy implements IVolunteerRolePolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3782,7 +3781,7 @@ export class VolunteerRolePolicy implements IVolunteerRolePolicy {
if (Array.isArray(this.policyVersions)) {
data["policyVersions"] = [];
for (let item of this.policyVersions)
- data["policyVersions"].push(item.toJSON());
+ data["policyVersions"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -3802,7 +3801,7 @@ export class VolunteerRolePolicyVersion implements IVolunteerRolePolicyVersion {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3813,7 +3812,7 @@ export class VolunteerRolePolicyVersion implements IVolunteerRolePolicyVersion {
init(_data?: any) {
if (_data) {
this.version = _data["version"];
- this.supersededAtUtc = _data["supersededAtUtc"] ? new Date(_data["supersededAtUtc"].toString()) : undefined;
+ this.supersededAtUtc = _data["supersededAtUtc"] ? new Date(_data["supersededAtUtc"].toString()) : undefined as any;
if (Array.isArray(_data["requirements"])) {
this.requirements = [] as any;
for (let item of _data["requirements"])
@@ -3832,11 +3831,11 @@ export class VolunteerRolePolicyVersion implements IVolunteerRolePolicyVersion {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["version"] = this.version;
- data["supersededAtUtc"] = this.supersededAtUtc ? this.supersededAtUtc.toISOString() : undefined;
+ data["supersededAtUtc"] = this.supersededAtUtc ? this.supersededAtUtc.toISOString() : undefined as any;
if (Array.isArray(this.requirements)) {
data["requirements"] = [];
for (let item of this.requirements)
- data["requirements"].push(item.toJSON());
+ data["requirements"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -3856,7 +3855,7 @@ export class VolunteerApprovalRequirement implements IVolunteerApprovalRequireme
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -3902,7 +3901,7 @@ export class VolunteerFamilyRolePolicy implements IVolunteerFamilyRolePolicy {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3934,7 +3933,7 @@ export class VolunteerFamilyRolePolicy implements IVolunteerFamilyRolePolicy {
if (Array.isArray(this.policyVersions)) {
data["policyVersions"] = [];
for (let item of this.policyVersions)
- data["policyVersions"].push(item.toJSON());
+ data["policyVersions"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -3954,7 +3953,7 @@ export class VolunteerFamilyRolePolicyVersion implements IVolunteerFamilyRolePol
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -3965,7 +3964,7 @@ export class VolunteerFamilyRolePolicyVersion implements IVolunteerFamilyRolePol
init(_data?: any) {
if (_data) {
this.version = _data["version"];
- this.supersededAtUtc = _data["supersededAtUtc"] ? new Date(_data["supersededAtUtc"].toString()) : undefined;
+ this.supersededAtUtc = _data["supersededAtUtc"] ? new Date(_data["supersededAtUtc"].toString()) : undefined as any;
if (Array.isArray(_data["requirements"])) {
this.requirements = [] as any;
for (let item of _data["requirements"])
@@ -3984,11 +3983,11 @@ export class VolunteerFamilyRolePolicyVersion implements IVolunteerFamilyRolePol
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["version"] = this.version;
- data["supersededAtUtc"] = this.supersededAtUtc ? this.supersededAtUtc.toISOString() : undefined;
+ data["supersededAtUtc"] = this.supersededAtUtc ? this.supersededAtUtc.toISOString() : undefined as any;
if (Array.isArray(this.requirements)) {
data["requirements"] = [];
for (let item of this.requirements)
- data["requirements"].push(item.toJSON());
+ data["requirements"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -4009,7 +4008,7 @@ export class VolunteerFamilyApprovalRequirement implements IVolunteerFamilyAppro
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -4059,7 +4058,7 @@ export class CurrentFeatureFlags implements ICurrentFeatureFlags {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -4102,7 +4101,7 @@ export class DocumentUploadInfo implements IDocumentUploadInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -4143,7 +4142,7 @@ export abstract class RecordsAggregate implements IRecordsAggregate {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
this._discriminator = "RecordsAggregate";
@@ -4198,23 +4197,23 @@ export class CommunityRecordsAggregate extends RecordsAggregate implements IComm
this._discriminator = "CommunityRecordsAggregate";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.community = _data["community"] ? CommunityInfo.fromJS(_data["community"]) : new CommunityInfo();
}
}
- static fromJS(data: any): CommunityRecordsAggregate {
+ static override fromJS(data: any): CommunityRecordsAggregate {
data = typeof data === 'object' ? data : {};
let result = new CommunityRecordsAggregate();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["community"] = this.community ? this.community.toJSON() : undefined;
+ data["community"] = this.community ? this.community.toJSON() : undefined as any;
super.toJSON(data);
return data;
}
@@ -4232,7 +4231,7 @@ export class CommunityInfo implements ICommunityInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -4261,7 +4260,7 @@ export class CommunityInfo implements ICommunityInfo {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["community"] = this.community ? this.community.toJSON() : undefined;
+ data["community"] = this.community ? this.community.toJSON() : undefined as any;
if (Array.isArray(this.userPermissions)) {
data["userPermissions"] = [];
for (let item of this.userPermissions)
@@ -4288,7 +4287,7 @@ export class Community implements ICommunity {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -4341,12 +4340,12 @@ export class Community implements ICommunity {
if (Array.isArray(this.communityRoleAssignments)) {
data["communityRoleAssignments"] = [];
for (let item of this.communityRoleAssignments)
- data["communityRoleAssignments"].push(item.toJSON());
+ data["communityRoleAssignments"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.uploadedDocuments)) {
data["uploadedDocuments"] = [];
for (let item of this.uploadedDocuments)
- data["uploadedDocuments"].push(item.toJSON());
+ data["uploadedDocuments"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -4369,7 +4368,7 @@ export class CommunityRoleAssignment implements ICommunityRoleAssignment {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -4411,7 +4410,7 @@ export class UploadedDocumentInfo implements IUploadedDocumentInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -4419,7 +4418,7 @@ export class UploadedDocumentInfo implements IUploadedDocumentInfo {
init(_data?: any) {
if (_data) {
this.userId = _data["userId"];
- this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined;
+ this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined as any;
this.uploadedDocumentId = _data["uploadedDocumentId"];
this.uploadedFileName = _data["uploadedFileName"];
}
@@ -4435,7 +4434,7 @@ export class UploadedDocumentInfo implements IUploadedDocumentInfo {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["userId"] = this.userId;
- data["timestampUtc"] = this.timestampUtc ? this.timestampUtc.toISOString() : undefined;
+ data["timestampUtc"] = this.timestampUtc ? this.timestampUtc.toISOString() : undefined as any;
data["uploadedDocumentId"] = this.uploadedDocumentId;
data["uploadedFileName"] = this.uploadedFileName;
return data;
@@ -4460,23 +4459,23 @@ export class FamilyRecordsAggregate extends RecordsAggregate implements IFamilyR
this._discriminator = "FamilyRecordsAggregate";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.family = _data["family"] ? CombinedFamilyInfo.fromJS(_data["family"]) : new CombinedFamilyInfo();
}
}
- static fromJS(data: any): FamilyRecordsAggregate {
+ static override fromJS(data: any): FamilyRecordsAggregate {
data = typeof data === 'object' ? data : {};
let result = new FamilyRecordsAggregate();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["family"] = this.family ? this.family.toJSON() : undefined;
+ data["family"] = this.family ? this.family.toJSON() : undefined as any;
super.toJSON(data);
return data;
}
@@ -4500,7 +4499,7 @@ export class CombinedFamilyInfo implements ICombinedFamilyInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -4521,8 +4520,8 @@ export class CombinedFamilyInfo implements ICombinedFamilyInfo {
for (let item of _data["users"])
this.users!.push(UserInfo.fromJS(item));
}
- this.partneringFamilyInfo = _data["partneringFamilyInfo"] ? PartneringFamilyInfo.fromJS(_data["partneringFamilyInfo"]) : undefined;
- this.volunteerFamilyInfo = _data["volunteerFamilyInfo"] ? VolunteerFamilyInfo.fromJS(_data["volunteerFamilyInfo"]) : undefined;
+ this.partneringFamilyInfo = _data["partneringFamilyInfo"] ? PartneringFamilyInfo.fromJS(_data["partneringFamilyInfo"]) : undefined as any;
+ this.volunteerFamilyInfo = _data["volunteerFamilyInfo"] ? VolunteerFamilyInfo.fromJS(_data["volunteerFamilyInfo"]) : undefined as any;
if (Array.isArray(_data["notes"])) {
this.notes = [] as any;
for (let item of _data["notes"])
@@ -4555,23 +4554,23 @@ export class CombinedFamilyInfo implements ICombinedFamilyInfo {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["family"] = this.family ? this.family.toJSON() : undefined;
+ data["family"] = this.family ? this.family.toJSON() : undefined as any;
if (Array.isArray(this.users)) {
data["users"] = [];
for (let item of this.users)
- data["users"].push(item.toJSON());
+ data["users"].push(item ? item.toJSON() : undefined as any);
}
- data["partneringFamilyInfo"] = this.partneringFamilyInfo ? this.partneringFamilyInfo.toJSON() : undefined;
- data["volunteerFamilyInfo"] = this.volunteerFamilyInfo ? this.volunteerFamilyInfo.toJSON() : undefined;
+ data["partneringFamilyInfo"] = this.partneringFamilyInfo ? this.partneringFamilyInfo.toJSON() : undefined as any;
+ data["volunteerFamilyInfo"] = this.volunteerFamilyInfo ? this.volunteerFamilyInfo.toJSON() : undefined as any;
if (Array.isArray(this.notes)) {
data["notes"] = [];
for (let item of this.notes)
- data["notes"].push(item.toJSON());
+ data["notes"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.uploadedDocuments)) {
data["uploadedDocuments"] = [];
for (let item of this.uploadedDocuments)
- data["uploadedDocuments"].push(item.toJSON());
+ data["uploadedDocuments"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.missingCustomFields)) {
data["missingCustomFields"] = [];
@@ -4615,7 +4614,7 @@ export class Family implements IFamily {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -4688,22 +4687,22 @@ export class Family implements IFamily {
if (Array.isArray(this.adults)) {
data["adults"] = [];
for (let item of this.adults)
- data["adults"].push(item.toJSON());
+ data["adults"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.children)) {
data["children"] = [];
for (let item of this.children)
- data["children"].push(item.toJSON());
+ data["children"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.custodialRelationships)) {
data["custodialRelationships"] = [];
for (let item of this.custodialRelationships)
- data["custodialRelationships"].push(item.toJSON());
+ data["custodialRelationships"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.uploadedDocuments)) {
data["uploadedDocuments"] = [];
for (let item of this.uploadedDocuments)
- data["uploadedDocuments"].push(item.toJSON());
+ data["uploadedDocuments"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.deletedDocuments)) {
data["deletedDocuments"] = [];
@@ -4713,12 +4712,12 @@ export class Family implements IFamily {
if (Array.isArray(this.completedCustomFields)) {
data["completedCustomFields"] = [];
for (let item of this.completedCustomFields)
- data["completedCustomFields"].push(item.toJSON());
+ data["completedCustomFields"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.history)) {
data["history"] = [];
for (let item of this.history)
- data["history"].push(item.toJSON());
+ data["history"].push(item ? item.toJSON() : undefined as any);
}
data["isTestFamily"] = this.isTestFamily;
return data;
@@ -4747,15 +4746,15 @@ export class ValueTupleOfPersonAndFamilyAdultRelationshipInfo implements IValueT
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
init(_data?: any) {
if (_data) {
- this.item1 = _data["item1"] ? Person.fromJS(_data["item1"]) : undefined;
- this.item2 = _data["item2"] ? FamilyAdultRelationshipInfo.fromJS(_data["item2"]) : undefined;
+ this.item1 = _data["item1"] ? Person.fromJS(_data["item1"]) : undefined as any;
+ this.item2 = _data["item2"] ? FamilyAdultRelationshipInfo.fromJS(_data["item2"]) : undefined as any;
}
}
@@ -4768,8 +4767,8 @@ export class ValueTupleOfPersonAndFamilyAdultRelationshipInfo implements IValueT
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["item1"] = this.item1 ? this.item1.toJSON() : undefined;
- data["item2"] = this.item2 ? this.item2.toJSON() : undefined;
+ data["item1"] = this.item1 ? this.item1.toJSON() : undefined as any;
+ data["item2"] = this.item2 ? this.item2.toJSON() : undefined as any;
return data;
}
}
@@ -4800,7 +4799,7 @@ export class Person implements IPerson {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -4817,7 +4816,7 @@ export class Person implements IPerson {
this.firstName = _data["firstName"];
this.lastName = _data["lastName"];
this.gender = _data["gender"];
- this.age = _data["age"] ? Age.fromJS(_data["age"]) : undefined;
+ this.age = _data["age"] ? Age.fromJS(_data["age"]) : undefined as any;
this.ethnicity = _data["ethnicity"];
if (Array.isArray(_data["addresses"])) {
this.addresses = [] as any;
@@ -4856,24 +4855,24 @@ export class Person implements IPerson {
data["firstName"] = this.firstName;
data["lastName"] = this.lastName;
data["gender"] = this.gender;
- data["age"] = this.age ? this.age.toJSON() : undefined;
+ data["age"] = this.age ? this.age.toJSON() : undefined as any;
data["ethnicity"] = this.ethnicity;
if (Array.isArray(this.addresses)) {
data["addresses"] = [];
for (let item of this.addresses)
- data["addresses"].push(item.toJSON());
+ data["addresses"].push(item ? item.toJSON() : undefined as any);
}
data["currentAddressId"] = this.currentAddressId;
if (Array.isArray(this.phoneNumbers)) {
data["phoneNumbers"] = [];
for (let item of this.phoneNumbers)
- data["phoneNumbers"].push(item.toJSON());
+ data["phoneNumbers"].push(item ? item.toJSON() : undefined as any);
}
data["preferredPhoneNumberId"] = this.preferredPhoneNumberId;
if (Array.isArray(this.emailAddresses)) {
data["emailAddresses"] = [];
for (let item of this.emailAddresses)
- data["emailAddresses"].push(item.toJSON());
+ data["emailAddresses"].push(item ? item.toJSON() : undefined as any);
}
data["preferredEmailAddressId"] = this.preferredEmailAddressId;
data["concerns"] = this.concerns;
@@ -4914,7 +4913,7 @@ export abstract class Age implements IAge {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
this._discriminator = "Age";
@@ -4957,25 +4956,25 @@ export class AgeInYears extends Age implements IAgeInYears {
this._discriminator = "AgeInYears";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.years = _data["years"];
- this.asOf = _data["asOf"] ? new Date(_data["asOf"].toString()) : undefined;
+ this.asOf = _data["asOf"] ? new Date(_data["asOf"].toString()) : undefined as any;
}
}
- static fromJS(data: any): AgeInYears {
+ static override fromJS(data: any): AgeInYears {
data = typeof data === 'object' ? data : {};
let result = new AgeInYears();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["years"] = this.years;
- data["asOf"] = this.asOf ? this.asOf.toISOString() : undefined;
+ data["asOf"] = this.asOf ? this.asOf.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -4994,23 +4993,23 @@ export class ExactAge extends Age implements IExactAge {
this._discriminator = "ExactAge";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
- this.dateOfBirth = _data["dateOfBirth"] ? new Date(_data["dateOfBirth"].toString()) : undefined;
+ this.dateOfBirth = _data["dateOfBirth"] ? new Date(_data["dateOfBirth"].toString()) : undefined as any;
}
}
- static fromJS(data: any): ExactAge {
+ static override fromJS(data: any): ExactAge {
data = typeof data === 'object' ? data : {};
let result = new ExactAge();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["dateOfBirth"] = this.dateOfBirth ? this.dateOfBirth.toISOString() : undefined;
+ data["dateOfBirth"] = this.dateOfBirth ? this.dateOfBirth.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -5033,7 +5032,7 @@ export class Address implements IAddress {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -5089,7 +5088,7 @@ export class PhoneNumber implements IPhoneNumber {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -5140,7 +5139,7 @@ export class EmailAddress implements IEmailAddress {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -5188,7 +5187,7 @@ export class FamilyAdultRelationshipInfo implements IFamilyAdultRelationshipInfo
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -5229,7 +5228,7 @@ export class CustodialRelationship implements ICustodialRelationship {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -5282,7 +5281,7 @@ export class CompletedCustomFieldInfo implements ICompletedCustomFieldInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -5290,7 +5289,7 @@ export class CompletedCustomFieldInfo implements ICompletedCustomFieldInfo {
init(_data?: any) {
if (_data) {
this.userId = _data["userId"];
- this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined;
+ this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined as any;
this.completedCustomFieldId = _data["completedCustomFieldId"];
this.customFieldName = _data["customFieldName"];
this.customFieldType = _data["customFieldType"];
@@ -5308,7 +5307,7 @@ export class CompletedCustomFieldInfo implements ICompletedCustomFieldInfo {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["userId"] = this.userId;
- data["timestampUtc"] = this.timestampUtc ? this.timestampUtc.toISOString() : undefined;
+ data["timestampUtc"] = this.timestampUtc ? this.timestampUtc.toISOString() : undefined as any;
data["completedCustomFieldId"] = this.completedCustomFieldId;
data["customFieldName"] = this.customFieldName;
data["customFieldType"] = this.customFieldType;
@@ -5339,7 +5338,7 @@ export abstract class Activity implements IActivity {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
this._discriminator = "Activity";
@@ -5348,8 +5347,8 @@ export abstract class Activity implements IActivity {
init(_data?: any) {
if (_data) {
this.userId = _data["userId"];
- this.auditTimestampUtc = _data["auditTimestampUtc"] ? new Date(_data["auditTimestampUtc"].toString()) : undefined;
- this.activityTimestampUtc = _data["activityTimestampUtc"] ? new Date(_data["activityTimestampUtc"].toString()) : undefined;
+ this.auditTimestampUtc = _data["auditTimestampUtc"] ? new Date(_data["auditTimestampUtc"].toString()) : undefined as any;
+ this.activityTimestampUtc = _data["activityTimestampUtc"] ? new Date(_data["activityTimestampUtc"].toString()) : undefined as any;
this.uploadedDocumentId = _data["uploadedDocumentId"];
this.noteId = _data["noteId"];
}
@@ -5404,8 +5403,8 @@ export abstract class Activity implements IActivity {
data = typeof data === 'object' ? data : {};
data["discriminator"] = this._discriminator;
data["userId"] = this.userId;
- data["auditTimestampUtc"] = this.auditTimestampUtc ? this.auditTimestampUtc.toISOString() : undefined;
- data["activityTimestampUtc"] = this.activityTimestampUtc ? this.activityTimestampUtc.toISOString() : undefined;
+ data["auditTimestampUtc"] = this.auditTimestampUtc ? this.auditTimestampUtc.toISOString() : undefined as any;
+ data["activityTimestampUtc"] = this.activityTimestampUtc ? this.activityTimestampUtc.toISOString() : undefined as any;
data["uploadedDocumentId"] = this.uploadedDocumentId;
data["noteId"] = this.noteId;
return data;
@@ -5430,27 +5429,27 @@ export class ArrangementRequirementCompleted extends Activity implements IArrang
this._discriminator = "ArrangementRequirementCompleted";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.arrangementId = _data["arrangementId"];
this.requirementName = _data["requirementName"];
- this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined;
+ this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined as any;
}
}
- static fromJS(data: any): ArrangementRequirementCompleted {
+ static override fromJS(data: any): ArrangementRequirementCompleted {
data = typeof data === 'object' ? data : {};
let result = new ArrangementRequirementCompleted();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["arrangementId"] = this.arrangementId;
data["requirementName"] = this.requirementName;
- data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined;
+ data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -5474,28 +5473,28 @@ export class ChildLocationChanged extends Activity implements IChildLocationChan
this._discriminator = "ChildLocationChanged";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.arrangementId = _data["arrangementId"];
- this.changedAtUtc = _data["changedAtUtc"] ? new Date(_data["changedAtUtc"].toString()) : undefined;
+ this.changedAtUtc = _data["changedAtUtc"] ? new Date(_data["changedAtUtc"].toString()) : undefined as any;
this.childLocationFamilyId = _data["childLocationFamilyId"];
this.childLocationReceivingAdultId = _data["childLocationReceivingAdultId"];
this.plan = _data["plan"];
}
}
- static fromJS(data: any): ChildLocationChanged {
+ static override fromJS(data: any): ChildLocationChanged {
data = typeof data === 'object' ? data : {};
let result = new ChildLocationChanged();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["arrangementId"] = this.arrangementId;
- data["changedAtUtc"] = this.changedAtUtc ? this.changedAtUtc.toISOString() : undefined;
+ data["changedAtUtc"] = this.changedAtUtc ? this.changedAtUtc.toISOString() : undefined as any;
data["childLocationFamilyId"] = this.childLocationFamilyId;
data["childLocationReceivingAdultId"] = this.childLocationReceivingAdultId;
data["plan"] = this.plan;
@@ -5526,23 +5525,23 @@ export class ReferralOpened extends Activity implements IReferralOpened {
this._discriminator = "ReferralOpened";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
- this.openedAtUtc = _data["openedAtUtc"] ? new Date(_data["openedAtUtc"].toString()) : undefined;
+ this.openedAtUtc = _data["openedAtUtc"] ? new Date(_data["openedAtUtc"].toString()) : undefined as any;
}
}
- static fromJS(data: any): ReferralOpened {
+ static override fromJS(data: any): ReferralOpened {
data = typeof data === 'object' ? data : {};
let result = new ReferralOpened();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["openedAtUtc"] = this.openedAtUtc ? this.openedAtUtc.toISOString() : undefined;
+ data["openedAtUtc"] = this.openedAtUtc ? this.openedAtUtc.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -5561,25 +5560,25 @@ export class ReferralRequirementCompleted extends Activity implements IReferralR
this._discriminator = "ReferralRequirementCompleted";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.requirementName = _data["requirementName"];
- this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined;
+ this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined as any;
}
}
- static fromJS(data: any): ReferralRequirementCompleted {
+ static override fromJS(data: any): ReferralRequirementCompleted {
data = typeof data === 'object' ? data : {};
let result = new ReferralRequirementCompleted();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["requirementName"] = this.requirementName;
- data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined;
+ data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -5598,23 +5597,23 @@ export class V1ReferralAccepted extends Activity implements IV1ReferralAccepted
this._discriminator = "V1ReferralAccepted";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
- this.acceptedAtUtc = _data["acceptedAtUtc"] ? new Date(_data["acceptedAtUtc"].toString()) : undefined;
+ this.acceptedAtUtc = _data["acceptedAtUtc"] ? new Date(_data["acceptedAtUtc"].toString()) : undefined as any;
}
}
- static fromJS(data: any): V1ReferralAccepted {
+ static override fromJS(data: any): V1ReferralAccepted {
data = typeof data === 'object' ? data : {};
let result = new V1ReferralAccepted();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["acceptedAtUtc"] = this.acceptedAtUtc ? this.acceptedAtUtc.toISOString() : undefined;
+ data["acceptedAtUtc"] = this.acceptedAtUtc ? this.acceptedAtUtc.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -5633,24 +5632,24 @@ export class V1ReferralClosed extends Activity implements IV1ReferralClosed {
this._discriminator = "V1ReferralClosed";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
- this.closedAtUtc = _data["closedAtUtc"] ? new Date(_data["closedAtUtc"].toString()) : undefined;
+ this.closedAtUtc = _data["closedAtUtc"] ? new Date(_data["closedAtUtc"].toString()) : undefined as any;
this.closeReason = _data["closeReason"];
}
}
- static fromJS(data: any): V1ReferralClosed {
+ static override fromJS(data: any): V1ReferralClosed {
data = typeof data === 'object' ? data : {};
let result = new V1ReferralClosed();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["closedAtUtc"] = this.closedAtUtc ? this.closedAtUtc.toISOString() : undefined;
+ data["closedAtUtc"] = this.closedAtUtc ? this.closedAtUtc.toISOString() : undefined as any;
data["closeReason"] = this.closeReason;
super.toJSON(data);
return data;
@@ -5670,23 +5669,23 @@ export class V1ReferralOpened extends Activity implements IV1ReferralOpened {
this._discriminator = "V1ReferralOpened";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
- this.openedAtUtc = _data["openedAtUtc"] ? new Date(_data["openedAtUtc"].toString()) : undefined;
+ this.openedAtUtc = _data["openedAtUtc"] ? new Date(_data["openedAtUtc"].toString()) : undefined as any;
}
}
- static fromJS(data: any): V1ReferralOpened {
+ static override fromJS(data: any): V1ReferralOpened {
data = typeof data === 'object' ? data : {};
let result = new V1ReferralOpened();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["openedAtUtc"] = this.openedAtUtc ? this.openedAtUtc.toISOString() : undefined;
+ data["openedAtUtc"] = this.openedAtUtc ? this.openedAtUtc.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -5705,25 +5704,25 @@ export class V1ReferralRequirementCompleted extends Activity implements IV1Refer
this._discriminator = "V1ReferralRequirementCompleted";
}
- init(_data?: any) {
+ override init(_data?: any) {
super.init(_data);
if (_data) {
this.requirementName = _data["requirementName"];
- this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined;
+ this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined as any;
}
}
- static fromJS(data: any): V1ReferralRequirementCompleted {
+ static override fromJS(data: any): V1ReferralRequirementCompleted {
data = typeof data === 'object' ? data : {};
let result = new V1ReferralRequirementCompleted();
result.init(data);
return result;
}
- toJSON(data?: any) {
+ override toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["requirementName"] = this.requirementName;
- data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined;
+ data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined as any;
super.toJSON(data);
return data;
}
@@ -5743,7 +5742,7 @@ export class UserInfo implements IUserInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -5798,7 +5797,7 @@ export class PartneringFamilyInfo implements IPartneringFamilyInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -5809,7 +5808,7 @@ export class PartneringFamilyInfo implements IPartneringFamilyInfo {
init(_data?: any) {
if (_data) {
- this.openV1Case = _data["openV1Case"] ? V1Case.fromJS(_data["openV1Case"]) : undefined;
+ this.openV1Case = _data["openV1Case"] ? V1Case.fromJS(_data["openV1Case"]) : undefined as any;
if (Array.isArray(_data["closedV1Cases"])) {
this.closedV1Cases = [] as any;
for (let item of _data["closedV1Cases"])
@@ -5832,16 +5831,16 @@ export class PartneringFamilyInfo implements IPartneringFamilyInfo {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
- data["openV1Case"] = this.openV1Case ? this.openV1Case.toJSON() : undefined;
+ data["openV1Case"] = this.openV1Case ? this.openV1Case.toJSON() : undefined as any;
if (Array.isArray(this.closedV1Cases)) {
data["closedV1Cases"] = [];
for (let item of this.closedV1Cases)
- data["closedV1Cases"].push(item.toJSON());
+ data["closedV1Cases"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.history)) {
data["history"] = [];
for (let item of this.history)
- data["history"].push(item.toJSON());
+ data["history"].push(item ? item.toJSON() : undefined as any);
}
return data;
}
@@ -5871,7 +5870,7 @@ export class V1Case implements IV1Case {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
if (!data) {
@@ -5888,8 +5887,8 @@ export class V1Case implements IV1Case {
init(_data?: any) {
if (_data) {
this.id = _data["id"];
- this.openedAtUtc = _data["openedAtUtc"] ? new Date(_data["openedAtUtc"].toString()) : undefined;
- this.closedAtUtc = _data["closedAtUtc"] ? new Date(_data["closedAtUtc"].toString()) : undefined;
+ this.openedAtUtc = _data["openedAtUtc"] ? new Date(_data["openedAtUtc"].toString()) : undefined as any;
+ this.closedAtUtc = _data["closedAtUtc"] ? new Date(_data["closedAtUtc"].toString()) : undefined as any;
this.closeReason = _data["closeReason"];
if (Array.isArray(_data["completedRequirements"])) {
this.completedRequirements = [] as any;
@@ -5940,28 +5939,28 @@ export class V1Case implements IV1Case {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
- data["openedAtUtc"] = this.openedAtUtc ? this.openedAtUtc.toISOString() : undefined;
- data["closedAtUtc"] = this.closedAtUtc ? this.closedAtUtc.toISOString() : undefined;
+ data["openedAtUtc"] = this.openedAtUtc ? this.openedAtUtc.toISOString() : undefined as any;
+ data["closedAtUtc"] = this.closedAtUtc ? this.closedAtUtc.toISOString() : undefined as any;
data["closeReason"] = this.closeReason;
if (Array.isArray(this.completedRequirements)) {
data["completedRequirements"] = [];
for (let item of this.completedRequirements)
- data["completedRequirements"].push(item.toJSON());
+ data["completedRequirements"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.exemptedRequirements)) {
data["exemptedRequirements"] = [];
for (let item of this.exemptedRequirements)
- data["exemptedRequirements"].push(item.toJSON());
+ data["exemptedRequirements"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.missingRequirements)) {
data["missingRequirements"] = [];
for (let item of this.missingRequirements)
- data["missingRequirements"].push(item.toJSON());
+ data["missingRequirements"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.completedCustomFields)) {
data["completedCustomFields"] = [];
for (let item of this.completedCustomFields)
- data["completedCustomFields"].push(item.toJSON());
+ data["completedCustomFields"].push(item ? item.toJSON() : undefined as any);
}
if (Array.isArray(this.missingCustomFields)) {
data["missingCustomFields"] = [];
@@ -5971,7 +5970,7 @@ export class V1Case implements IV1Case {
if (Array.isArray(this.arrangements)) {
data["arrangements"] = [];
for (let item of this.arrangements)
- data["arrangements"].push(item.toJSON());
+ data["arrangements"].push(item ? item.toJSON() : undefined as any);
}
data["comments"] = this.comments;
if (Array.isArray(this.linkedV1ReferralIds)) {
@@ -6020,7 +6019,7 @@ export class CompletedRequirementInfo implements ICompletedRequirementInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -6028,11 +6027,11 @@ export class CompletedRequirementInfo implements ICompletedRequirementInfo {
init(_data?: any) {
if (_data) {
this.userId = _data["userId"];
- this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined;
+ this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined as any;
this.completedRequirementId = _data["completedRequirementId"];
this.requirementName = _data["requirementName"];
- this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined;
- this.expiresAtUtc = _data["expiresAtUtc"] ? new Date(_data["expiresAtUtc"].toString()) : undefined;
+ this.completedAtUtc = _data["completedAtUtc"] ? new Date(_data["completedAtUtc"].toString()) : undefined as any;
+ this.expiresAtUtc = _data["expiresAtUtc"] ? new Date(_data["expiresAtUtc"].toString()) : undefined as any;
this.uploadedDocumentId = _data["uploadedDocumentId"];
this.noteId = _data["noteId"];
}
@@ -6048,11 +6047,11 @@ export class CompletedRequirementInfo implements ICompletedRequirementInfo {
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["userId"] = this.userId;
- data["timestampUtc"] = this.timestampUtc ? this.timestampUtc.toISOString() : undefined;
+ data["timestampUtc"] = this.timestampUtc ? this.timestampUtc.toISOString() : undefined as any;
data["completedRequirementId"] = this.completedRequirementId;
data["requirementName"] = this.requirementName;
- data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined;
- data["expiresAtUtc"] = this.expiresAtUtc ? this.expiresAtUtc.toISOString() : undefined;
+ data["completedAtUtc"] = this.completedAtUtc ? this.completedAtUtc.toISOString() : undefined as any;
+ data["expiresAtUtc"] = this.expiresAtUtc ? this.expiresAtUtc.toISOString() : undefined as any;
data["uploadedDocumentId"] = this.uploadedDocumentId;
data["noteId"] = this.noteId;
return data;
@@ -6082,7 +6081,7 @@ export class ExemptedRequirementInfo implements IExemptedRequirementInfo {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
- (this)[property] = (data)[property];
+ (this as any)[property] = (data as any)[property];
}
}
}
@@ -6090,11 +6089,11 @@ export class ExemptedRequirementInfo implements IExemptedRequirementInfo {
init(_data?: any) {
if (_data) {
this.userId = _data["userId"];
- this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined;
+ this.timestampUtc = _data["timestampUtc"] ? new Date(_data["timestampUtc"].toString()) : undefined as any;
this.requirementName = _data["requirementName"];
- this.dueDate = _data["dueDate"] ? new Date(_data["dueDate"].toString()) :