diff --git a/.gitignore b/.gitignore
index 65221e93f..ccbc71287 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
dist
lib
+.nx
+
# Logs
logs
*.log
@@ -49,6 +51,8 @@ node_modules
.node_repl_history
.dist
+# ignore temp created for pushing prod changes to devleop
+lerna-temp.json
# IDE
.idea
*.DS_Store
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 000000000..d0a778429
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1 @@
+npx lint-staged
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
index 4b410d508..6c49dc1c8 100755
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -13,23 +13,24 @@ pipeline {
string(name: 'CONNECTION_ID', defaultValue: 'test', description: 'connection id', trim: true)
string(name: 'WORKSPACE_ID', defaultValue: 'fullstack-pro', description: 'workspace id', trim: true)
string(name: 'UNIQUE_NAME', defaultValue: 'default', description: 'chart name', trim: true)
- string(name: 'VERSION', defaultValue: 'v1', description: 'version of the deployment', trim: true)
+ string(name: 'VERSION', defaultValue: 'v3', description: 'version of the deployment', trim: true)
string(name: 'HEMERA_LOG_LEVEL', defaultValue: 'info', description: 'log level for hemera')
string(name: 'LOG_LEVEL', defaultValue: 'info', description: 'log level')
string(name: 'DEPLOYMENT_PATH', defaultValue: '/servers', description: 'folder path to load helm charts')
- string(name: 'PUBLISH_BRANCH', defaultValue: 'devpublish', description: 'publish branch')
+ string(name: 'PUBLISH_BRANCH', defaultValue: 'devpublish3', description: 'the publish branch for packages release')
string(name: 'EXCLUDE_SETTING_NAMESPACE_FILTER', defaultValue: 'brigade', description: 'exclude setting namespace that matches search string')
string(name: 'GIT_CREDENTIAL_ID', defaultValue: 'fullstack-pro-github-deploy-key', description: 'jenkins credential id of git deploy secret')
+ string(name: 'BUILD_MODULE_TO_INCLUDE', defaultValue: '@sample-stack*', description: 'build env')
string(name: 'REPOSITORY_SSH_URL', defaultValue: 'git@github.com:CDEBase/fullstack-pro.git', description: 'ssh url of the git repository')
- string(name: 'REPOSITORY_BRANCH', defaultValue: 'develop', description: 'the branch of repository')
- string(name: 'DEVELOP_BRANCH', defaultValue: 'develop', description: 'Develop branch as default for the development.')
+ string(name: 'REPOSITORY_BRANCH', defaultValue: 'develop3', description: 'the branch with changes')
+ string(name: 'DEVELOP_BRANCH', defaultValue: 'develop3', description: 'the branch for the development')
string(name: 'MASTER_BRANCH', defaultValue: 'master', description: 'Master branch as default branch for production.')
// by default first value of the choice will be choosen
choice choices: ['auto', 'force'], description: 'Choose merge strategy', name: 'NPM_PUBLISH_STRATEGY'
choice choices: ['yarn', 'npm'], description: 'Choose build strategy', name: 'BUILD_STRATEGY'
choice choices: ['0.7.9','0.7.7', '0.6.0'], description: 'Choose Idestack chart version', name: 'IDESTACK_CHART_VERSION'
- choice choices: ['nodejs16', 'nodejs14'], description: 'Choose NodeJS version', name: 'NODEJS_TOOL_VERSION'
+ choice choices: ['nodejs20', 'nodejs18', 'nodejs22'], description: 'Choose NodeJS version', name: 'NODEJS_TOOL_VERSION'
choice choices: ['buildOnly', 'buildAndTest', 'buildAndPublish', 'mobileBuild', 'mobilePreview', 'mobilePreviewLocal', 'mobilePreviewSubmit', 'mobileProd', 'mobileProdSubmit', 'devDeployOnly', 'stageDeploy', 'stageDeployOnly', 'prodDeploy', 'prodDeployOnly', 'allenv'], description: 'Where to deploy micro services?', name: 'ENV_CHOICE'
choice choices: ['all', 'ios', 'android' ], description: 'Mobile type if it is mobile build?', name: 'MOBILE_CHOICE'
booleanParam (defaultValue: false, description: 'Skip production release approval', name: 'SKIP_RELEASE_APPROVAL')
@@ -41,7 +42,7 @@ pipeline {
environment {
BUILD_COMMAND = getBuildCommand()
NAMESPACE = "${params.BASE_NAMESPACE}-${params.VERSION}"
- PYTHON='/usr/bin/python'
+ PYTHON = '/usr/bin/python'
GCR_KEY = credentials('jenkins-gcr-login-key')
EXPO_TOKEN = credentials('expo_cdmbase_token')
GIT_PR_BRANCH_NAME = getGitPrBranchName()
@@ -54,69 +55,65 @@ pipeline {
}
stages {
-
stage('define environment') {
steps {
- // skip the build if ends with `[skip ci]` which is equivalent to regex `.*\[skip ci\]$`
+ // skip the build if ends with `[skip ci]` which is equivalent to regex `.*\[skip ci\\]\\s`
scmSkip(deleteBuild: true, skipPattern:'.*\\[skip ci\\]\\s')
- checkout([$class: 'GitSCM', branches: [[name: '*/'+ params.REPOSITORY_BRANCH]],
- doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'WipeWorkspace']],
- submoduleCfg: [], userRemoteConfigs: [[credentialsId: params.GIT_CREDENTIAL_ID, url: params.REPOSITORY_SSH_URL]]])
+ checkout([$class: 'GitSCM', branches: [[name: '*/' + params.REPOSITORY_BRANCH]],
+ doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'WipeWorkspace']],
+ submoduleCfg: [], userRemoteConfigs: [[credentialsId: params.GIT_CREDENTIAL_ID, url: params.REPOSITORY_SSH_URL]]])
sh "git checkout ${env.GIT_PR_BRANCH_NAME}"
}
}
- stage('Unlock secrets'){ //unlock keys for all runs
- environment{ deployment_env = 'dev' }
- steps{
+ stage('Unlock secrets') { //unlock keys for all runs
+ environment { deployment_env = 'dev' }
+ steps {
sh '''
- gpg --import /tmp/gpg-public-key/gpg-public-key.pub
- gpg --import /tmp/gpg-private-key/gpg-private-key.key
- git-crypt unlock
+ gpg --import /tmp/gpg-public-key/gpg-public-key.pub
+ gpg --import /tmp/gpg-private-key/gpg-private-key.key
+ git-crypt unlock
'''
load "./jenkins_variables.groovy"
- // if we need to load stag configuration for different location.
- // sh "curl -H 'Authorization: token ${env.GITHUB_ACCESS_TOKEN}' -H 'Accept: application/vnd.github.v3.raw' -O -L https://raw.githubusercontent.com/cdmbase/kube-orchestration/master/idestack/values-stage.yaml"
}
}
// Install packages. If
// a. any branch
// b. ENV_CHOICE set not selected `dev`, `stage` or `prod`
- stage ('Install git repository'){
- steps{
- sh """
- echo "what is docker git version $GIT_BRANCH_NAME -- ${params.ENV_CHOICE}"
- ${params.BUILD_STRATEGY} install
- ${params.BUILD_STRATEGY} run lerna
- """
- }
+ stage('Install git repository') {
+ steps {
+ sh """
+ echo "what is docker git version $GIT_BRANCH_NAME -- ${params.ENV_CHOICE}"
+ ${params.BUILD_STRATEGY} install
+ """
+ }
}
- stage ('Mobile Build'){
+ stage('Mobile Build') {
when {
expression { params.ENV_CHOICE == 'mobileBuild' || params.ENV_CHOICE == 'mobilePreview' || params.ENV_CHOICE == 'mobilePreviewLocal' || params.ENV_CHOICE == 'mobilePreviewSubmit' || params.ENV_CHOICE == 'mobileProd' || params.ENV_CHOICE == 'mobileProdSubmit' }
}
- steps{
- sshagent (credentials: [params.GIT_CREDENTIAL_ID]) {
+ steps {
+ sshagent(credentials: [params.GIT_CREDENTIAL_ID]) {
sh """
- rm .npmrc
- lerna exec --scope=*mobile-device ${params.BUILD_STRATEGY} ${env.BUILD_COMMAND}
- git checkout -- .npmrc
- yarn gitcommit
- git pull origin ${params.REPOSITORY_BRANCH}
- git push origin ${params.REPOSITORY_BRANCH}
+ rm .npmrc
+ npx lerna exec --scope=*mobile-device ${params.BUILD_STRATEGY} ${env.BUILD_COMMAND}
+ git checkout -- .npmrc
+ yarn gitcommit
+ git pull origin ${params.REPOSITORY_BRANCH}
+ git push origin ${params.REPOSITORY_BRANCH}
"""
}
}
}
// Run build for all cases except when ENV_CHOICE is 'buildAndPublish' and `dev`, `stage` or `prod`
- stage ('Build Packages'){
+ stage('Build Packages') {
when {
expression { params.ENV_CHOICE == 'buildOnly' || params.ENV_CHOICE == 'buildAndTest' || params.ENV_CHOICE == 'buildAndPublish' }
}
- steps{
+ steps {
sh """
${params.BUILD_STRATEGY} run build
"""
@@ -124,11 +121,11 @@ pipeline {
}
// Test build for all cases except when ENV_CHOICE is 'buildAndPublish' and `dev`, `stage` or `prod`
- stage ('Test Packages'){
+ stage('Test Packages') {
when {
expression { params.ENV_CHOICE == 'buildAndTest' }
}
- steps{
+ steps {
sh """
${params.BUILD_STRATEGY} run test
"""
@@ -137,17 +134,16 @@ pipeline {
// if PR is from branch other than `develop` then merge to `develop` if we chose ENV_CHOICE as 'buildAndPublish'.
// Skip this stage. Future implementation.
- stage ('Merge PR, Install, Build'){
+ stage('Merge PR, Install, Build') {
when {
expression { params.ENV_CHOICE == '1' }
}
- steps{
+ steps {
sh """
git checkout ${params.DEVELOP_BRANCH}
git merge ${env.GIT_PR_BRANCH_NAME} -m 'auto merging ${params.GIT_PR_BRANCH_NAME} \r\n[skip ci]'
git push origin ${params.DEVELOP_BRANCH}
${params.BUILD_STRATEGY} install
- ${params.BUILD_STRATEGY} run lerna
${params.BUILD_STRATEGY} run build
"""
script {
@@ -159,16 +155,16 @@ pipeline {
// publish packages to npm repository.
// commit new package-lock.json that might get generated during install
// Build will be ignore with tag '[skip ci]'
- stage ('Publish Packages'){
+ stage('Publish Packages') {
when {
expression { GIT_BRANCH_NAME == params.DEVELOP_BRANCH }
- expression { params.ENV_CHOICE == 'buildOnly' || params.ENV_CHOICE == 'buildAndPublish' }
+ expression { params.ENV_CHOICE == 'buildOnly' || params.ENV_CHOICE == 'buildAndPublish' }
}
- steps{
+ steps {
script {
- GIT_BRANCH_NAME=params.PUBLISH_BRANCH
+ GIT_BRANCH_NAME = params.PUBLISH_BRANCH
}
- sshagent (credentials: [params.GIT_CREDENTIAL_ID]) {
+ sshagent(credentials: [params.GIT_CREDENTIAL_ID]) {
sh """
git add -A
git diff --staged --quiet || git commit -am 'auto build [skip ci] \r\n'
@@ -182,16 +178,16 @@ pipeline {
}
}
- stage('Docker login'){
- steps{
+ stage('Docker login') {
+ steps {
sh 'cat "$GCR_KEY" | docker login -u _json_key --password-stdin https://gcr.io'
}
}
stage('Dev Docker Images') {
options {
- timeout(time: params.BUILD_TIME_OUT, unit: 'MINUTES')
- }
+ timeout(time: params.BUILD_TIME_OUT, unit: 'MINUTES')
+ }
when {
// Docker build need be performed in PUBLISH branch only
expression { GIT_BRANCH_NAME == params.PUBLISH_BRANCH }
@@ -199,46 +195,67 @@ pipeline {
}
// Below variable is only set to load all (variables, functions) from jenkins_variables.groovy file.
- environment{ deployment_env = 'dev' }
- steps{
- load "./jenkins_variables.groovy"
- script {
- def servers = getDirs(pwd() + params.DEPLOYMENT_PATH)
- def parallelStagesMap = servers.collectEntries {
- ["${it}" : generateBuildStage(it)]
+ environment {
+ deployment_env = 'dev'
+ BUILD_MODULE_TO_INCLUDE = "${params.BUILD_MODULE_TO_INCLUDE}"
+ }
+ steps {
+ load "./jenkins_variables.groovy"
+ script {
+ def servers = getDirs(pwd() + params.DEPLOYMENT_PATH)
+ def frontendProjects = servers.findAll { it.startsWith('frontend-') }
+ def otherProjects = servers - frontendProjects
+
+ // Create parallel stages for non-frontend projects
+ def parallelStagesMap = otherProjects.collectEntries {
+ ["${it}" : generateBuildStage(it)]
+ }
+
+ // Run the first frontend project in parallel with others
+ if (frontendProjects.size() > 0) {
+ parallelStagesMap["${frontendProjects[0]}"] = generateBuildStage(frontendProjects[0])
+ frontendProjects.remove(0)
+ }
+
+ // Run non-frontend projects in parallel
+ parallel parallelStagesMap
+
+ // Run remaining frontend projects sequentially
+ frontendProjects.each {
+ stage("${it}") {
+ runBuildStage(it)
}
- parallel parallelStagesMap
}
}
+ }
}
// Below are dev stages
stage('Dev deployment') {
- environment{
- deployment_env = 'dev'
+ environment {
+ deployment_env = 'dev'
}
when {
- expression { GIT_BRANCH_NAME == params.PUBLISH_BRANCH || GIT_BRANCH_NAME == params.DEVELOP_BRANCH }
+ expression { GIT_BRANCH_NAME == params.PUBLISH_BRANCH || GIT_BRANCH_NAME == params.DEVELOP_BRANCH }
expression { params.ENV_CHOICE == 'buildOnly' || params.ENV_CHOICE == 'devDeployOnly' }
beforeInput true
}
steps {
- withKubeConfig([credentialsId: 'kubernetes-dev-cluster-r1', serverUrl: "https://34.74.64.165"]) {
- sh """
+ withKubeConfig([credentialsId: 'kubernetes-dev-cluster-r1', serverUrl: "https://34.74.64.165"]) {
+ sh """
helm repo add stable https://charts.helm.sh/stable
helm repo add incubator https://charts.helm.sh/incubator
helm repo add kube-orchestration https://"""+ GITHUB_HELM_REPO_TOKEN +"""@raw.githubusercontent.com/cdmbase/kube-orchestration/develop/helm-packages
helm repo update
- """
+ """
script {
-
nameSpaceCheck = sh(script: "kubectl get ns | tr '\\n' ','", returnStdout: true)
if (!nameSpaceCheck.contains(env.NAMESPACE)) { sh "kubectl create ns " + env.NAMESPACE }
def servers = getDirs(pwd() + params.DEPLOYMENT_PATH)
def parallelStagesMap = servers.collectEntries {
- ["${it}" : generateStage(it, deployment_env)]
+ ["${it}" : generateStage(it, deployment_env)]
}
parallel parallelStagesMap
}
@@ -247,33 +264,32 @@ pipeline {
} // End of dev deployment code block.
// Only master branch will be merged
- stage ('Merge Develop to master & Install'){
+ stage('Merge Develop to master & Install') {
when {
expression { GIT_BRANCH_NAME == params.MASTER_BRANCH }
expression { params.ENV_CHOICE == 'stageDeploy' || params.ENV_CHOICE == 'prodDeploy' }
}
- steps{
+ steps {
sh """
git add -A
git diff --staged --quiet || git commit -am 'pre merge to master \r\n[skip ci]'
git checkout ${params.REPOSITORY_BRANCH}
git merge origin/${params.DEVELOP_BRANCH} -m 'auto merging ${params.DEVELOP_BRANCH} \r\n[skip ci]'
${params.BUILD_STRATEGY} install
- ${params.BUILD_STRATEGY} run lerna
"""
script {
GIT_BRANCH_NAME = params.REPOSITORY_BRANCH
}
}
}
-
+
// Run build for all cases except when ENV_CHOICE is 'buildAndPublish' and `dev`, `stage` or `prod`
- stage ('Prod Build Packages'){
+ stage('Prod Build Packages') {
when {
expression { GIT_BRANCH_NAME == params.MASTER_BRANCH }
expression { params.ENV_CHOICE == 'stageDeploy' || params.ENV_CHOICE == 'prodDeploy' }
}
- steps{
+ steps {
sh """
${params.BUILD_STRATEGY} run build
"""
@@ -283,16 +299,16 @@ pipeline {
// publish packages to npm repository.
// commit new package-lock.json that might get generated during install
// Build will be ignore with tag '[skip ci]'
- stage ('Prod Publish Packages'){
+ stage('Prod Publish Packages') {
when {
expression { GIT_BRANCH_NAME == params.MASTER_BRANCH }
expression { params.ENV_CHOICE == 'stageDeploy' || params.ENV_CHOICE == 'prodDeploy' }
}
- steps{
+ steps {
script {
- GIT_BRANCH_NAME=params.PUBLISH_BRANCH
+ GIT_BRANCH_NAME = params.PUBLISH_BRANCH
}
- sshagent (credentials: [params.GIT_CREDENTIAL_ID]) {
+ sshagent(credentials: [params.GIT_CREDENTIAL_ID]) {
sh """
git add -A
git diff --staged --quiet || git commit -am 'auto build [skip ci]\r\n'
@@ -305,12 +321,12 @@ pipeline {
}
}
}
-
+
// Build Docker containers for production.
stage('Prod Docker Images') {
options {
- timeout(time: params.BUILD_TIME_OUT, unit: 'MINUTES')
- }
+ timeout(time: params.BUILD_TIME_OUT, unit: 'MINUTES')
+ }
when {
// required to be in Publish branch to build docker
expression { GIT_BRANCH_NAME == params.PUBLISH_BRANCH }
@@ -318,25 +334,46 @@ pipeline {
}
// Below variable is only set to load all (variables, functions) from jenkins_variables.groovy file.
- environment{ deployment_env = 'prod' }
- steps{
- load "./jenkins_variables.groovy"
- script {
- def servers = getDirs(pwd() + params.DEPLOYMENT_PATH)
- def parallelStagesMap = servers.collectEntries {
- ["${it}" : generateBuildStage(it)]
+ environment { deployment_env = 'prod' }
+ steps {
+ load "./jenkins_variables.groovy"
+ script {
+ def servers = getDirs(pwd() + params.DEPLOYMENT_PATH)
+ def frontendProjects = servers.findAll { it.startsWith('frontend-') }
+ def otherProjects = servers - frontendProjects
+
+ // Create parallel stages for non-frontend projects
+ def parallelStagesMap = otherProjects.collectEntries {
+ ["${it}" : generateBuildStage(it)]
+ }
+
+ // First frontend project
+ if (frontendProjects) {
+ parallelStagesMap["${frontendProjects[0]}"] = generateBuildStage(frontendProjects[0])
+ frontendProjects.remove(0)
+ }
+
+ // Run non-frontend projects in parallel
+ parallel parallelStagesMap
+
+ // Run remaining frontend projects sequentially
+ frontendProjects.each {
+ stage("${it}") {
+ steps {
+ runBuildStage(it)
+ }
}
- parallel parallelStagesMap
}
}
+ }
} // End of production docker build.
// Below are stage code block
stage('Stage Deployment') {
options {
- timeout(time: 300, unit: 'SECONDS')
- }
- environment{
+ timeout(time: 300, unit: 'SECONDS')
+ }
+ environment {
deployment_env = 'stage'
}
when {
@@ -348,7 +385,6 @@ pipeline {
steps {
load "./jenkins_variables.groovy"
withKubeConfig([credentialsId: 'kubernetes-staging-cluster', serverUrl: 'https://34.139.244.149']) {
-
sh """
helm repo add stable https://charts.helm.sh/stable
helm repo add incubator https://charts.helm.sh/incubator
@@ -376,38 +412,25 @@ pipeline {
expression { params.SKIP_RELEASE_APPROVAL == false }
}
options {
- // Optionally, let's add a timeout that we don't allow ancient
- // builds to be released.
- timeout time: 900, unit: 'SECONDS'
+ timeout time: 900, unit: 'SECONDS'
}
steps {
- // Optionally, send some notifications to the approver before
- // asking for input. You can't do that with the input directive
- // without using an extra stage.
slackSend (color: '#2596BE', message: "Approval Needed for Production Release: Job '${env.JOB_NAME}' BUILD NUMBER: '${env.BUILD_NUMBER}' to be approved. Click <${env.RUN_DISPLAY_URL}|here> to approve it.", channel: 'idestack-automation')
- // The input statement has to go to a script block because we
- // want to assign the result to an environment variable. As we
- // want to stay as declarative as possible, we put noting but
- // this into the script block.
script {
- // Assign the 'DO_RELEASE' environment variable that is going
- // to be used in the next stage.
- env.DO_RELEASE = input message: 'Want to deploy fullstack-pro on prod cluster?',
- parameters:[choice(choices: ['yes', 'no'], description: 'Deploy branch in Production?', name: 'PROD_DEPLOYMENT')]
+ env.DO_RELEASE = input message: 'Want to deploy fullstack-pro on prod cluster?',
+ parameters: [choice(choices: ['yes', 'no'], description: 'Deploy branch in Production?', name: 'PROD_DEPLOYMENT')]
}
- // In case you approved multiple pipeline runs in parallel, this
- // milestone would kill the older runs and prevent deploying
- // older releases over newer ones.
milestone 1
}
}
+
// Below are production stages
stage('Prod Deployment') {
options {
timeout(time: 300, unit: 'SECONDS')
}
- environment{
+ environment {
deployment_env = 'prod'
}
when {
@@ -418,17 +441,8 @@ pipeline {
}
steps {
- // Make sure that only one release can happen at a time.
lock('release') {
- // As using the first milestone only would introduce a race
- // condition (assume that the older build would enter the
- // milestone first, but the lock second) and Jenkins does
- // not support inter-stage locks yet, we need a second
- // milestone to make sure that older builds don't overwrite
- // newer ones.
milestone 2
-
- // Now do the actual work here
load "./jenkins_variables.groovy"
withKubeConfig([credentialsId: 'kubernetes-prod-cluster-r1', serverUrl: 'https://35.229.71.215']) {
sh """
@@ -440,7 +454,7 @@ pipeline {
script {
nameSpaceCheck = sh(script: "kubectl get ns | tr '\\n' ','", returnStdout: true)
if (!nameSpaceCheck.contains(env.NAMESPACE)) { sh "kubectl create ns " + env.NAMESPACE }
-
+
def servers = getDirs(pwd() + params.DEPLOYMENT_PATH)
def parallelStagesMap = servers.collectEntries {
["${it}" : generateStage(it, deployment_env)]
@@ -459,35 +473,35 @@ pipeline {
always {
deleteDir()
}
- success{
+ success {
slackSend (color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME}' BUILD NUMBER: '${env.BUILD_NUMBER}' Job success. click <${env.RUN_DISPLAY_URL}|here> to see the log.", channel: 'idestack-automation')
}
- failure{
+ failure {
slackSend (color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME}' BUILD NUMBER: '${env.BUILD_NUMBER}' Job failed. click <${env.RUN_DISPLAY_URL}|here> to see the log.", channel: 'idestack-automation')
}
}
}
-def getBuildCommand(){
- if(params.ENV_CHOICE == 'mobileBuild'){
+def getBuildCommand() {
+ if (params.ENV_CHOICE == 'mobileBuild') {
return 'build:auto'
}
- if(params.ENV_CHOICE == 'mobilePreview'){
+ if (params.ENV_CHOICE == 'mobilePreview') {
return 'build:preview:' + params.MOBILE_CHOICE
}
- if(params.ENV_CHOICE == 'mobilePreviewLocal'){
+ if (params.ENV_CHOICE == 'mobilePreviewLocal') {
return 'build:previewLocal:' + params.MOBILE_CHOICE
}
- if(params.ENV_CHOICE == 'mobilePreviewSubmit'){
+ if (params.ENV_CHOICE == 'mobilePreviewSubmit') {
return 'build:previewSubmit:' + params.MOBILE_CHOICE
}
- if(params.ENV_CHOICE == 'mobileProd'){
+ if (params.ENV_CHOICE == 'mobileProd') {
return 'build:prod:' + params.MOBILE_CHOICE
}
- if(params.ENV_CHOICE == 'mobileProdSubmit'){
+ if (params.ENV_CHOICE == 'mobileProdSubmit') {
return 'build:prodSubmit:' + params.MOBILE_CHOICE
}
- if(params.ENABLE_DEBUG.toBoolean()){
+ if (params.ENABLE_DEBUG.toBoolean()) {
return 'build:debug'
} else {
return 'build'
@@ -495,18 +509,15 @@ def getBuildCommand(){
}
def getGitPrBranchName() {
- // The branch name could be in the BRANCH_NAME or GIT_BRANCH variable depending on the type of job
- //def branchName = env.BRANCH_NAME ? env.BRANCH_NAME : env.GIT_BRANCH
- //return branchName || ghprbSourceBranch
- if(env.ghprbSourceBranch){
+ if (env.ghprbSourceBranch) {
return env.ghprbSourceBranch
} else {
return params.REPOSITORY_BRANCH
}
}
-def getGitBranchName(){ // we can place some conditions in future
- if(env.ghprbSourceBranch){
+def getGitBranchName() {
+ if (env.ghprbSourceBranch) {
return env.ghprbSourceBranch
} else {
return params.REPOSITORY_BRANCH
@@ -515,23 +526,23 @@ def getGitBranchName(){ // we can place some conditions in future
@NonCPS
//TODO: Fix below get method for Jenkins slave if possible.
-def getDirs1(path){
+def getDirs1(path) {
def currentDir = new File(path)
def dirs = []
currentDir.eachDir() {
- dirs << it.name
+ dirs << it.name
}
return dirs
}
// Below function to work in Jenkins slave
-def getDirs(path){
- def currentDir = sh(script: "ls -CF "+path+" | tr '/' ' '", returnStdout: true)
- def dirs = []
- (currentDir.split()).each {
- dirs << "${it}"
- }
- return dirs
+def getDirs(path) {
+ def currentDir = sh(script: "ls -CF " + path + " | tr '/' ' '", returnStdout: true)
+ def dirs = []
+ (currentDir.split()).each {
+ dirs << "${it}"
+ }
+ return dirs
}
def generateStage(server, environmentType) {
@@ -544,15 +555,15 @@ def generateStage(server, environmentType) {
def version = getVersion(pwd() + params.DEPLOYMENT_PATH + "/${server}/package.json")
def valuesFile = "values-${environmentType}.yaml"
// deploy anything matching `*backend-server` or `*frontend-server` to use idestack chart
- try{
+ try {
if ("${server}".endsWith("backend-server") | "${server}".endsWith("frontend-server")) {
echo "add deployment flag to - ${server} "
- if ("${server}".endsWith("frontend-server")){
+ if ("${server}".endsWith("frontend-server")) {
deployment_flag = " --set backend.enabled='false' --set external.enabled='true'"
}
- if ("${server}".endsWith("backend-server")){
+ if ("${server}".endsWith("backend-server")) {
deployment_flag = " --set frontend.enabled='false' --set external.enabled='false' --set ingress.enabled=false "
}
@@ -560,7 +571,7 @@ def generateStage(server, environmentType) {
helm upgrade -i \
${server} \
-f "${valuesFile}" \
- ${namespace}\
+ ${namespace} \
${deployment_flag} \
--set frontend.image="${REPOSITORY_SERVER}/${name}" \
--set frontend.imageTag=${version} \
@@ -572,12 +583,11 @@ def generateStage(server, environmentType) {
--set VERSION=${VERSION} \
--version=${IDESTACK_CHART_VERSION} \
kube-orchestration/idestack
- """
-
+ """
} else {
sh """
cd .${params.DEPLOYMENT_PATH}/${server}
- helm dependency update charts/chart/
+ helm dependency update charts/chart/
helm upgrade -i \
${server}-api \
-f "charts/chart/${valuesFile}" \
@@ -587,7 +597,6 @@ def generateStage(server, environmentType) {
--set VERSION=${VERSION} \
charts/chart
"""
-
}
} catch (Exception err) {
slackSend (color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME}' BUILD NUMBER: '${env.BUILD_NUMBER}' Job failed in stage deployment ${server}. click <${env.RUN_DISPLAY_URL}|here> to see the log. Error: ${err.toString()}", channel: 'idestack-automation')
@@ -602,35 +611,59 @@ def generateStage(server, environmentType) {
def generateBuildStage(server) {
return {
stage("stage: ${server}") {
- try{
- echo "This is ${server}."
- def name = getName(pwd() + params.DEPLOYMENT_PATH + "/${server}/package.json")
- def version = getVersion(pwd() + params.DEPLOYMENT_PATH + "/${server}/package.json")
- sh """
- lerna exec --scope=*${server} ${params.BUILD_STRATEGY} run docker:${env.BUILD_COMMAND};
- docker tag ${name}:${version} ${REPOSITORY_SERVER}/${name}:${version}
- docker push ${REPOSITORY_SERVER}/${name}:${version}
- docker rmi ${REPOSITORY_SERVER}/${name}:${version}
- """
+ try {
+ echo "This is ${server}."
+ def name = getName(pwd() + params.DEPLOYMENT_PATH + "/${server}/package.json")
+ def version = getVersion(pwd() + params.DEPLOYMENT_PATH + "/${server}/package.json")
+
+ buildAndPushDockerImage(server, name, version)
} catch (e) {
- slackSend (color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME}' BUILD NUMBER: '${env.BUILD_NUMBER}' Job failed in stage docker-build ${server}. click <${env.RUN_DISPLAY_URL}|here> to see the log. Error: ${e}", channel: 'idestack-automation')
+ slackSend(color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME}' BUILD NUMBER: '${env.BUILD_NUMBER}' Job failed in stage docker-build ${server}. click <${env.RUN_DISPLAY_URL}|here> to see the log. Error: ${e}", channel: 'idestack-automation')
throw(e)
}
}
}
}
+def runBuildStage(server) {
+ try {
+ echo "This is ${server}."
+ def name = getName(pwd() + params.DEPLOYMENT_PATH + "/${server}/package.json")
+ def version = getVersion(pwd() + params.DEPLOYMENT_PATH + "/${server}/package.json")
+
+ buildAndPushDockerImage(server, name, version)
+ } catch (e) {
+ slackSend(color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME}' BUILD NUMBER: '${env.BUILD_NUMBER}' Job failed in stage docker-build ${server}. click <${env.RUN_DISPLAY_URL}|here> to see the log. Error: ${e}", channel: 'idestack-automation')
+ throw(e)
+ }
+}
+
+def buildAndPushDockerImage(server, name, version) {
+ def imageExists = sh(script: "docker manifest inspect ${REPOSITORY_SERVER}/${name}:${version} > /dev/null 2>&1 && echo 'true' || echo 'false'", returnStdout: true).trim()
+
+ if (imageExists == 'true') {
+ echo "Docker image ${REPOSITORY_SERVER}/${name}:${version} already exists. Skipping build."
+ } else {
+ sh """
+ npx lerna exec --scope=*${server} ${params.BUILD_STRATEGY} run docker:${env.BUILD_COMMAND};
+ docker tag ${name}:${version} ${REPOSITORY_SERVER}/${name}:${version}
+ docker push ${REPOSITORY_SERVER}/${name}:${version}
+ docker rmi ${REPOSITORY_SERVER}/${name}:${version}
+ """
+ }
+}
+
import groovy.json.JsonSlurper
-def getVersion(json_file_path){
+def getVersion(json_file_path) {
def inputFile = readFile(json_file_path)
def InputJSON = new JsonSlurper().parseText(inputFile)
def version = InputJSON.version
return version
}
-def getName(json_file_path){
+def getName(json_file_path) {
def inputFile = readFile(json_file_path)
def InputJSON = new JsonSlurper().parseText(inputFile)
def name = InputJSON.name
return name
-}
+}
\ No newline at end of file
diff --git a/build.config.js b/build.config.js
index 1b43a6d95..7362c5863 100644
--- a/build.config.js
+++ b/build.config.js
@@ -1,35 +1,32 @@
/* eslint-disable no-nested-ternary */
/* eslint-disable no-underscore-dangle */
-process.env.ENV_FILE !== null && require('dotenv').config({ path: process.env.ENV_FILE });
+// process.env.ENV_FILE !== null && require('dotenv').config({ path: process.env.ENV_FILE });
const __API_SERVER_PORT__ = process.env.GRAPHQL_URL ? new URL(process.env.GRAPHQL_URL).port : 8080;
const __WEB_SERVER_PORT__ = process.env.LOCAL_BACKEND_URL ? new URL(process.env.LOCAL_BACKEND_URL).port : 3000;
-const __WEB_DEV_SERVER_PORT__ = process.env.SSR
- ? 3010
- : process.env.CLIENT_URL
- ? new URL(process.env.CLIENT_URL).port
- : 3000;
+const __WEB_DEV_SERVER_PORT__ =
+ process.env.SSR === 'true' ? 3010 : process.env.CLIENT_URL ? new URL(process.env.CLIENT_URL).port : 3000;
const __SERVER_PROTOCOL__ = 'http';
-const __SERVER_HOST__ = 'localhost';
+const __LOCAL_SERVER_HOST__ = 'localhost';
const __GRAPHQL_ENDPOINT__ = process.env.GRAPHQL_URL ? new URL(process.env.GRAPHQL_URL).pathname : '/graphql';
const config = {
__SERVER__: false,
__CLIENT__: true,
- __SSR__: process.env.NODE_ENV === 'production', // enableing SSR only in Production as in Dev we have a issue
+ __SSR_BACKEND__: process.env.SSR_BACKEND,
+ __SSR__: process.env.SSR === 'true',
__DEBUGGING__: false,
__TEST__: false,
__WEB_DEV_SERVER_PORT__,
__GRAPHQL_ENDPOINT__,
- __SERVER_HOST__,
+ __LOCAL_SERVER_HOST__,
__API_SERVER_PORT__,
__API_URL__:
process.env.API_URL ||
- `${__SERVER_PROTOCOL__}://${__SERVER_HOST__}:${__API_SERVER_PORT__}${__GRAPHQL_ENDPOINT__}`,
+ `${__SERVER_PROTOCOL__}://${__LOCAL_SERVER_HOST__}:${__API_SERVER_PORT__}${__GRAPHQL_ENDPOINT__}`,
__WEBSITE_URL__:
- process.env.WEBSITE_URL || `${__SERVER_PROTOCOL__}://${__SERVER_HOST__}:${__WEB_DEV_SERVER_PORT__}`,
+ process.env.WEBSITE_URL || `${__SERVER_PROTOCOL__}://${__LOCAL_SERVER_HOST__}:${__WEB_DEV_SERVER_PORT__}`,
__BACKEND_URL__:
- process.env.LOCAL_BACKEND_URL || `${__SERVER_PROTOCOL__}://${__SERVER_HOST__}:${__WEB_SERVER_PORT__}`,
+ process.env.LOCAL_BACKEND_URL || `${__SERVER_PROTOCOL__}://${__LOCAL_SERVER_HOST__}:${__WEB_SERVER_PORT__}`,
};
-console.log('---CONFIG', config);
module.exports = config;
diff --git a/build.config.mjs b/build.config.mjs
new file mode 100644
index 000000000..fe8d098ba
--- /dev/null
+++ b/build.config.mjs
@@ -0,0 +1,37 @@
+/* eslint-disable no-nested-ternary */
+/* eslint-disable no-underscore-dangle */
+import { config as dotenvConfig } from 'dotenv-esm';
+
+if (process.env.ENV_FILE !== null) {
+ dotenvConfig({ path: process.env.ENV_FILE });
+}
+
+const __API_SERVER_PORT__ = process.env.GRAPHQL_URL ? new URL(process.env.GRAPHQL_URL).port : 8080;
+const __WEB_SERVER_PORT__ = process.env.LOCAL_BACKEND_URL ? new URL(process.env.LOCAL_BACKEND_URL).port : 3000;
+const __WEB_DEV_SERVER_PORT__ =
+ process.env.SSR === 'true' ? 3010 : process.env.CLIENT_URL ? new URL(process.env.CLIENT_URL).port : 3000;
+const __SERVER_PROTOCOL__ = 'http';
+const __LOCAL_SERVER_HOST__ = 'localhost';
+const __GRAPHQL_ENDPOINT__ = process.env.GRAPHQL_URL ? new URL(process.env.GRAPHQL_URL).pathname : '/graphql';
+
+const config = {
+ __SERVER__: false,
+ __CLIENT__: true,
+ __SSR_BACKEND__: process.env.SSR_BACKEND,
+ __SSR__: process.env.SSR === 'true',
+ __DEBUGGING__: false,
+ __TEST__: false,
+ __WEB_DEV_SERVER_PORT__,
+ __GRAPHQL_ENDPOINT__,
+ __LOCAL_SERVER_HOST__,
+ __API_SERVER_PORT__,
+ __API_URL__:
+ process.env.API_URL ||
+ `${__SERVER_PROTOCOL__}://${__LOCAL_SERVER_HOST__}:${__API_SERVER_PORT__}${__GRAPHQL_ENDPOINT__}`,
+ __WEBSITE_URL__:
+ process.env.WEBSITE_URL || `${__SERVER_PROTOCOL__}://${__LOCAL_SERVER_HOST__}:${__WEB_DEV_SERVER_PORT__}`,
+ __BACKEND_URL__:
+ process.env.LOCAL_BACKEND_URL || `${__SERVER_PROTOCOL__}://${__LOCAL_SERVER_HOST__}:${__WEB_SERVER_PORT__}`,
+};
+
+export default config;
diff --git a/codegen.yml b/codegen.yml
index b41f7b577..e90837c72 100755
--- a/codegen.yml
+++ b/codegen.yml
@@ -18,6 +18,7 @@ generates:
withMutationFn: false
withHOC: false
withComponent: false
+ noGraphQLTag: true
plugins:
- add:
content: /* tslint:disable */
@@ -33,8 +34,9 @@ generates:
config:
withMutationFn: false
withHOC: false
- withComponent: true
+ withComponent: false
withHooks: true
+ noGraphQLTag: true
preset: import-types-preset
presetConfig:
typesPath: "../generated-models"
diff --git a/config/development/dev.env.sample b/config/development/dev.env.sample
index c57da82b9..e25f8af4d 100755
--- a/config/development/dev.env.sample
+++ b/config/development/dev.env.sample
@@ -1,6 +1,10 @@
#
# Create `dev.env` file and load following required values
#
+# Build-time Variables
+BUILD_MODULE_TO_INCLUDE=@sample-stack/counter-module-browser|@sample-stack/assets|@sample-stack/platform-browser
+
+
NATS_URL=nats://localhost:4222/
NATS_USER=test
NATS_PW=test
diff --git a/config/staging/docker-staging.env.sample b/config/staging/docker-staging.env.sample
new file mode 100644
index 000000000..76579b284
--- /dev/null
+++ b/config/staging/docker-staging.env.sample
@@ -0,0 +1,26 @@
+###
+### To connect from docker to localhost, if you are using a Mac host, you can use -
+#
+# HOSTNAME= docker.for.mac.host.internal
+# Or
+#
+# HOSTNAME = docker.for.mac.localhost
+###docker.for.mac.localhost
+
+NATS_URL=nats://docker.for.mac.localhost:4222/
+NATS_USER=test
+NATS_PW=test
+GRAPHQL_URL=http://docker.for.mac.localhost:8080/graphql
+LOCAL_GRAPHQL_URL=http://docker.for.mac.localhost:8080/graphql
+CLIENT_URL=http://localhost:3010
+ZIPKIN_URL=test
+ZIPKIN_PORT=test
+LOG_LEVEL=trace
+MONGO_URL=mongodb://docker.for.mac.localhost:27017/sample-stack
+REDIS_CLUSTER_URL='[{"port":6379,"host":"docker.for.mac.localhost"}]'
+REDIS_URL=redis://docker.for.mac.localhost:6379
+REDIS_CLUSTER_ENABLED=false
+REDIS_SENTINEL_ENABLED=false
+BACKEND_URL=http://localhost:8080
+CONNECTION_ID=v1
+LOCAL_BACKEND_URL=http://localhost:3010
\ No newline at end of file
diff --git a/config/staging/staging.env.sample b/config/staging/staging.env.sample
new file mode 100755
index 000000000..cda4af70b
--- /dev/null
+++ b/config/staging/staging.env.sample
@@ -0,0 +1,20 @@
+#
+# Create `dev.env` file and load following required values
+#
+NATS_URL=nats://localhost:4222/
+NATS_USER=test
+NATS_PW=test
+GRAPHQL_URL=http://localhost:8080/graphql
+LOCAL_GRAPHQL_URL=http://localhost:8080/graphql
+CLIENT_URL=http://localhost:3011
+ZIPKIN_URL=test
+ZIPKIN_PORT=test
+LOG_LEVEL=trace
+MONGO_URL=mongodb://localhost:27017/sample-stack
+REDIS_CLUSTER_URL='[{"port":6379,"host":"localhost"}]'
+REDIS_URL=redis://localhost:6379
+REDIS_CLUSTER_ENABLED=false
+REDIS_SENTINEL_ENABLED=false
+BACKEND_URL=http://localhost:8080
+CONNECTION_ID=v1
+LOCAL_BACKEND_URL=http://localhost:3000
\ No newline at end of file
diff --git a/jest-mongodb-config.js b/jest-mongodb-config.js
index efdef0e3f..a6da3a105 100644
--- a/jest-mongodb-config.js
+++ b/jest-mongodb-config.js
@@ -1,12 +1,13 @@
module.exports = {
mongodbMemoryServerOptions: {
- instance: {
- dbName: 'jest'
- },
- binary: {
- version: '4.0.12', // Version of MongoDB
- skipMD5: true
- },
- autoStart: false
- }
- };
\ No newline at end of file
+ instance: {
+ dbName: 'jest',
+ storageEngine: 'wiredTiger',
+ },
+ binary: {
+ version: '4.0.27', // Version of MongoDB
+ skipMD5: true,
+ },
+ autoStart: false,
+ },
+};
diff --git a/jest.config.base.js b/jest.config.base.js
index 45161c219..5335374a0 100755
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -2,6 +2,45 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { defaults } = require('jest-config');
+const packagesToTransform = [
+ '@apollo/client',
+ '@common-stack/client-core',
+ '@common-stack/client-react',
+ '@common-stack/core',
+ '@admin-layout/client',
+ '@common-stack/components-pro',
+ '@common-stack/server-core',
+ '@common-stack/cache-api-server',
+ '@common-stack/remix-router-redux',
+ '@cdmbase/redux-auth-wrapper',
+ '@cdmbase/remix-redis-session',
+ '@cdm-logger/server',
+ '@cdm-logger/core',
+ '@cdm-logger/client',
+ '@files-stack/server-core',
+ '@vscode-alt/monaco-editor',
+ '@workbench-stack/core',
+ '@workbench-stack/platform-server',
+ 'abortable-rx',
+ 'lodash-es',
+ 'sort-keys',
+ 'is-plain-obj',
+ 'query-string',
+ 'decode-uri-component',
+ 'split-on-first',
+ 'filter-obj',
+ 'react-dnd-html5-backend',
+ 'react-sortable-tree',
+ 'react-dnd',
+ 'dnd-core',
+];
+
+const generateTransformIgnorePattern = (packages) => {
+ const escapedPackages = packages.map((pkg) => pkg.replace(/\//g, '\\/'));
+ return `/node_modules/(?!(${escapedPackages.join('|')})/).+\\.js$`;
+};
+const transformIgnorePattern = generateTransformIgnorePattern(packagesToTransform);
+
module.exports = {
testEnvironment: 'node',
setupFiles: [
@@ -10,11 +49,11 @@ module.exports = {
],
preset: 'ts-jest',
testMatch: null,
- testRegex: '.*test*\\.(ts|tsx|js)$',
- testPathIgnorePatterns: ['/node_modules/', '/dist/'],
+ testRegex: '.*test\\.(ts|tsx|js)$',
+ testPathIgnorePatterns: ['/node_modules/', '/lib', '/dist/'],
transform: {
'\\.(gql)$': 'jest-transform-graphql',
- '\\.(graphql|graphqls)$': 'jest-raw-loader',
+ '\\.(graphql|graphqls)$': '@glen/jest-raw-loader',
'\\.(ts|tsx)$': 'ts-jest',
// Use our custom transformer only for the *.js and *.jsx files
'\\.(js|jsx)?$': './transform.js',
@@ -39,7 +78,7 @@ module.exports = {
// because we don't need to use any kind of tree shaking right?!
'^lodash-es$': '/node_modules/lodash/index.js',
},
- transformIgnorePatterns: ['/node_modules/(?!(babel-runtime|antd)).*/', '/node_modules/(?!lodash-es/.*)'],
+ transformIgnorePatterns: [transformIgnorePattern],
clearMocks: true,
verbose: true,
// projects: [''], // TODO need to test with it https://github.com/bryan-hunter/yarn-workspace-lerna-monorepo/blob/master/jest.config.base.js
diff --git a/jest.config.base.mjs b/jest.config.base.mjs
new file mode 100644
index 000000000..435ae8c55
--- /dev/null
+++ b/jest.config.base.mjs
@@ -0,0 +1,94 @@
+/* eslint-disable import/no-extraneous-dependencies */
+/* eslint-disable @typescript-eslint/no-var-requires */
+import { defaults } from 'jest-config';
+
+const packagesToTransform = [
+ '@apollo/client',
+ '@apollo/server',
+ '@graphql-tools/schema',
+ '@graphql-tools/mock',
+ '@common-stack/client-core',
+ '@common-stack/client-react',
+ '@common-stack/core',
+ '@common-stack/server-core',
+ '@common-stack/cache-api-server',
+ '@common-stack/remix-router-redux',
+ '@common-stack/graphql-api',
+ '@cdmbase/graphql-type-uri',
+ '@cdm-logger/server',
+ '@cdm-logger/core',
+ '@cdm-logger/client',
+ '@files-stack/core',
+ '@files-stack/server-core',
+ '@vscode-alt/monaco-editor',
+ '@workbench-stack/core',
+ '@workbench-stack/platform-server',
+ 'graphql',
+ 'abortable-rx',
+ 'lodash-es',
+ 'sort-keys',
+ 'is-plain-obj',
+ 'query-string',
+ 'decode-uri-component',
+ 'split-on-first',
+ 'filter-obj',
+ 'react-dnd-html5-backend',
+ 'react-sortable-tree',
+ 'react-dnd',
+ 'dnd-core',
+];
+
+const generateTransformIgnorePattern = (packages) => {
+ const escapedPackages = packages.map((pkg) => pkg.replace(/\//g, '\\/'));
+ return `/node_modules/(?!(${escapedPackages.join('|')})/).+\\.js$`;
+};
+const transformIgnorePattern = generateTransformIgnorePattern(packagesToTransform);
+
+export default {
+ testEnvironment: 'node',
+ setupFiles: [
+ // needed for UI to mock canvas load
+ // "jest-canvas-mock"
+ ],
+ extensionsToTreatAsEsm: ['.ts', '.tsx'],
+ preset: 'ts-jest',
+ testMatch: null,
+ testRegex: '.*test\\.(ts|tsx|js)$',
+ testPathIgnorePatterns: ['/node_modules/', '/lib', '/dist/'],
+ transform: {
+ '\\.(gql)$': 'jest-transform-graphql',
+ '\\.(graphql|graphqls)$': '@glen/jest-raw-loader',
+ '\\.(ts|tsx)$': 'ts-jest',
+ // // Use our custom transformer only for the *.js and *.jsx files
+ '\\.(js|jsx)?$': './transform.mjs',
+ // future need to test with
+ // "^.+\\.(js|jsx|ts|tsx)$": "./transform.js",
+ '.+\\.(css|styl|less|sass|scss)$': 'jest-css-modules-transform',
+ },
+ roots: ['packages', 'packages-modules', 'servers'],
+ moduleFileExtensions: [...defaults.moduleFileExtensions, 'json', 'gql', 'graphql'],
+ moduleNameMapper: {
+ '^__mocks__/(.*)$': '/../../__mocks__/$1',
+ // we'll use commonjs version of lodash for tests 👌
+ // because we don't need to use any kind of tree shaking right?!
+ '^lodash-es$': '/node_modules/lodash/index.js',
+ },
+ transformIgnorePatterns: [transformIgnorePattern],
+ clearMocks: true,
+ verbose: true,
+ // projects: [''], // TODO need to test with it https://github.com/bryan-hunter/yarn-workspace-lerna-monorepo/blob/master/jest.config.base.js
+ coverageDirectory: '/coverage/',
+ coveragePathIgnorePatterns: ['/build/', '/lib/', '/dist/', '/node_modules/'],
+ globals: {
+ __BACKEND_URL__: 'http://localhost:3010',
+ __GRAPHQL_URL__: 'http://localhost:8085/graphql',
+ 'ts-jest': {
+ // tsConfig: "/src/__tests__/tsconfig.json",
+ // https://github.com/kulshekhar/ts-jest/issues/766
+ diagnostics: {
+ warnOnly: true,
+ },
+ // "skipBabel": true
+ },
+ },
+};
diff --git a/jest.config.mongodb.mjs b/jest.config.mongodb.mjs
new file mode 100644
index 000000000..ffb542d95
--- /dev/null
+++ b/jest.config.mongodb.mjs
@@ -0,0 +1,3 @@
+export default {
+ preset: '@shelf/jest-mongodb',
+};
diff --git a/lerna.json b/lerna.json
index 491f38a14..759884a8b 100755
--- a/lerna.json
+++ b/lerna.json
@@ -1,42 +1,48 @@
{
- "$schema": "./node_modules/lerna/schemas/lerna-schema.json",
- "changelog": true,
- "command": {
- "publish": {
- "registry": "https://registry.npmjs.org",
- "graphType": "all",
- "allowBranch": [
- "publish",
- "devpublish",
- "devpublishn2"
- ],
- "message": "chore(release): publish",
- "ignoreChanges": [
- "**/__fixtures__/**",
- "**/__tests__/**",
- "**/*.md",
- "**/example/**"
- ]
- },
- "version": {
- "allowBranch": [
- "master",
- "develop",
- "publish",
- "devpublish",
- "devpublishn2"
- ],
- "private": true,
- "conventionalCommits": true,
- "message": "chore: release package(s)"
- }
+ "$schema": "./node_modules/lerna/schemas/lerna-schema.json",
+ "changelog": true,
+ "command": {
+ "publish": {
+ "registry": "https://registry.npmjs.org",
+ "allowBranch": [
+ "publish",
+ "devpublish",
+ "devpublish3",
+ "devpublishn2",
+ "devpublish4",
+ "devpublish5"
+ ],
+ "message": "chore(release): publish",
+ "ignoreChanges": [
+ "**/__fixtures__/**",
+ "**/__tests__/**",
+ "**/*.md",
+ "**/example/**"
+ ]
},
- "npmClient": "yarn",
- "packages": [
- "packages-modules/**",
- "packages/**",
- "servers/*",
- "portable-devices/*"
- ],
- "version": "0.0.0"
+ "version": {
+ "allowBranch": [
+ "master",
+ "develop",
+ "publish",
+ "devpublish",
+ "devpublish3",
+ "devpublishn2",
+ "devpublish4",
+ "devpublish5"
+ ],
+ "private": true,
+ "conventionalCommits": true,
+ "message": "chore: release package(s)"
+ }
+ },
+ "npmClient": "yarn",
+ "useNx": true,
+ "packages": [
+ "packages-modules/**",
+ "packages/**",
+ "servers/*",
+ "portable-devices/*"
+ ],
+ "version": "5.0.1"
}
\ No newline at end of file
diff --git a/lint-staged.config.js b/lint-staged.config.js
index 253c221f7..7c6c56a4b 100644
--- a/lint-staged.config.js
+++ b/lint-staged.config.js
@@ -1,4 +1,5 @@
module.exports = {
'*.{js,jsx,ts,tsx,json,md}': ['prettier --write', 'git add'],
// '*.{ts,tsx}': ['eslint --fix'], // this can be tested
-};
\ No newline at end of file
+ 'package.json': ['sort-package-json', 'prettier --write'],
+};
diff --git a/nx.json b/nx.json
index 1469d49dc..a357ab822 100644
--- a/nx.json
+++ b/nx.json
@@ -1,33 +1,25 @@
{
- "tasksRunnerOptions": {
- "default": {
- "runner": "nx/tasks-runners/default",
- "options": {
- "cacheableOperations": [
- "build"
- ]
- }
- }
- },
- "namedInputs": {
- "adminide": [
- "{projectRoot}/packages/**/*",
- "{projectRoot}/packages-modules/**/*"
- ]
- },
- "targetDefaults": {
- "build": {
- "dependsOn": [
- "^build"
- ],
- "inputs": [
- "adminide"
- ]
+ "tasksRunnerOptions": {
+ "default": {
+ "runner": "@nx-aws-plugin/nx-aws-cache",
+ "options": {
+ "runtimeCacheInputs": ["node --version"],
+ "awsAccessKeyId": "xxxx",
+ "awsSecretAccessKey": "xxxx",
+ "awsRegion": "ca-central-1",
+ "awsBucket": "clockbook-screenshot"
+ }
+ }
},
- "test": {
- "dependsOn": [
- "build"
- ]
+ "targetDefaults": {
+ "build": {
+ "dependsOn": ["^build"],
+ "inputs": ["default", "^default", "{projectRoot}/src/**/*"],
+ "cache": true,
+ "outputs": ["{projectRoot}/lib"]
+ },
+ "test": {
+ "dependsOn": ["^test"]
+ }
}
- }
}
diff --git a/package.json b/package.json
index 834fe34bd..172c0610f 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "sample-stack",
- "version": "0.12.4",
+ "version": "0.14.0",
"private": true,
"homepage": "https://github.com/cdmbase/fullstack-pro#readme",
"bugs": {
@@ -43,9 +43,8 @@
"db:migrate": "knex migrate:latest --cwd . --knexfile ./servers/backend-server/knexfile.js",
"db:migrate:rollback": "knex migrate:rollback --cwd . --knexfile ./servers/backend-server/knexfile.js",
"db:seed": "yarn db:migrate && knex seed:run --cwd . --knexfile ./servers/backend-server/knexfile.js",
- "setBranchEnv": "cross-env REPOSITORY_BRANCH=${1:-$REPOSITORY_BRANCH} PUBLISH_BRANCH=${2:-$PUBLISH_BRANCH}",
"predevpublish": "if ! git show-ref --verify --quiet refs/remotes/origin/$PUBLISH_BRANCH; then git checkout -b $PUBLISH_BRANCH && git push -u origin $PUBLISH_BRANCH; fi && git fetch origin $PUBLISH_BRANCH && git checkout $PUBLISH_BRANCH && git pull origin $PUBLISH_BRANCH && git merge -s recursive -X theirs $REPOSITORY_BRANCH -m \"merge from $REPOSITORY_BRANCH\" && yarn gitcommit && node tools/update-dependency-version.js && yarn gitcommit",
- "devpublish": "lerna publish prerelease --ignore-scripts --exact",
+ "devpublish": "lerna publish prerelease --ignore-scripts --exact",
"postdevpublish": "git checkout $REPOSITORY_BRANCH",
"devpublish:auto": "yarn devpublish -- --yes",
"devpublish:force": "yarn devpublish -- --force-publish=* --yes",
@@ -62,29 +61,34 @@
"jest": "./node_modules/.bin/jest",
"lerna": "lerna bootstrap",
"prelernapublish": "git checkout publish && git pull origin publish && git merge -s recursive -X theirs master -m 'merge from master' && yarn gitcommit && node tools/update-dependency-version.js && yarn gitcommit",
- "lernapublish": "lerna publish --ignore-scripts --cd-version=patch",
+ "lernapublish": "lerna publish --ignore-scripts --cd-version=patch && yarn update-lerna-on-develop",
"postlernapublish": "git checkout master",
"lint": "eslint --ext js --ext ts --ext md",
"lint:ci": "yarn lint . --format junit",
"lint:fix": "yarn lint -- --fix",
"lint:md": "markdownlint",
"lintx": "yarn lint ./packages/**/src/**/*.ts ./packages-modules/**/src/**/*.ts",
+ "prepare": "husky",
"prodBuild": "cross-env NODE_ENV=production babel-node --presets es2015 tools/webpack.run",
"publish": "yarn lernapublish",
"publish:auto": "yarn lernapublish --yes",
"publish:force": "yarn publish:forceManual --yes",
"publish:forceManual": "yarn lernapublish --force-publish=*",
"publish:push": "yarn prelernapublish && git push origin publish && yarn postlernapublish",
- "startWeb": "lerna run --scope='{*frontend-server,*backend-server}' --parallel watch --stream",
+ "setBranchEnv": "cross-env REPOSITORY_BRANCH=${1:-$REPOSITORY_BRANCH} PUBLISH_BRANCH=${2:-$PUBLISH_BRANCH}",
+ "sort-packages": "node tools/sortPackageJson.mjs && prettier --write package.json **/**/*/package.json **/*/package.json",
"start": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env yarn startWeb",
- "start:envSSR": "cross-env SSR=true NODE_ENV=development ENV_FILE=../../config/development/dev.env yarn startWeb",
+ "start:SSR": "concurrently --names \"BACKEND,FRONTEND\" -c \"bgBlue.bold,bgMagenta.bold\" \"lerna run --scope='*backend-server' start\" \"lerna run --scope='*frontend-server' start:SSR\"",
+ "start:devSSR": "concurrently --names \"BACKEND,FRONTEND\" -c \"bgBlue.bold,bgMagenta.bold\" \"lerna run --scope='*backend-server' watch\" \"lerna run --scope='*frontend-server' start:devSSR\"",
"start:test": "cross-env NODE_ENV=test ENV_FILE=../../config/test/test.env yarn startWeb",
+ "startWeb": "lerna run --scope='{*frontend-server,*backend-server}' --parallel watch --stream",
"test": "cross-env ENV_FILE=config/test/test.env jest",
"posttest": "yarn lint",
"test:watch": "npm test -- --watch",
"pretravis": "yarn compile",
"travis": "istanbul cover -x \"*.test.js\" _mocha -- --timeout 5000 --full-trace ./test/tests.js",
"posttravis": "yarn lint",
+ "update-lerna-on-develop": "git checkout publish && git pull && cp lerna.json ../lerna-temp.json && git checkout develop && mv ../lerna-temp.json lerna.json && git commit -am 'Update lerna.json' && git push",
"watch": "lerna exec --no-sort --ignore *server --ignore *device --ignore *browser-extension --stream --parallel -- webpack --watch",
"watch-packages": "lerna exec --no-sort --scope @sample-stack/platform* --scope @sample-stack/react-shared-components --scope @sample-stack/core --stream --parallel 'webpack --watch'",
"zen:build": "cross-env NODE_ENV=production zen build",
@@ -98,32 +102,22 @@
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
- "lint-staged": {
- "*.md": [
- "yarn format:md",
- "git add"
- ],
- "*.{js,jsx,ts,tsx}": [
- "eslint --fix",
- "git add"
- ]
- },
"resolutions": {
- "@apollo/client": "~3.7.1",
+ "@apollo/client": "^3.9.0",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
- "chokidar": "^3.5.3",
"html-to-text": "^8.0.0",
- "react": "18.0.0",
- "react-dom": "18.0.0",
- "react-native-gesture-handler": "~2.5.0"
+ "react": "18.3.0-canary-c3048aab4-20240326",
+ "react-dom": "18.3.0-canary-c3048aab4-20240326",
+ "react-native": "0.72.10",
+ "react-native-gesture-handler": "~2.12.0"
},
"dependencies": {
- "dataloader": "^2.1.0",
- "graphql": "^15.0.0",
+ "graphql": "^16.0.0",
"graphql-tag": "^2.12.6"
},
"devDependencies": {
+ "@apollo/utils.keyvadapter": "^3.1.0",
"@babel/cli": "^7.19.3",
"@babel/core": "^7.20.2",
"@babel/plugin-proposal-class-properties": "^7.18.6",
@@ -151,24 +145,30 @@
"@babel/preset-typescript": "^7.18.6",
"@babel/register": "^7.18.9",
"@babel/runtime": "^7.20.1",
- "@common-stack/env-list-loader": "0.5.8",
- "@graphql-codegen/add": "^2.0.2",
- "@graphql-codegen/cli": "^1.21.8",
- "@graphql-codegen/fragment-matcher": "^2.0.1",
- "@graphql-codegen/import-types-preset": "^1.18.6",
- "@graphql-codegen/near-operation-file-preset": "^1.18.6",
- "@graphql-codegen/typescript": "^1.23.0",
- "@graphql-codegen/typescript-graphql-files-modules": "^1.18.1",
- "@graphql-codegen/typescript-operations": "^1.18.4",
- "@graphql-codegen/typescript-react-apollo": "^2.3.1",
- "@graphql-codegen/typescript-resolvers": "^1.20.0",
+ "@common-stack/env-list-loader": "5.0.6-alpha.3",
+ "@common-stack/generate-plugin": "6.0.1-alpha.0",
+ "@emotion/babel-plugin": "^11.11.0",
+ "@graphql-codegen/add": "^5.0.2",
+ "@graphql-codegen/cli": "^5.0.2",
+ "@graphql-codegen/fragment-matcher": "^5.0.2",
+ "@graphql-codegen/import-types-preset": "^3.0.0",
+ "@graphql-codegen/near-operation-file-preset": "^3.0.0",
+ "@graphql-codegen/typescript": "^4.0.6",
+ "@graphql-codegen/typescript-graphql-files-modules": "^3.0.0",
+ "@graphql-codegen/typescript-operations": "^4.2.0",
+ "@graphql-codegen/typescript-react-apollo": "^4.3.0",
+ "@graphql-codegen/typescript-resolvers": "^4.0.6",
"@loadable/babel-plugin": "^5.13.2",
"@loadable/webpack-plugin": "^5.15.2",
+ "@nx-aws-plugin/nx-aws-cache": "^3.2.2",
+ "@nx/workspace": "^19.5.1",
"@open-wc/building-rollup": "^2.0.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.8",
"@redux-devtools/core": "^3.13.1",
"@redux-devtools/dock-monitor": "^3.0.1",
"@redux-devtools/log-monitor": "^4.0.1",
+ "@remix-run/dev": "^2.9.2",
+ "@remix-run/react": "^2.9.2",
"@rollup/plugin-graphql": "2.0.2",
"@rollup/plugin-image": "^3.0.1",
"@rollup/plugin-json": "^5.0.2",
@@ -183,23 +183,18 @@
"@types/classnames": "^2.3.1",
"@types/cors": "2.8.12",
"@types/enzyme": "^3.10.12",
- "@types/express": "^4.17.14",
+ "@types/express": "^4.17.20",
"@types/hoist-non-react-statics": "^3.3.1",
- "@types/ioredis": "^5.0.0",
"@types/isomorphic-fetch": "0.0.36",
- "@types/jest": "^29.2.2",
+ "@types/jest": "^29.4.0",
"@types/lodash-es": "^4.17.6",
"@types/minimist": "^1.2.2",
- "@types/node": "^18.11.9",
+ "@types/node": "18.16.9",
"@types/prop-types": "^15.7.5",
- "@types/react": "^18.0.25",
- "@types/react-dom": "^18.0.8",
+ "@types/react": "^18.2.20",
+ "@types/react-dom": "^18.2.7",
"@types/react-helmet": "^6.1.5",
- "@types/react-loadable": "^5.5.6",
"@types/react-redux": "^7.1.24",
- "@types/react-router": "^5.1.19",
- "@types/react-router-config": "^5.0.6",
- "@types/react-router-dom": "^5.3.3",
"@types/react-test-renderer": "^18.0.0",
"@types/redux-logger": "^3.0.9",
"@types/semver": "^7.3.13",
@@ -207,13 +202,11 @@
"@types/webpack": "^5.28.0",
"@types/webpack-env": "^1.18.0",
"@types/zen-observable": "^0.8.3",
- "@typescript-eslint/eslint-plugin": "^5.42.1",
- "@typescript-eslint/eslint-plugin-tslint": "^5.42.1",
- "@typescript-eslint/parser": "^5.42.1",
+ "@typescript-eslint/eslint-plugin": "^6.7.4",
+ "@typescript-eslint/parser": "^6.7.4",
+ "@web/rollup-plugin-copy": "^0.5.1",
"@webpack-cli/serve": "^1.7.0",
- "@wojtekmaj/enzyme-adapter-react-17": "^0.7.0",
"autoprefixer": "^10.4.13",
- "awesome-typescript-loader": "^5.2.1",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^29.3.0",
@@ -232,25 +225,28 @@
"cross-env": "^7.0.3",
"css-loader": "^6.7.1",
"csstype": "^3.1.1",
- "dotenv-safe": "^8.2.0",
+ "dotenv": "^16.4.5",
+ "dotenv-esm": "^16.0.3-4",
+ "dotenv-safe": "^9.0.0",
"dotenv-webpack": "^8.0.1",
"enzyme": "^3.11.0",
"esbuild": "^0.15.13",
- "eslint": "^8.27.0",
- "eslint-config-airbnb-typescript": "^17.0.0",
- "eslint-config-prettier": "^8.5.0",
+ "esbuild-loader": "^4.0.3",
+ "eslint": "^8.38.0",
+ "eslint-config-airbnb-typescript": "^18.0.0",
+ "eslint-config-prettier": "^9.1.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-graphql": "^4.0.0",
- "eslint-plugin-import": "^2.26.0",
- "eslint-plugin-jest": "^27.1.4",
- "eslint-plugin-jsdoc": "^39.6.2",
+ "eslint-plugin-import": "^2.29.1",
+ "eslint-plugin-jest": "^28.2.0",
+ "eslint-plugin-jsdoc": "^48.2.3",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-jsonc": "^2.5.0",
- "eslint-plugin-jsx-a11y": "^6.6.1",
- "eslint-plugin-markdown": "^3.0.0",
+ "eslint-plugin-jsx-a11y": "^6.7.1",
+ "eslint-plugin-markdown": "^4.0.1",
"eslint-plugin-no-null": "^1.0.2",
- "eslint-plugin-prettier": "^4.2.1",
- "eslint-plugin-react": "^7.31.10",
+ "eslint-plugin-prettier": "^5.1.3",
+ "eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-simple-import-sort": "^8.0.0",
"express": "^4.18.2",
@@ -261,23 +257,22 @@
"html-loader": "^4.2.0",
"html-webpack-plugin": "^5.5.0",
"http-proxy-middleware": "^2.0.6",
- "husky": "^8.0.2",
+ "husky": "^9.1.5",
"ignore-loader": "^0.1.2",
"ip": "^1.1.8",
"isomorphic-style-loader": "^5.3.2",
"istanbul": "1.0.0-alpha.2",
- "jest": "^29.3.0",
+ "jest": "^29.4.1",
"jest-css-modules-transform": "^4.4.2",
"jest-dom": "^4.0.0",
"jest-junit": "^14.0.1",
"jest-matcher-utils": "^29.2.2",
- "jest-raw-loader": "^1.0.1",
"jest-transform-graphql": "^2.1.0",
"jsdom": "^20.0.2",
- "lerna": "^6.1.0",
+ "lerna": "8",
"less": "^4.1.3",
"less-loader": "^11.0.0",
- "lint-staged": "^13.0.3",
+ "lint-staged": "^15.2.7",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-webpack-plugin": "^0.11.6",
@@ -311,13 +306,14 @@
"remap-istanbul": "^0.13.0",
"resolve-url-loader": "^5.0.0",
"rimraf": "^3.0.2",
- "rollup": "^3.2.5",
- "rollup-plugin-esbuild": "^5.0.0",
+ "rollup": "^4.13.0",
+ "rollup-plugin-esbuild": "^6.1.1",
"rollup-plugin-string": "^3.0.0",
"sass-loader": "^13.1.0",
"shelljs": "^0.8.5",
"simple-git": "^3.14.1",
"sinon": "^14.0.2",
+ "sort-package-json": "^2.10.0",
"source-list-map": "^2.0.1",
"source-map-loader": "^4.0.1",
"source-map-support": "^0.5.21",
@@ -326,15 +322,12 @@
"style-loader": "^3.3.1",
"svg-url-loader": "^8.0.0",
"tcomb": "^3.2.29",
- "ts-jest": "^29.0.3",
+ "ts-jest": "^29.1.0",
"ts-loader": "^9.4.1",
"ts-node": "^10.9.1",
"tslib": "^2.4.1",
- "type-fest": "^3.2.0",
"typedoc": "^0.23.20",
- "typescript": "~4.8.4",
- "uglify-es": "^3.3.9",
- "uglifyjs-webpack-plugin": "^2.2.0",
+ "typescript": "^5.1.6",
"url-loader": "^4.1.1",
"wait-on": "^6.0.1",
"webpack": "^5.74.0",
@@ -348,10 +341,10 @@
"ws": "^8.11.0"
},
"engines": {
- "node": ">=14.17.3 < 17.0.0",
+ "node": ">=14.17.3 < 23.0.0",
"yarn": ">=1.22"
},
"cacheDirectories": [
".cache"
]
-}
\ No newline at end of file
+}
diff --git a/packages-modules/counter/browser/package.json b/packages-modules/counter/browser/package.json
index b67e6bd67..a5205225a 100755
--- a/packages-modules/counter/browser/package.json
+++ b/packages-modules/counter/browser/package.json
@@ -6,6 +6,7 @@
"author": "CDMBase LLC",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
+ "type": "module",
"scripts": {
"build": "yarn build:clean && yarn build:lib",
"build:clean": "rimraf lib",
@@ -19,17 +20,16 @@
"watch": "yarn build:lib:watch"
},
"dependencies": {
- "@sample-stack/platform-browser": "0.0.1",
+ "@sample-stack/platform-browser": "link:../../../packages/sample-platform/browser",
+ "@remix-run/react": "^2.10.3",
"antd": "~5.1.7"
},
- "devDependencies": {},
"peerDependencies": {
"@common-stack/client-react": "*",
"@rollup/plugin-graphql": "*",
"@rollup/plugin-image": "*",
"@rollup/plugin-typescript": "*",
"react": "*",
- "react-native": "*",
"react-redux": "*",
"react-router": "*",
"react-router-dom": "*",
@@ -44,4 +44,4 @@
"typescript": {
"definition": "lib/index.d.ts"
}
-}
\ No newline at end of file
+}
diff --git a/packages-modules/counter/browser/rollup.config.mjs b/packages-modules/counter/browser/rollup.config.mjs
index 78e79fc1c..d898dffb0 100644
--- a/packages-modules/counter/browser/rollup.config.mjs
+++ b/packages-modules/counter/browser/rollup.config.mjs
@@ -1,27 +1,18 @@
-import graphql from '@rollup/plugin-graphql';
-import image from '@rollup/plugin-image';
-import typescript from '@rollup/plugin-typescript';
-import { string } from 'rollup-plugin-string';
-
-const bundle = (config) => ({
- ...config,
- input: 'src/index.ts',
- // marking all node modules as external
- external: (id) => !/^[./]/.test(id),
-});
-const globals = { react: 'React' };
+import { createRollupConfig } from '../../../rollup.config.base.mjs';
+import json from '@rollup/plugin-json';
+// Define any additional plugins specific to this bundle
+const additionalPlugins = [
+ json()
+];
+// Use the createRollupConfig function to merge the base and specific configurations
export default [
- bundle({
+ createRollupConfig({
+ input: ['src/index.ts'],
plugins: [
- image(),
- graphql({
- include: '**/*.gql',
- }),
- string({
- include: '**/*.graphql',
- }),
- typescript({ noEmitOnError: true }),
+ // Spread in additional plugins specific to this config
+ ...additionalPlugins,
+
],
output: [
{
@@ -33,8 +24,8 @@ export default [
sourcemap: true,
preserveModules: true,
chunkFileNames: '[name]-[hash].[format].js',
- globals,
+ globals: { react: 'React' },
},
],
}),
-];
+];
\ No newline at end of file
diff --git a/packages-modules/counter/browser/src/apollo-server-n-client/components/CounterView.tsx b/packages-modules/counter/browser/src/apollo-server-n-client/components/CounterView.tsx
index 5beef8ce3..746d29291 100755
--- a/packages-modules/counter/browser/src/apollo-server-n-client/components/CounterView.tsx
+++ b/packages-modules/counter/browser/src/apollo-server-n-client/components/CounterView.tsx
@@ -39,9 +39,8 @@ const CounterView = ({
{renderMetaData()}
- Current counter, is {counter?.amount} and cached data. This is being stored
- server-side in the database and using Apollo subscription for
- real-time updates.
+ {`Current counter, is ${counter?.amount} and cached data. This is being stored
+ server-side in the database and using Apollo subscription for real-time updates.`}
Click to increase counter
@@ -65,9 +64,8 @@ const CounterView = ({
- Current reduxCount, is {reduxCount}. This is being stored
- client-side with Redux.
-
+ {`Current reduxCount, is ${reduxCount}. This is being stored client-side with Redux.`}
+
- Current apolloLinkStateCount, is {counterState}. This is being
- stored client-side with Apollo Link State.
-
+ {`Current apolloLinkStateCount, is ${counterState}. This is being stored client-side with Apollo Link State.`}
+
import('../common/components/Dashboard'));
-const Counter = lazy(() => import('./containers/Counter'));
-
export const counterPageStore: any[] = [
- {
- exact: false,
- icon: 'export',
- key: 'dashboard',
- component: Dashboard,
- tab: 'Apollo Server & Client',
- position: IMenuPosition.MIDDLE,
- name: 'Apollo Server & Client',
- path: '/apollo-server-n-client',
- },
- {
- key: 'counter',
- name: 'Counter',
- icon: 'appstore-o',
- component: Counter,
- position: IMenuPosition.MIDDLE,
- path: '/apollo-server-n-client/counter',
- },
+ {
+ exact: false,
+ icon: 'export',
+ key: 'dashboard',
+ component: () => import('../common/components/Dashboard'),
+ tab: 'Apollo Server',
+ position: IMenuPosition.MIDDLE,
+ name: 'Apollo Server',
+ path: '/apollo-server-n-client',
+ },
+ {
+ key: 'counter',
+ name: 'Counter',
+ icon: 'appstore-o',
+ component: () => import('./containers/Counter'),
+ position: IMenuPosition.MIDDLE,
+ path: '/apollo-server-n-client/counter',
+ },
];
const selectedRoutesAndMenus = ['dashboard', 'counter'];
diff --git a/packages-modules/counter/browser/src/apollo-server-n-client/generated-model.tsx b/packages-modules/counter/browser/src/apollo-server-n-client/generated-model.tsx
index c27ba4f05..8464d989b 100755
--- a/packages-modules/counter/browser/src/apollo-server-n-client/generated-model.tsx
+++ b/packages-modules/counter/browser/src/apollo-server-n-client/generated-model.tsx
@@ -1,27 +1,11 @@
/* tslint:disable */
import * as SchemaTypes from '../generated-models';
-import { gql } from '@apollo/client';
-import * as Apollo from '@apollo/client';
-import * as React from 'react';
-import * as ApolloReactComponents from '@apollo/client/react/components';
-export type Omit = Pick>;
-const defaultOptions = {}
+import { DocumentNode } from 'graphql';
+import * as Apollo from '@apollo/client/index.js';
+const defaultOptions = {} as const;
-export const AddCounterStateDocument = gql`
- mutation addCounterState($amount: Int!) {
- addCounterState(amount: $amount) @client {
- counter
- }
-}
- `;
-export type AddCounterStateMutationFn = Apollo.MutationFunction;
-export type AddCounterStateComponentProps = Omit, 'mutation'>;
-
- export const AddCounterStateComponent = (props: AddCounterStateComponentProps) => (
- mutation={AddCounterStateDocument} {...props} />
- );
-
+export const AddCounterStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCounterState"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"amount"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCounterState"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"amount"},"value":{"kind":"Variable","name":{"kind":"Name","value":"amount"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counter"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useAddCounterStateMutation__
@@ -47,20 +31,7 @@ export function useAddCounterStateMutation(baseOptions?: Apollo.MutationHookOpti
export type AddCounterStateMutationHookResult = ReturnType;
export type AddCounterStateMutationResult = Apollo.MutationResult;
export type AddCounterStateMutationOptions = Apollo.BaseMutationOptions;
-export const AddCounterDocument = gql`
- mutation addCounter($amount: Int!) {
- addCounter(amount: $amount) {
- amount
- }
-}
- `;
-export type AddCounterMutationFn = Apollo.MutationFunction;
-export type AddCounterComponentProps = Omit, 'mutation'>;
-
- export const AddCounterComponent = (props: AddCounterComponentProps) => (
- mutation={AddCounterDocument} {...props} />
- );
-
+export const AddCounterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCounter"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"amount"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCounter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"amount"},"value":{"kind":"Variable","name":{"kind":"Name","value":"amount"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useAddCounterMutation__
@@ -86,20 +57,7 @@ export function useAddCounterMutation(baseOptions?: Apollo.MutationHookOptions;
export type AddCounterMutationResult = Apollo.MutationResult;
export type AddCounterMutationOptions = Apollo.BaseMutationOptions;
-export const AddCounter_WsDocument = gql`
- mutation AddCounter_WS($amount: Int!) {
- addCounter(amount: $amount) {
- amount
- }
-}
- `;
-export type AddCounter_WsMutationFn = Apollo.MutationFunction;
-export type AddCounter_WsComponentProps = Omit, 'mutation'>;
-
- export const AddCounter_WsComponent = (props: AddCounter_WsComponentProps) => (
- mutation={AddCounter_WsDocument} {...props} />
- );
-
+export const AddCounter_WsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AddCounter_WS"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"amount"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCounter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"amount"},"value":{"kind":"Variable","name":{"kind":"Name","value":"amount"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useAddCounter_WsMutation__
@@ -125,18 +83,7 @@ export function useAddCounter_WsMutation(baseOptions?: Apollo.MutationHookOption
export type AddCounter_WsMutationHookResult = ReturnType;
export type AddCounter_WsMutationResult = Apollo.MutationResult;
export type AddCounter_WsMutationOptions = Apollo.BaseMutationOptions;
-export const SyncCachedCounterDocument = gql`
- mutation SyncCachedCounter {
- syncCachedCounter
-}
- `;
-export type SyncCachedCounterMutationFn = Apollo.MutationFunction;
-export type SyncCachedCounterComponentProps = Omit, 'mutation'>;
-
- export const SyncCachedCounterComponent = (props: SyncCachedCounterComponentProps) => (
- mutation={SyncCachedCounterDocument} {...props} />
- );
-
+export const SyncCachedCounterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SyncCachedCounter"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"syncCachedCounter"}}]}}]} as unknown as DocumentNode;
/**
* __useSyncCachedCounterMutation__
@@ -161,19 +108,7 @@ export function useSyncCachedCounterMutation(baseOptions?: Apollo.MutationHookOp
export type SyncCachedCounterMutationHookResult = ReturnType;
export type SyncCachedCounterMutationResult = Apollo.MutationResult;
export type SyncCachedCounterMutationOptions = Apollo.BaseMutationOptions;
-export const CounterCacheQueryDocument = gql`
- query counterCacheQuery {
- counterCache {
- amount
- }
-}
- `;
-export type CounterCacheQueryComponentProps = Omit, 'query'>;
-
- export const CounterCacheQueryComponent = (props: CounterCacheQueryComponentProps) => (
- query={CounterCacheQueryDocument} {...props} />
- );
-
+export const CounterCacheQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"counterCacheQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counterCache"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useCounterCacheQueryQuery__
@@ -198,22 +133,15 @@ export function useCounterCacheQueryLazyQuery(baseOptions?: Apollo.LazyQueryHook
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery(CounterCacheQueryDocument, options);
}
+export function useCounterCacheQuerySuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(CounterCacheQueryDocument, options);
+ }
export type CounterCacheQueryQueryHookResult = ReturnType;
export type CounterCacheQueryLazyQueryHookResult = ReturnType;
+export type CounterCacheQuerySuspenseQueryHookResult = ReturnType;
export type CounterCacheQueryQueryResult = Apollo.QueryResult;
-export const CounterStateDocument = gql`
- query CounterState {
- counterState @client {
- counter
- }
-}
- `;
-export type CounterStateComponentProps = Omit, 'query'>;
-
- export const CounterStateComponent = (props: CounterStateComponentProps) => (
- query={CounterStateDocument} {...props} />
- );
-
+export const CounterStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CounterState"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counterState"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counter"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useCounterStateQuery__
@@ -238,22 +166,15 @@ export function useCounterStateLazyQuery(baseOptions?: Apollo.LazyQueryHookOptio
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery(CounterStateDocument, options);
}
+export function useCounterStateSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(CounterStateDocument, options);
+ }
export type CounterStateQueryHookResult = ReturnType;
export type CounterStateLazyQueryHookResult = ReturnType;
+export type CounterStateSuspenseQueryHookResult = ReturnType;
export type CounterStateQueryResult = Apollo.QueryResult;
-export const CounterQueryDocument = gql`
- query counterQuery {
- counter {
- amount
- }
-}
- `;
-export type CounterQueryComponentProps = Omit, 'query'>;
-
- export const CounterQueryComponent = (props: CounterQueryComponentProps) => (
- query={CounterQueryDocument} {...props} />
- );
-
+export const CounterQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"counterQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counter"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useCounterQueryQuery__
@@ -278,22 +199,15 @@ export function useCounterQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptio
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery(CounterQueryDocument, options);
}
+export function useCounterQuerySuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(CounterQueryDocument, options);
+ }
export type CounterQueryQueryHookResult = ReturnType;
export type CounterQueryLazyQueryHookResult = ReturnType;
+export type CounterQuerySuspenseQueryHookResult = ReturnType;
export type CounterQueryQueryResult = Apollo.QueryResult;
-export const OnCounterUpdatedDocument = gql`
- subscription onCounterUpdated {
- counterUpdated {
- amount
- }
-}
- `;
-export type OnCounterUpdatedComponentProps = Omit, 'subscription'>;
-
- export const OnCounterUpdatedComponent = (props: OnCounterUpdatedComponentProps) => (
- subscription={OnCounterUpdatedDocument} {...props} />
- );
-
+export const OnCounterUpdatedDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"onCounterUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counterUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useOnCounterUpdatedSubscription__
diff --git a/packages-modules/counter/browser/src/apollo-server-n-client/graphql/__tests__/apollo-client-test-helper.ts b/packages-modules/counter/browser/src/apollo-server-n-client/graphql/__tests__/apollo-client-test-helper.ts
index 151bb08a3..90c6cc7ef 100755
--- a/packages-modules/counter/browser/src/apollo-server-n-client/graphql/__tests__/apollo-client-test-helper.ts
+++ b/packages-modules/counter/browser/src/apollo-server-n-client/graphql/__tests__/apollo-client-test-helper.ts
@@ -1,6 +1,6 @@
/* eslint-disable no-use-before-define */
/* eslint-disable import/no-extraneous-dependencies */
-import { ApolloClient, ApolloClientOptions, ApolloLink } from '@apollo/client';
+import { ApolloClient, ApolloClientOptions, ApolloLink } from '@apollo/client/index.js';
import { InMemoryCache } from '@apollo/client/cache';
// import * as schema from '../schema/schema.graphql';
import { resolvers } from '../resolvers';
diff --git a/packages-modules/counter/browser/src/apollo-server-n-client/module.tsx b/packages-modules/counter/browser/src/apollo-server-n-client/module.tsx
index 6cf1eda6b..4a6b21b1a 100755
--- a/packages-modules/counter/browser/src/apollo-server-n-client/module.tsx
+++ b/packages-modules/counter/browser/src/apollo-server-n-client/module.tsx
@@ -1,4 +1,4 @@
-import { reducers } from './redux';
+import { counterReducer } from './redux';
import { resolvers, stateDefault } from './graphql';
import { Feature } from '@common-stack/client-react';
@@ -7,6 +7,6 @@ import { filteredMenus, filteredRoutes } from './compute';
export default new Feature({
menuConfig: filteredMenus,
routeConfig: filteredRoutes,
- reducer: { counter: reducers },
+ reducer: { counter: counterReducer },
clientStateParams: { resolvers, defaults: [stateDefault] },
});
diff --git a/packages-modules/counter/browser/src/apollo-server-n-client/redux/reducers/index.ts b/packages-modules/counter/browser/src/apollo-server-n-client/redux/reducers/index.ts
index bc46ec54e..c60613602 100755
--- a/packages-modules/counter/browser/src/apollo-server-n-client/redux/reducers/index.ts
+++ b/packages-modules/counter/browser/src/apollo-server-n-client/redux/reducers/index.ts
@@ -1,16 +1,31 @@
-const defaultState = {
+// Import createSlice from Redux Toolkit
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import type * as rtk from "@reduxjs/toolkit";
+
+// Define the initial state type
+interface DefaultState {
+ reduxCount: number;
+}
+
+// Define the initial state
+const initialState: DefaultState = {
reduxCount: 1,
};
-export const reducers = function (state = defaultState, action) {
- switch (action.type) {
- case 'COUNTER_INCREMENT':
- return {
- ...state,
- reduxCount: state.reduxCount + action.value,
- };
+// Create the slice
+const counterSlice = createSlice({
+ name: 'counter', // the name of your slice, used in action types
+ initialState,
+ reducers: {
+ // Define the reducer and automatically generate associated action
+ increment: (state, action: PayloadAction) => {
+ state.reduxCount += action.payload; // Immer allows us to "mutate" the state
+ },
+ },
+});
- default:
- return state;
- }
-};
+// Export the reducer, generated from the slice
+export const counterReducer = counterSlice.reducer;
+
+// Export the action creators
+export const { increment } = counterSlice.actions;
diff --git a/packages-modules/counter/browser/src/common/components/Dashboard.tsx b/packages-modules/counter/browser/src/common/components/Dashboard.tsx
index f1ce50960..930cc5f64 100755
--- a/packages-modules/counter/browser/src/common/components/Dashboard.tsx
+++ b/packages-modules/counter/browser/src/common/components/Dashboard.tsx
@@ -1,4 +1,4 @@
-import * as React from 'react';
-import { renderRoutes } from 'react-router-config';
+import { Outlet } from "@remix-run/react";
+// import { renderRoutes2 as renderRoutes } from '@common-stack/client-react';
-export default (props) => <>{renderRoutes(props.route.routes, { matchPath: props.route.path })}>;
+export default (props) => <>Dashboard >;
diff --git a/packages-modules/counter/browser/src/common/components/Wrapper.tsx b/packages-modules/counter/browser/src/common/components/Wrapper.tsx
new file mode 100644
index 000000000..c1c2d4e0c
--- /dev/null
+++ b/packages-modules/counter/browser/src/common/components/Wrapper.tsx
@@ -0,0 +1,3 @@
+export const authWrapper = (Component: React.ReactElement, props: Record) => {
+ return <>-- auth wrapped -- {Component}>;
+}
diff --git a/packages-modules/counter/browser/src/common/compute.tsx b/packages-modules/counter/browser/src/common/compute.tsx
index eec4925ce..87c3eb9d3 100755
--- a/packages-modules/counter/browser/src/common/compute.tsx
+++ b/packages-modules/counter/browser/src/common/compute.tsx
@@ -1,18 +1,15 @@
-import * as React from 'react';
import { IMenuPosition } from '@common-stack/client-react';
-import { lazy } from '@loadable/component'
import { getFilteredMenus, getFilteredRoutes } from '../utils';
-const Home = lazy(() => import('../common/components/Home'));
-
export const commonPageStore: any[] = [
{
path: '/',
key: 'home',
- exact: true,
+ exact: false,
name: 'Home',
- component: Home,
+ component: () => import('../common/components/Home'),
+ wrapper: () => import('../common/components/Wrapper'),
position: IMenuPosition.MIDDLE,
},
];
diff --git a/packages-modules/counter/browser/src/common/interfaces/context.ts b/packages-modules/counter/browser/src/common/interfaces/context.ts
index acb8051de..85f0ff167 100755
--- a/packages-modules/counter/browser/src/common/interfaces/context.ts
+++ b/packages-modules/counter/browser/src/common/interfaces/context.ts
@@ -1,5 +1,5 @@
import { DataProxy } from '@apollo/client/cache';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
export interface MyContext {
cache: DataProxy;
diff --git a/packages-modules/counter/browser/src/compute-ref.ts b/packages-modules/counter/browser/src/compute-ref.ts
new file mode 100644
index 000000000..4c32275d3
--- /dev/null
+++ b/packages-modules/counter/browser/src/compute-ref.ts
@@ -0,0 +1,4 @@
+// import './apollo-server-n-client/compute';
+// import './common/compute';
+import './redux-first-history/compute';
+// import './emotion/compute';
diff --git a/packages-modules/counter/browser/src/connected-react-router/components/HelloChild.tsx b/packages-modules/counter/browser/src/connected-react-router/components/HelloChild.tsx
deleted file mode 100755
index c1aac8cfa..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/components/HelloChild.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-
-import * as React from 'react';
-import { connect } from 'react-redux';
-import { Link } from 'react-router-dom';
-import { State } from '../interfaces';
-import { CONNECTED_REACT_ROUTER_ROUTES_TYPES } from '../constants';
-
-interface HelloChildProps {
- pathname: string;
- search: string;
- hash: string;
-}
-
-const HelloChildComponent = ({ pathname, search, hash }: HelloChildProps) => (
-
- Hello-Child 23423
-
- with query string
- with hash
-
-
- pathname: {pathname}
-
-
- search: {search}
-
-
- hash: {hash}
-
-
-);
-
-const mapStateToProps = (state: State) => ({
- pathname: state.router.location.pathname,
- search: state.router.location.search,
- hash: state.router.location.hash,
-});
-
-export const HelloChild = connect(mapStateToProps)(HelloChildComponent);
diff --git a/packages-modules/counter/browser/src/connected-react-router/constants/action-types.ts b/packages-modules/counter/browser/src/connected-react-router/constants/action-types.ts
deleted file mode 100755
index f73efec22..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/constants/action-types.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const enum CONNECTED_REACT_ROUTER_ACTION_TYPES {
- INCREMENT = '@connected-react-router/INCREMENT',
- DECREMENT = '@connected-react-router/DECREMENT',
-}
diff --git a/packages-modules/counter/browser/src/connected-react-router/constants/routes-types.ts b/packages-modules/counter/browser/src/connected-react-router/constants/routes-types.ts
deleted file mode 100755
index b4694d0de..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/constants/routes-types.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export enum CONNECTED_REACT_ROUTER_ROUTES_TYPES {
- ROOT = '/',
- HOME = '/connected-react-router',
- HELLO = '/connected-react-router/hello',
- COUNTER = '/connected-react-router/counter',
-}
diff --git a/packages-modules/counter/browser/src/connected-react-router/interfaces/state.ts b/packages-modules/counter/browser/src/connected-react-router/interfaces/state.ts
deleted file mode 100755
index f5de723d6..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/interfaces/state.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { RouterState } from 'connected-react-router';
-
-export interface State {
- connectedReactRouterCounter: number;
- router: RouterState;
-}
diff --git a/packages-modules/counter/browser/src/connected-react-router/redux/actions/counter.ts b/packages-modules/counter/browser/src/connected-react-router/redux/actions/counter.ts
deleted file mode 100755
index bbdeb5027..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/redux/actions/counter.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '../../constants';
-
-export const increment = () => ({
- type: CONNECTED_REACT_ROUTER_ACTION_TYPES.INCREMENT,
-});
-
-export const decrement = () => ({
- type: CONNECTED_REACT_ROUTER_ACTION_TYPES.DECREMENT,
-});
diff --git a/packages-modules/counter/browser/src/connected-react-router/redux/actions/index.ts b/packages-modules/counter/browser/src/connected-react-router/redux/actions/index.ts
deleted file mode 100755
index 0ab63758b..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/redux/actions/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './counter';
diff --git a/packages-modules/counter/browser/src/connected-react-router/redux/index.ts b/packages-modules/counter/browser/src/connected-react-router/redux/index.ts
deleted file mode 100755
index 43988367b..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/redux/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './actions';
-export * from './reducers';
diff --git a/packages-modules/counter/browser/src/connected-react-router/redux/reducers/counter.ts b/packages-modules/counter/browser/src/connected-react-router/redux/reducers/counter.ts
deleted file mode 100755
index ca8c85332..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/redux/reducers/counter.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Action } from 'redux';
-import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '../../constants';
-
-const connectedReactRouterCounter = (state = 0, action: Action) => {
- switch (action.type) {
- case CONNECTED_REACT_ROUTER_ACTION_TYPES.INCREMENT:
- return state + 1;
- case CONNECTED_REACT_ROUTER_ACTION_TYPES.DECREMENT:
- return state - 1;
- default:
- return state;
- }
-};
-
-export { connectedReactRouterCounter };
diff --git a/packages-modules/counter/browser/src/connected-react-router/redux/reducers/index.ts b/packages-modules/counter/browser/src/connected-react-router/redux/reducers/index.ts
deleted file mode 100755
index 0ab63758b..000000000
--- a/packages-modules/counter/browser/src/connected-react-router/redux/reducers/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './counter';
diff --git a/packages-modules/counter/browser/src/emotion/compute.tsx b/packages-modules/counter/browser/src/emotion/compute.tsx
index ec67b9af4..ac6acba45 100755
--- a/packages-modules/counter/browser/src/emotion/compute.tsx
+++ b/packages-modules/counter/browser/src/emotion/compute.tsx
@@ -1,19 +1,15 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
-import * as React from 'react';
import { IMenuPosition } from '@common-stack/client-react';
-import { lazy } from '@loadable/component'
import { getFilteredMenus, getFilteredRoutes } from '../utils';
-const ComplexWithTheme = lazy(() => import('./components/CompledWithTheme'));
-
export const emotionPageStore: any[] = [
{
- component: ComplexWithTheme,
tab: 'Emotion Styling',
key: 'emotion',
position: IMenuPosition.MIDDLE,
name: 'Emotion Styling',
+ component: () => import('./components/CompledWithTheme'),
path: '/emotion',
},
];
diff --git a/packages-modules/counter/browser/src/epics/locationEpic.ts b/packages-modules/counter/browser/src/epics/locationEpic.ts
new file mode 100644
index 000000000..5ddf6ebd5
--- /dev/null
+++ b/packages-modules/counter/browser/src/epics/locationEpic.ts
@@ -0,0 +1,14 @@
+import { ofType } from 'redux-observable';
+import { map, tap } from 'rxjs/operators/index.js';
+import { LOCATION_CHANGE } from '@common-stack/remix-router-redux';
+
+// Assuming LOCATION_CHANGE action type and a dummy action creator for demonstration
+// const LOCATION_CHANGE = 'LOCATION_CHANGE';
+const dummyAction = () => ({ type: 'DUMMY_ACTION' });
+
+export const locationChangeEpic = (action$) =>
+ action$.pipe(
+ ofType(LOCATION_CHANGE),
+ tap(() => console.log('Location changed!')), // Side effect: logging to the console
+ map(() => dummyAction()), // Dispatch a dummy action (replace with your actual follow-up action)
+ );
diff --git a/packages-modules/counter/browser/src/epics/module.ts b/packages-modules/counter/browser/src/epics/module.ts
new file mode 100755
index 000000000..ab0b93e23
--- /dev/null
+++ b/packages-modules/counter/browser/src/epics/module.ts
@@ -0,0 +1,7 @@
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import { Feature } from '@common-stack/client-react';
+import { locationChangeEpic } from './locationEpic';
+
+export default new Feature({
+ epic: [locationChangeEpic],
+});
diff --git a/packages-modules/counter/browser/src/generated-models.ts b/packages-modules/counter/browser/src/generated-models.ts
index 838d24835..f9a8dcc2c 100755
--- a/packages-modules/counter/browser/src/generated-models.ts
+++ b/packages-modules/counter/browser/src/generated-models.ts
@@ -1,32 +1,35 @@
/* tslint:disable */
import { GraphQLResolveInfo } from 'graphql';
-import { gql } from '@apollo/client';
-import * as Apollo from '@apollo/client';
+import { DocumentNode } from 'graphql';
+import * as Apollo from '@apollo/client/index.js';
export type Maybe = T | null;
+export type InputMaybe = Maybe;
export type Exact = { [K in keyof T]: T[K] };
export type MakeOptional = Omit & { [SubKey in K]?: Maybe };
export type MakeMaybe = Omit & { [SubKey in K]: Maybe };
-export type RequireFields = { [X in Exclude]?: T[X] } & { [P in K]-?: NonNullable };
-const defaultOptions = {}
+export type MakeEmpty = { [_ in K]?: never };
+export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
+export type RequireFields = Omit & { [P in K]-?: NonNullable };
+const defaultOptions = {} as const;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
- ID: string;
- String: string;
- Boolean: boolean;
- Int: number;
- Float: number;
+ ID: { input: string; output: string; }
+ String: { input: string; output: string; }
+ Boolean: { input: boolean; output: boolean; }
+ Int: { input: number; output: number; }
+ Float: { input: number; output: number; }
};
export type ClientCounter = {
__typename?: 'ClientCounter';
- counter?: Maybe;
+ counter?: Maybe;
};
/** Database counter */
export type Counter = {
__typename?: 'Counter';
/** Current amount */
- amount: Scalars['Int'];
+ amount: Scalars['Int']['output'];
};
export type Mutation = {
@@ -37,22 +40,22 @@ export type Mutation = {
/** add Counter */
addMoleculerCounter?: Maybe;
/** sync cached counter with current value */
- syncCachedCounter?: Maybe;
+ syncCachedCounter?: Maybe;
};
export type MutationAddCounterArgs = {
- amount?: Maybe;
+ amount?: InputMaybe;
};
export type MutationAddCounterStateArgs = {
- amount: Scalars['Int'];
+ amount: Scalars['Int']['input'];
};
export type MutationAddMoleculerCounterArgs = {
- amount?: Maybe;
+ amount?: InputMaybe;
};
export type Query = {
@@ -74,95 +77,50 @@ export type Subscription = {
};
export type AddCounterStateMutationVariables = Exact<{
- amount: Scalars['Int'];
+ amount: Scalars['Int']['input'];
}>;
-export type AddCounterStateMutation = (
- { __typename?: 'Mutation' }
- & { addCounterState?: Maybe<(
- { __typename?: 'ClientCounter' }
- & Pick
- )> }
-);
+export type AddCounterStateMutation = { __typename?: 'Mutation', addCounterState?: { __typename?: 'ClientCounter', counter?: number | null } | null };
export type AddCounterMutationVariables = Exact<{
- amount: Scalars['Int'];
+ amount: Scalars['Int']['input'];
}>;
-export type AddCounterMutation = (
- { __typename?: 'Mutation' }
- & { addCounter?: Maybe<(
- { __typename?: 'Counter' }
- & Pick
- )> }
-);
+export type AddCounterMutation = { __typename?: 'Mutation', addCounter?: { __typename?: 'Counter', amount: number } | null };
export type AddCounter_WsMutationVariables = Exact<{
- amount: Scalars['Int'];
+ amount: Scalars['Int']['input'];
}>;
-export type AddCounter_WsMutation = (
- { __typename?: 'Mutation' }
- & { addCounter?: Maybe<(
- { __typename?: 'Counter' }
- & Pick
- )> }
-);
+export type AddCounter_WsMutation = { __typename?: 'Mutation', addCounter?: { __typename?: 'Counter', amount: number } | null };
export type SyncCachedCounterMutationVariables = Exact<{ [key: string]: never; }>;
-export type SyncCachedCounterMutation = (
- { __typename?: 'Mutation' }
- & Pick
-);
+export type SyncCachedCounterMutation = { __typename?: 'Mutation', syncCachedCounter?: boolean | null };
export type CounterCacheQueryQueryVariables = Exact<{ [key: string]: never; }>;
-export type CounterCacheQueryQuery = (
- { __typename?: 'Query' }
- & { counterCache?: Maybe<(
- { __typename?: 'Counter' }
- & Pick
- )> }
-);
+export type CounterCacheQueryQuery = { __typename?: 'Query', counterCache?: { __typename?: 'Counter', amount: number } | null };
export type CounterStateQueryVariables = Exact<{ [key: string]: never; }>;
-export type CounterStateQuery = (
- { __typename?: 'Query' }
- & { counterState?: Maybe<(
- { __typename?: 'ClientCounter' }
- & Pick
- )> }
-);
+export type CounterStateQuery = { __typename?: 'Query', counterState?: { __typename?: 'ClientCounter', counter?: number | null } | null };
export type CounterQueryQueryVariables = Exact<{ [key: string]: never; }>;
-export type CounterQueryQuery = (
- { __typename?: 'Query' }
- & { counter?: Maybe<(
- { __typename?: 'Counter' }
- & Pick
- )> }
-);
+export type CounterQueryQuery = { __typename?: 'Query', counter?: { __typename?: 'Counter', amount: number } | null };
export type OnCounterUpdatedSubscriptionVariables = Exact<{ [key: string]: never; }>;
-export type OnCounterUpdatedSubscription = (
- { __typename?: 'Subscription' }
- & { counterUpdated?: Maybe<(
- { __typename?: 'Counter' }
- & Pick
- )> }
-);
+export type OnCounterUpdatedSubscription = { __typename?: 'Subscription', counterUpdated?: { __typename?: 'Counter', amount: number } | null };
@@ -172,21 +130,7 @@ export type ResolverTypeWrapper = Promise | T;
export type ResolverWithResolve = {
resolve: ResolverFn;
};
-
-export type LegacyStitchingResolver = {
- fragment: string;
- resolve: ResolverFn;
-};
-
-export type NewStitchingResolver = {
- selectionSet: string;
- resolve: ResolverFn;
-};
-export type StitchingResolver = LegacyStitchingResolver | NewStitchingResolver;
-export type Resolver =
- | ResolverFn
- | ResolverWithResolve
- | StitchingResolver;
+export type Resolver = ResolverFn | ResolverWithResolve;
export type ResolverFn = (
parent: TParent,
@@ -200,7 +144,7 @@ export type SubscriptionSubscribeFn = (
args: TArgs,
context: TContext,
info: GraphQLResolveInfo
-) => AsyncIterator | Promise>;
+) => AsyncIterable | Promise>;
export type SubscriptionResolveFn = (
parent: TParent,
@@ -245,28 +189,30 @@ export type DirectiveResolverFn TResult | Promise;
+
+
/** Mapping between all available schema types and the resolvers types */
export type ResolversTypes = {
- Query: ResolverTypeWrapper<{}>;
- Counter: ResolverTypeWrapper;
- Int: ResolverTypeWrapper;
+ Boolean: ResolverTypeWrapper;
ClientCounter: ResolverTypeWrapper;
+ Counter: ResolverTypeWrapper;
+ Int: ResolverTypeWrapper;
Mutation: ResolverTypeWrapper<{}>;
- Boolean: ResolverTypeWrapper;
+ Query: ResolverTypeWrapper<{}>;
+ String: ResolverTypeWrapper;
Subscription: ResolverTypeWrapper<{}>;
- String: ResolverTypeWrapper;
};
/** Mapping between all available schema types and the resolvers parents */
export type ResolversParentTypes = {
- Query: {};
- Counter: Counter;
- Int: Scalars['Int'];
+ Boolean: Scalars['Boolean']['output'];
ClientCounter: ClientCounter;
+ Counter: Counter;
+ Int: Scalars['Int']['output'];
Mutation: {};
- Boolean: Scalars['Boolean'];
+ Query: {};
+ String: Scalars['String']['output'];
Subscription: {};
- String: Scalars['String'];
};
export type ClientCounterResolvers = {
@@ -280,9 +226,9 @@ export type CounterResolvers = {
- addCounter?: Resolver, ParentType, ContextType, RequireFields>;
+ addCounter?: Resolver, ParentType, ContextType, Partial>;
addCounterState?: Resolver, ParentType, ContextType, RequireFields>;
- addMoleculerCounter?: Resolver, ParentType, ContextType, RequireFields>;
+ addMoleculerCounter?: Resolver, ParentType, ContextType, Partial>;
syncCachedCounter?: Resolver, ParentType, ContextType>;
};
@@ -307,20 +253,8 @@ export type Resolvers = {
};
-/**
- * @deprecated
- * Use "Resolvers" root object instead. If you wish to get "IResolvers", add "typesPrefix: I" to your config.
- */
-export type IResolvers = Resolvers;
-
-export const AddCounterStateDocument = gql`
- mutation addCounterState($amount: Int!) {
- addCounterState(amount: $amount) @client {
- counter
- }
-}
- `;
+export const AddCounterStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCounterState"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"amount"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCounterState"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"amount"},"value":{"kind":"Variable","name":{"kind":"Name","value":"amount"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counter"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useAddCounterStateMutation__
@@ -346,13 +280,7 @@ export function useAddCounterStateMutation(baseOptions?: Apollo.MutationHookOpti
export type AddCounterStateMutationHookResult = ReturnType;
export type AddCounterStateMutationResult = Apollo.MutationResult;
export type AddCounterStateMutationOptions = Apollo.BaseMutationOptions;
-export const AddCounterDocument = gql`
- mutation addCounter($amount: Int!) {
- addCounter(amount: $amount) {
- amount
- }
-}
- `;
+export const AddCounterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"addCounter"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"amount"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCounter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"amount"},"value":{"kind":"Variable","name":{"kind":"Name","value":"amount"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useAddCounterMutation__
@@ -378,13 +306,7 @@ export function useAddCounterMutation(baseOptions?: Apollo.MutationHookOptions;
export type AddCounterMutationResult = Apollo.MutationResult;
export type AddCounterMutationOptions = Apollo.BaseMutationOptions;
-export const AddCounter_WsDocument = gql`
- mutation AddCounter_WS($amount: Int!) {
- addCounter(amount: $amount) {
- amount
- }
-}
- `;
+export const AddCounter_WsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AddCounter_WS"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"amount"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addCounter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"amount"},"value":{"kind":"Variable","name":{"kind":"Name","value":"amount"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useAddCounter_WsMutation__
@@ -410,11 +332,7 @@ export function useAddCounter_WsMutation(baseOptions?: Apollo.MutationHookOption
export type AddCounter_WsMutationHookResult = ReturnType;
export type AddCounter_WsMutationResult = Apollo.MutationResult;
export type AddCounter_WsMutationOptions = Apollo.BaseMutationOptions;
-export const SyncCachedCounterDocument = gql`
- mutation SyncCachedCounter {
- syncCachedCounter
-}
- `;
+export const SyncCachedCounterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SyncCachedCounter"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"syncCachedCounter"}}]}}]} as unknown as DocumentNode;
/**
* __useSyncCachedCounterMutation__
@@ -439,13 +357,7 @@ export function useSyncCachedCounterMutation(baseOptions?: Apollo.MutationHookOp
export type SyncCachedCounterMutationHookResult = ReturnType;
export type SyncCachedCounterMutationResult = Apollo.MutationResult;
export type SyncCachedCounterMutationOptions = Apollo.BaseMutationOptions;
-export const CounterCacheQueryDocument = gql`
- query counterCacheQuery {
- counterCache {
- amount
- }
-}
- `;
+export const CounterCacheQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"counterCacheQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counterCache"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useCounterCacheQueryQuery__
@@ -470,16 +382,15 @@ export function useCounterCacheQueryLazyQuery(baseOptions?: Apollo.LazyQueryHook
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery(CounterCacheQueryDocument, options);
}
+export function useCounterCacheQuerySuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(CounterCacheQueryDocument, options);
+ }
export type CounterCacheQueryQueryHookResult = ReturnType;
export type CounterCacheQueryLazyQueryHookResult = ReturnType;
+export type CounterCacheQuerySuspenseQueryHookResult = ReturnType;
export type CounterCacheQueryQueryResult = Apollo.QueryResult;
-export const CounterStateDocument = gql`
- query CounterState {
- counterState @client {
- counter
- }
-}
- `;
+export const CounterStateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CounterState"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counterState"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counter"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useCounterStateQuery__
@@ -504,16 +415,15 @@ export function useCounterStateLazyQuery(baseOptions?: Apollo.LazyQueryHookOptio
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery(CounterStateDocument, options);
}
+export function useCounterStateSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(CounterStateDocument, options);
+ }
export type CounterStateQueryHookResult = ReturnType;
export type CounterStateLazyQueryHookResult = ReturnType;
+export type CounterStateSuspenseQueryHookResult = ReturnType;
export type CounterStateQueryResult = Apollo.QueryResult;
-export const CounterQueryDocument = gql`
- query counterQuery {
- counter {
- amount
- }
-}
- `;
+export const CounterQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"counterQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counter"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useCounterQueryQuery__
@@ -538,16 +448,15 @@ export function useCounterQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptio
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery(CounterQueryDocument, options);
}
+export function useCounterQuerySuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useSuspenseQuery(CounterQueryDocument, options);
+ }
export type CounterQueryQueryHookResult = ReturnType;
export type CounterQueryLazyQueryHookResult = ReturnType;
+export type CounterQuerySuspenseQueryHookResult = ReturnType;
export type CounterQueryQueryResult = Apollo.QueryResult;
-export const OnCounterUpdatedDocument = gql`
- subscription onCounterUpdated {
- counterUpdated {
- amount
- }
-}
- `;
+export const OnCounterUpdatedDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"onCounterUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"counterUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}}]}}]} as unknown as DocumentNode;
/**
* __useOnCounterUpdatedSubscription__
diff --git a/packages-modules/counter/browser/src/index.ts b/packages-modules/counter/browser/src/index.ts
index 8a83c5ff2..b2a18e8d5 100755
--- a/packages-modules/counter/browser/src/index.ts
+++ b/packages-modules/counter/browser/src/index.ts
@@ -2,9 +2,10 @@ import { Feature } from '@common-stack/client-react';
import Common from './common';
import ApolloCounter from './apollo-server-n-client';
-import ConnectedReactRouter from './connected-react-router';
+import ReduxFirstHistory from './redux-first-history';
+import EpicModule from './epics/module';
import emotion from './emotion';
-import { ElectronTrayModule } from './connected-react-router/index.electron';
-
-export default new Feature(Common, ConnectedReactRouter, ApolloCounter, emotion);
-export { ElectronTrayModule };
+// import { ElectronTrayModule } from './redux-first-history/index.electron';
+export * from './generated-models';
+export default new Feature(Common, ReduxFirstHistory, ApolloCounter, emotion, EpicModule);
+// export { ElectronTrayModule };
diff --git a/packages-modules/counter/browser/src/connected-react-router/README.md b/packages-modules/counter/browser/src/redux-first-history/README.md
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/README.md
rename to packages-modules/counter/browser/src/redux-first-history/README.md
diff --git a/packages-modules/counter/browser/src/connected-react-router/__tests__/__snapshots__/connected-react-router-module.test.ts.snap b/packages-modules/counter/browser/src/redux-first-history/__tests__/__snapshots__/connected-react-router-module.test.ts.snap
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/__tests__/__snapshots__/connected-react-router-module.test.ts.snap
rename to packages-modules/counter/browser/src/redux-first-history/__tests__/__snapshots__/connected-react-router-module.test.ts.snap
diff --git a/packages-modules/counter/browser/src/connected-react-router/__tests__/connected-react-router-module.test.ts b/packages-modules/counter/browser/src/redux-first-history/__tests__/connected-react-router-module.test.ts
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/__tests__/connected-react-router-module.test.ts
rename to packages-modules/counter/browser/src/redux-first-history/__tests__/connected-react-router-module.test.ts
diff --git a/packages-modules/counter/browser/src/connected-react-router/components/Counter.tsx b/packages-modules/counter/browser/src/redux-first-history/components/Counter.tsx
similarity index 61%
rename from packages-modules/counter/browser/src/connected-react-router/components/Counter.tsx
rename to packages-modules/counter/browser/src/redux-first-history/components/Counter.tsx
index 16f1a4519..bacf0ccc8 100755
--- a/packages-modules/counter/browser/src/connected-react-router/components/Counter.tsx
+++ b/packages-modules/counter/browser/src/redux-first-history/components/Counter.tsx
@@ -1,18 +1,24 @@
/* eslint-disable react/button-has-type */
import * as React from 'react';
import { Dispatch } from 'redux';
-import { connect } from 'react-redux';
-import { RouteComponentProps } from 'react-router';
+import { connect, useDispatch } from 'react-redux';
+import { LOCATION_CHANGE } from '@common-stack/remix-router-redux';
import { increment, decrement } from '../redux';
import { State } from '../interfaces';
-const CounterComponent: React.FC = (props) => (
-
- Counter: {props.count}
- +
- -
-
-);
+const CounterComponent: React.FC = (props) => {
+ const dispatch = useDispatch();
+
+ return (
+
+
+ {`Counter: ${props.count}`}
+ dispatch({type: LOCATION_CHANGE, payload: {}})}>ROUTER
+ +
+ -
+
+ )
+};
interface StateProps {
count: number;
diff --git a/packages-modules/counter/browser/src/connected-react-router/components/Hello.tsx b/packages-modules/counter/browser/src/redux-first-history/components/Hello.tsx
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/components/Hello.tsx
rename to packages-modules/counter/browser/src/redux-first-history/components/Hello.tsx
diff --git a/packages-modules/counter/browser/src/redux-first-history/components/HelloChild.tsx b/packages-modules/counter/browser/src/redux-first-history/components/HelloChild.tsx
new file mode 100755
index 000000000..fbb25a9ae
--- /dev/null
+++ b/packages-modules/counter/browser/src/redux-first-history/components/HelloChild.tsx
@@ -0,0 +1,27 @@
+
+import * as React from 'react';
+import { useLocation, Link } from 'react-router-dom';
+import { CONNECTED_REACT_ROUTER_ROUTES_TYPES } from '../constants';
+
+export const HelloChild = () => {
+ const { pathname, search, hash } = useLocation();
+
+ return (
+
+ Hello-Child
+
+ with query string
+ with hash
+
+
+ pathname: {pathname}
+
+
+ search: {search}
+
+
+ hash: {hash}
+
+
+ );
+}
diff --git a/packages-modules/counter/browser/src/connected-react-router/components/Home.tsx b/packages-modules/counter/browser/src/redux-first-history/components/Home.tsx
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/components/Home.tsx
rename to packages-modules/counter/browser/src/redux-first-history/components/Home.tsx
diff --git a/packages-modules/counter/browser/src/connected-react-router/components/NavBar.tsx b/packages-modules/counter/browser/src/redux-first-history/components/NavBar.tsx
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/components/NavBar.tsx
rename to packages-modules/counter/browser/src/redux-first-history/components/NavBar.tsx
diff --git a/packages-modules/counter/browser/src/connected-react-router/components/NoMatch.tsx b/packages-modules/counter/browser/src/redux-first-history/components/NoMatch.tsx
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/components/NoMatch.tsx
rename to packages-modules/counter/browser/src/redux-first-history/components/NoMatch.tsx
diff --git a/packages-modules/counter/browser/src/connected-react-router/compute.tsx b/packages-modules/counter/browser/src/redux-first-history/compute.tsx
similarity index 60%
rename from packages-modules/counter/browser/src/connected-react-router/compute.tsx
rename to packages-modules/counter/browser/src/redux-first-history/compute.tsx
index 922c0e86a..81c59e29e 100755
--- a/packages-modules/counter/browser/src/connected-react-router/compute.tsx
+++ b/packages-modules/counter/browser/src/redux-first-history/compute.tsx
@@ -1,32 +1,25 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
-import * as React from 'react';
import { IMenuPosition, IRoute } from '@common-stack/client-react';
-import { lazy } from '@loadable/component'
-import { getFilteredMenus, getFilteredRoutes } from '../utils';
+import { getFilteredMenus, getFilteredRoutes } from '../utils/menu';
import { CONNECTED_REACT_ROUTER_ROUTES_TYPES } from './constants';
-
-const Dashboard = lazy(() => import('../common/components/Dashboard'));
-const Counter = lazy(() => import('./components/Counter'));
-const Hello = lazy(() => import('./components/Hello'));
-
-export const counterPageStore: IRoute[] = [
- {
- exact: false,
- icon: 'export',
- component: Dashboard,
- position: IMenuPosition.MIDDLE,
- name: 'Connected React Router',
- key: CONNECTED_REACT_ROUTER_ROUTES_TYPES.HOME,
- path: CONNECTED_REACT_ROUTER_ROUTES_TYPES.HOME,
- },
+export const counterPageStore = [
+ // {
+ // exact: false,
+ // icon: 'export',
+ // component: () => import('../common/components/Dashboard'),
+ // position: IMenuPosition.MIDDLE,
+ // name: 'Redux First History',
+ // key: CONNECTED_REACT_ROUTER_ROUTES_TYPES.HOME,
+ // path: CONNECTED_REACT_ROUTER_ROUTES_TYPES.HOME,
+ // },
{
exact: true,
icon: 'export',
name: 'Hello',
- component: Hello,
+ component: () => import('./components/Hello'),
position: IMenuPosition.MIDDLE,
key: CONNECTED_REACT_ROUTER_ROUTES_TYPES.HELLO,
path: CONNECTED_REACT_ROUTER_ROUTES_TYPES.HELLO,
@@ -35,7 +28,7 @@ export const counterPageStore: IRoute[] = [
exact: true,
icon: 'export',
name: 'Counter',
- component: Counter,
+ component: () => import('./components/Counter'),
position: IMenuPosition.MIDDLE,
key: CONNECTED_REACT_ROUTER_ROUTES_TYPES.COUNTER,
path: CONNECTED_REACT_ROUTER_ROUTES_TYPES.COUNTER,
diff --git a/packages-modules/counter/browser/src/redux-first-history/constants/action-types.ts b/packages-modules/counter/browser/src/redux-first-history/constants/action-types.ts
new file mode 100755
index 000000000..c76427a70
--- /dev/null
+++ b/packages-modules/counter/browser/src/redux-first-history/constants/action-types.ts
@@ -0,0 +1,4 @@
+export const enum CONNECTED_REACT_ROUTER_ACTION_TYPES {
+ INCREMENT = '@redux-first-history/INCREMENT',
+ DECREMENT = '@redux-first-history/DECREMENT',
+}
diff --git a/packages-modules/counter/browser/src/connected-react-router/constants/index.ts b/packages-modules/counter/browser/src/redux-first-history/constants/index.ts
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/constants/index.ts
rename to packages-modules/counter/browser/src/redux-first-history/constants/index.ts
diff --git a/packages-modules/counter/browser/src/redux-first-history/constants/routes-types.ts b/packages-modules/counter/browser/src/redux-first-history/constants/routes-types.ts
new file mode 100755
index 000000000..89ec17f63
--- /dev/null
+++ b/packages-modules/counter/browser/src/redux-first-history/constants/routes-types.ts
@@ -0,0 +1,6 @@
+export enum CONNECTED_REACT_ROUTER_ROUTES_TYPES {
+ ROOT = '/',
+ HOME = '/redux-first-history',
+ HELLO = '/redux-first-history/hello',
+ COUNTER = '/redux-first-history/counter',
+}
diff --git a/packages-modules/counter/browser/src/connected-react-router/electron-module.tsx b/packages-modules/counter/browser/src/redux-first-history/electron-module.tsx
similarity index 94%
rename from packages-modules/counter/browser/src/connected-react-router/electron-module.tsx
rename to packages-modules/counter/browser/src/redux-first-history/electron-module.tsx
index c719458db..1034328fe 100644
--- a/packages-modules/counter/browser/src/connected-react-router/electron-module.tsx
+++ b/packages-modules/counter/browser/src/redux-first-history/electron-module.tsx
@@ -2,7 +2,7 @@
import { Feature } from '@common-stack/client-react';
import { IMenuPosition, IRoute } from '@common-stack/client-react';
import Counter from './components/Counter';
-import { connectedReactRouterCounter } from './redux';
+import connectedReactRouterCounter from './redux';
import { CONNECTED_REACT_ROUTER_ROUTES_TYPES } from './constants';
import { getFilteredRoutes } from '../utils';
diff --git a/packages-modules/counter/browser/src/connected-react-router/index.electron.ts b/packages-modules/counter/browser/src/redux-first-history/index.electron.ts
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/index.electron.ts
rename to packages-modules/counter/browser/src/redux-first-history/index.electron.ts
diff --git a/packages-modules/counter/browser/src/connected-react-router/index.ts b/packages-modules/counter/browser/src/redux-first-history/index.ts
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/index.ts
rename to packages-modules/counter/browser/src/redux-first-history/index.ts
diff --git a/packages-modules/counter/browser/src/connected-react-router/interfaces/index.ts b/packages-modules/counter/browser/src/redux-first-history/interfaces/index.ts
similarity index 100%
rename from packages-modules/counter/browser/src/connected-react-router/interfaces/index.ts
rename to packages-modules/counter/browser/src/redux-first-history/interfaces/index.ts
diff --git a/packages-modules/counter/browser/src/redux-first-history/interfaces/state.ts b/packages-modules/counter/browser/src/redux-first-history/interfaces/state.ts
new file mode 100755
index 000000000..82e84abd0
--- /dev/null
+++ b/packages-modules/counter/browser/src/redux-first-history/interfaces/state.ts
@@ -0,0 +1,4 @@
+export interface State {
+ connectedReactRouterCounter: number;
+ router: any;
+}
diff --git a/packages-modules/counter/browser/src/connected-react-router/module.tsx b/packages-modules/counter/browser/src/redux-first-history/module.tsx
similarity index 89%
rename from packages-modules/counter/browser/src/connected-react-router/module.tsx
rename to packages-modules/counter/browser/src/redux-first-history/module.tsx
index cfa4f99c9..d51765bc4 100755
--- a/packages-modules/counter/browser/src/connected-react-router/module.tsx
+++ b/packages-modules/counter/browser/src/redux-first-history/module.tsx
@@ -3,7 +3,7 @@ import * as React from 'react';
import { Feature } from '@common-stack/client-react';
import Counter from './components/Counter';
import NavBar from './components/NavBar';
-import { connectedReactRouterCounter } from './redux';
+import connectedReactRouterCounter from './redux';
import { filteredRoutes, filteredMenus } from './compute';
export default new Feature({
diff --git a/packages-modules/counter/browser/src/redux-first-history/redux/index.ts b/packages-modules/counter/browser/src/redux-first-history/redux/index.ts
new file mode 100755
index 000000000..066116799
--- /dev/null
+++ b/packages-modules/counter/browser/src/redux-first-history/redux/index.ts
@@ -0,0 +1,29 @@
+// Import createSlice from Redux Toolkit
+import { createSlice, PayloadAction } from '@reduxjs/toolkit';
+import type * as rtk from "@reduxjs/toolkit";
+
+// Define initial state
+const initialState = 0;
+
+// Create a slice for the counter with `createSlice`
+const connectedReactRouterCounterSlice = createSlice({
+ name: 'redux-data', // A name, used in action types
+ initialState,
+ reducers: {
+ // The name of the reducer serves as the name of the action
+ increment(state) {
+ return state + 1;
+ },
+ decrement(state) {
+ return state - 1;
+ },
+ },
+});
+
+// Export the reducer
+const { reducer, actions } = connectedReactRouterCounterSlice;
+
+// Export actions
+export const { increment, decrement } = actions;
+
+export default reducer;
diff --git a/packages-modules/counter/browser/src/utils/menu.ts b/packages-modules/counter/browser/src/utils/menu.ts
index 9ab4aaaf1..67ecc596e 100755
--- a/packages-modules/counter/browser/src/utils/menu.ts
+++ b/packages-modules/counter/browser/src/utils/menu.ts
@@ -1,34 +1,35 @@
-export const getFilteredMenus = (accountPageStore, selectedMenu) =>
- accountPageStore
- .map((item) => {
- if (selectedMenu.indexOf(item.key) !== -1) {
- const { path, component, ...rest } = item;
- return {
- [path]: { name: rest.tab, ...rest },
- };
+const filterStore = (store, selected) => {
+ const cloned = [...store];
+ cloned.forEach((item) => {
+ if (Array.isArray(item.routes)) {
+ item.routes = filterStore(item.routes, selected);
+ if (item.routes.length < 1) {
+ delete item.routes;
}
- })
- .filter((valid) => valid);
+ }
+ });
+
+ return cloned.filter((item) => Array.isArray(item.routes) || selected.indexOf(item.key) !== -1);
+};
+
+export const getFilteredMenus = (accountPageStore, selectedMenu) =>
+ filterStore(accountPageStore, selectedMenu).map((item) => {
+ const { path, component, ...rest } = item;
+ return {
+ [path]: { name: rest.tab, ...rest },
+ };
+ });
export const getFilteredRoutes = (accountPageStore, selectedRoutes) =>
- accountPageStore
- .map((item) => {
- if (selectedRoutes.indexOf(item.key) !== -1) {
- const { path } = item;
- return {
- [path]: item,
- };
- }
- return null;
- })
- .filter((valid) => valid);
+ filterStore(accountPageStore, selectedRoutes).map((item) => {
+ const { path } = item;
+ return {
+ [path]: item,
+ };
+ });
export const getFilteredTabs = (accountPageStore, selectedTabs) =>
- accountPageStore
- .map((item) => {
- if (selectedTabs.indexOf(item.key) !== -1) {
- const { component, ...rest } = item;
- return rest;
- }
- })
- .filter((valid) => valid);
+ filterStore(accountPageStore, selectedTabs).map((item) => {
+ const { component, ...rest } = item;
+ return rest;
+ });
diff --git a/packages-modules/counter/browser/tsconfig.json b/packages-modules/counter/browser/tsconfig.json
index 88468a68b..c3f23862e 100755
--- a/packages-modules/counter/browser/tsconfig.json
+++ b/packages-modules/counter/browser/tsconfig.json
@@ -1,10 +1,6 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
- "allowSyntheticDefaultImports": true,
- "experimentalDecorators": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
"rootDir": "./src",
"outDir": "lib",
"declarationDir": "lib",
@@ -27,6 +23,5 @@
],
"include": [
"src",
- "./typings/*.d.ts"
]
}
\ No newline at end of file
diff --git a/packages-modules/counter/electron/package.json b/packages-modules/counter/electron/package.json
index b3fddf8cc..7405fc5c6 100755
--- a/packages-modules/counter/electron/package.json
+++ b/packages-modules/counter/electron/package.json
@@ -19,14 +19,7 @@
"watch": "yarn build:lib:watch"
},
"dependencies": {
- "@sample-stack/counter-module-browser": "0.0.1"
- },
- "devDependencies": {
- "@open-wc/building-rollup": "^1.10.0",
- "@rollup/plugin-graphql": "1.0.0",
- "@rollup/plugin-image": "^2.0.6",
- "@rollup/plugin-typescript": "^6.1.0",
- "rollup": "latest"
+ "@sample-stack/counter-module-browser": "link:../browser"
},
"peerDependencies": {
"@common-stack/client-react": "*",
@@ -46,4 +39,4 @@
"typescript": {
"definition": "lib/index.d.ts"
}
-}
\ No newline at end of file
+}
diff --git a/packages-modules/counter/electron/src/epics/count-tray-updater.ts b/packages-modules/counter/electron/src/epics/count-tray-updater.ts
index 2910586a4..d7b2fa0d4 100644
--- a/packages-modules/counter/electron/src/epics/count-tray-updater.ts
+++ b/packages-modules/counter/electron/src/epics/count-tray-updater.ts
@@ -3,7 +3,7 @@ import { ofType } from 'redux-observable';
import { Observable, of } from 'rxjs';
import { distinctUntilChanged, map, tap, exhaustMap, pluck, catchError, filter } from 'rxjs/operators';
import { ElectronTypes } from '@common-stack/client-core';
-import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '@sample-stack/counter-module-browser/lib/connected-react-router/constants/action-types';
+import { CONNECTED_REACT_ROUTER_ACTION_TYPES } from '@sample-stack/counter-module-browser/lib/redux-first-history/constants/action-types';
export const onCountChangedEpic = (
action$: Observable,
diff --git a/packages-modules/counter/electron/src/index.ts b/packages-modules/counter/electron/src/index.ts
index f16f0a440..096f8be30 100755
--- a/packages-modules/counter/electron/src/index.ts
+++ b/packages-modules/counter/electron/src/index.ts
@@ -1,5 +1,5 @@
import { Feature } from '@common-stack/client-react';
-import { connectedReactRouterCounter } from '@sample-stack/counter-module-browser/lib/connected-react-router/redux/reducers/counter';
+import connectedReactRouterCounter from '@sample-stack/counter-module-browser/lib/redux-first-history/redux/index.js';
import { onCountChangedEpic } from './epics';
const ElectronMainModule = new Feature({
diff --git a/packages-modules/counter/mobile/package.json b/packages-modules/counter/mobile/package.json
index 3c655b4b0..7d433a83b 100755
--- a/packages-modules/counter/mobile/package.json
+++ b/packages-modules/counter/mobile/package.json
@@ -19,7 +19,7 @@
"watch": "yarn build:lib:watch"
},
"dependencies": {
- "@sample-stack/platform-browser": "0.0.1",
+ "@sample-stack/platform-browser": "link:../../../packages/sample-platform/browser",
"antd": "~5.1.7"
},
"peerDependencies": {
@@ -38,4 +38,4 @@
"typescript": {
"definition": "lib/index.d.ts"
}
-}
\ No newline at end of file
+}
diff --git a/packages-modules/counter/mobile/src/common/components/Dashboard.tsx b/packages-modules/counter/mobile/src/common/components/Dashboard.tsx
index 7205da255..64d51611f 100755
--- a/packages-modules/counter/mobile/src/common/components/Dashboard.tsx
+++ b/packages-modules/counter/mobile/src/common/components/Dashboard.tsx
@@ -1,4 +1,3 @@
import * as React from 'react';
-import { renderRoutes } from 'react-router-config';
-export const Dashboard = (props) => <>{renderRoutes(props.route.routes, { matchPath: props.route.path })}>;
+export const Dashboard = (props) => <>{}>;
diff --git a/packages-modules/counter/mobile/src/common/interfaces/context.ts b/packages-modules/counter/mobile/src/common/interfaces/context.ts
index acb8051de..85f0ff167 100755
--- a/packages-modules/counter/mobile/src/common/interfaces/context.ts
+++ b/packages-modules/counter/mobile/src/common/interfaces/context.ts
@@ -1,5 +1,5 @@
import { DataProxy } from '@apollo/client/cache';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
export interface MyContext {
cache: DataProxy;
diff --git a/packages-modules/counter/mobile/src/connected-react-router/interfaces/state.ts b/packages-modules/counter/mobile/src/connected-react-router/interfaces/state.ts
index f5de723d6..82e84abd0 100755
--- a/packages-modules/counter/mobile/src/connected-react-router/interfaces/state.ts
+++ b/packages-modules/counter/mobile/src/connected-react-router/interfaces/state.ts
@@ -1,6 +1,4 @@
-import { RouterState } from 'connected-react-router';
-
export interface State {
connectedReactRouterCounter: number;
- router: RouterState;
+ router: any;
}
diff --git a/packages-modules/counter/server/src/dataloader/cache.ts b/packages-modules/counter/server/src/dataloader/cache.ts
index ff3baebbd..a784be7b9 100644
--- a/packages-modules/counter/server/src/dataloader/cache.ts
+++ b/packages-modules/counter/server/src/dataloader/cache.ts
@@ -1,5 +1,5 @@
-import * as DataLoader from 'dataloader';
-import { KeyValueCache } from 'apollo-server-caching';
+import DataLoader from 'dataloader';
+import { KeyValueCache } from '@apollo/utils.keyvaluecache';
import { logger } from '@cdm-logger/server';
import { config } from '../config';
import { ICounterService } from '../interfaces';
@@ -14,9 +14,7 @@ export const setupCaching = ({
cache: KeyValueCache;
}) => {
const loader = new DataLoader(
- (args) => {
- return (counterService.counterQuery() as Promise).then((data) => [data]);
- },
+ (args) => (counterService.counterQuery() as Promise).then((data) => [data]),
{ batch: false },
);
const cachedCounterService: ICounterService = {} as ICounterService;
diff --git a/packages-modules/counter/server/src/dataloader/counter-dataloader.ts b/packages-modules/counter/server/src/dataloader/counter-dataloader.ts
index 4f7301a0a..43bb2a771 100644
--- a/packages-modules/counter/server/src/dataloader/counter-dataloader.ts
+++ b/packages-modules/counter/server/src/dataloader/counter-dataloader.ts
@@ -1,8 +1,6 @@
-import { DataSource, DataSourceConfig } from 'apollo-datasource';
import { ApolloError } from 'apollo-server-errors';
-import { InMemoryLRUCache } from 'apollo-server-caching';
+import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache';
// import { setupCaching } from './cache';
-import { KeyValueCache } from 'apollo-server-caching';
import { IService, IContext, ICounterService } from '../interfaces';
import { setupCaching } from './cache';
import { Counter } from '../generated-models';
@@ -11,14 +9,12 @@ export interface CacheOptions {
ttl?: number;
}
-export class CounterDataSource extends DataSource implements ICounterService {
+export class CounterDataSource implements ICounterService {
private context!: IContext;
private cacheCounterService: ICounterService;
- constructor() {
- super();
- }
+ constructor(private cache?) {}
public counterQuery(): Counter | Promise | PromiseLike {
return this.cacheCounterService.counterQuery();
@@ -28,7 +24,7 @@ export class CounterDataSource extends DataSource implements ICounterS
return this.cacheCounterService.addCounter();
}
- public initialize(config: DataSourceConfig) {
+ public initialize(config) {
this.context = config.context;
if (!this.context.counterMockService) {
throw new ApolloError('Missing TextFileService in the context!');
diff --git a/packages/assets/src/assets/manifest.xjson b/packages/assets/src/assets/manifest.xjson
index c25820026..f08579b72 100644
--- a/packages/assets/src/assets/manifest.xjson
+++ b/packages/assets/src/assets/manifest.xjson
@@ -1,16 +1,7 @@
{
"name": "",
"icons": [
- {
- "src": "android-chrome-192x192.png",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "android-chrome-256x256.png",
- "sizes": "256x256",
- "type": "image/png"
- }
+
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
diff --git a/packages/sample-platform/browser/package.json b/packages/sample-platform/browser/package.json
index 548ea408f..aea195d6e 100644
--- a/packages/sample-platform/browser/package.json
+++ b/packages/sample-platform/browser/package.json
@@ -19,7 +19,7 @@
"watch": "yarn build:lib:watch"
},
"dependencies": {
- "@sample-stack/core": "0.0.1"
+ "@sample-stack/core": "link:../../sample-core"
},
"publishConfig": {
"access": "public"
@@ -27,4 +27,4 @@
"typescript": {
"definition": "lib/index.d.ts"
}
-}
\ No newline at end of file
+}
diff --git a/packages/sample-platform/browser/src/containers/PersonList.tsx b/packages/sample-platform/browser/src/containers/PersonList.tsx
index c2b62a054..7a73ecb5d 100755
--- a/packages/sample-platform/browser/src/containers/PersonList.tsx
+++ b/packages/sample-platform/browser/src/containers/PersonList.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { graphql } from '@apollo/react-hoc';
+import { graphql } from '@apollo/client/react/hoc';
import compose from 'lodash/flowRight';
import { PERSONS_QUERY } from '../graphql';
@@ -9,12 +9,11 @@ export interface IPersonListProps {
const PersonListComponent: React.FC = ({ persons }) => (
Persons:
- {persons && persons.map((person, i) =>
{person.name}
)}
+ {persons && persons.map((person, i) =>
{person.name}
)}
);
-export const PersonList: React.ComponentClass<{}> =
- compose(
- graphql<{}, any, {}, {}>(PERSONS_QUERY),
- // flattenProp('data'),
- )(PersonListComponent);
+export const PersonList: React.ComponentClass<{}> = compose(
+ graphql<{}, any, {}, {}>(PERSONS_QUERY),
+ // flattenProp('data'),
+)(PersonListComponent);
diff --git a/packages/sample-platform/browser/src/containers/ServerCounter.tsx b/packages/sample-platform/browser/src/containers/ServerCounter.tsx
index 948ffb7da..9de0e59cf 100755
--- a/packages/sample-platform/browser/src/containers/ServerCounter.tsx
+++ b/packages/sample-platform/browser/src/containers/ServerCounter.tsx
@@ -1,9 +1,9 @@
import * as React from 'react';
import update from 'immutability-helper';
-import { graphql } from '@apollo/react-hoc';
+import { graphql } from '@apollo/client/react/hoc';
import compose from 'lodash/flowRight';
import { CounterComponent, ICounterProps } from '../components';
-import { COUNT_SUBSCRIPTION, COUNT_QUERY, ADD_COUNT_MUTATION,} from '../graphql';
+import { COUNT_SUBSCRIPTION, COUNT_QUERY, ADD_COUNT_MUTATION } from '../graphql';
import { logger } from '@cdm-logger/client';
type SubscriptionProps = {
subscribeToMore: Function;
@@ -60,7 +60,6 @@ type SubscriptionProps = {
// }
// }
-
// save(amount) {
// return () => mutate({
// variables: { amount },
@@ -85,56 +84,59 @@ const updateQueries = {
},
};
-export const CounterWithApollo: React.ComponentClass = (compose(
+export const CounterWithApollo: React.ComponentClass = compose(
graphql<{}, any, {}, {}>(ADD_COUNT_MUTATION, {
props: ({ ownProps, mutate }) => ({
save: (amount) => {
- return () => mutate({
- variables: { amount },
- // optimisticResponse: {
- // __typename: 'Mutation',
+ return () =>
+ mutate({
+ variables: { amount },
+ // optimisticResponse: {
+ // __typename: 'Mutation',
- // },
- });
+ // },
+ });
},
}),
}),
graphql<{}, any, {}, {}>(ADD_COUNT_MUTATION, {
props: ({ ownProps, mutate }) => ({
increment: (amount) => {
- return () => mutate({
- variables: { amount },
- // updateQueries,
- });
+ return () =>
+ mutate({
+ variables: { amount },
+ // updateQueries,
+ });
},
}),
}),
-)(graphql(COUNT_QUERY, {
- name: 'countData',
- props: ({ countData }: any) => {
- const newlog = logger.child({ childName: 'UIController' });
- newlog.debug('count data : (%j)', countData);
- return {
- subscribeToCount: params => {
- // logger.debug('count subscript data (%j)', params);
- return countData.subscribeToMore({
- document: COUNT_SUBSCRIPTION,
- variables: {},
- updateQuery: (prev: any, { subscriptionData }) => {
- const payload = subscriptionData.data && subscriptionData.data.subscribeToWorkspace;
- if (!payload) {
- return prev;
- }
- return payload;
- },
- });
- },
- counter: countData.count && countData.count.amount,
- isLoading: countData.loading,
- isSaving: false,
- load: () => countData.count.amount,
- error: countData.error,
- };
- },
-})(CounterComponent as any))
+)(
+ graphql(COUNT_QUERY, {
+ name: 'countData',
+ props: ({ countData }: any) => {
+ const newlog = logger.child({ childName: 'UIController' });
+ newlog.debug('count data : (%j)', countData);
+ return {
+ subscribeToCount: (params) => {
+ // logger.debug('count subscript data (%j)', params);
+ return countData.subscribeToMore({
+ document: COUNT_SUBSCRIPTION,
+ variables: {},
+ updateQuery: (prev: any, { subscriptionData }) => {
+ const payload = subscriptionData.data && subscriptionData.data.subscribeToWorkspace;
+ if (!payload) {
+ return prev;
+ }
+ return payload;
+ },
+ });
+ },
+ counter: countData.count && countData.count.amount,
+ isLoading: countData.loading,
+ isSaving: false,
+ load: () => countData.count.amount,
+ error: countData.error,
+ };
+ },
+ })(CounterComponent as any),
);
diff --git a/packages/sample-platform/browser/src/module.ts b/packages/sample-platform/browser/src/module.ts
index 546693a14..7d8bdf592 100644
--- a/packages/sample-platform/browser/src/module.ts
+++ b/packages/sample-platform/browser/src/module.ts
@@ -1,7 +1,7 @@
import { Feature } from '@common-stack/client-react';
import { interfaces } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import { ClientTypes as BrowserTypes } from '@common-stack/client-core';
import { platformModule } from './inversify-containers';
diff --git a/packages/sample-platform/server/package.json b/packages/sample-platform/server/package.json
index 855976981..86dd1ccb6 100644
--- a/packages/sample-platform/server/package.json
+++ b/packages/sample-platform/server/package.json
@@ -19,7 +19,7 @@
"watch": "yarn build:lib:watch"
},
"dependencies": {
- "@sample-stack/core": "0.0.1"
+ "@sample-stack/core": "link:../../sample-core"
},
"publishConfig": {
"access": "public"
@@ -27,4 +27,4 @@
"typescript": {
"definition": "lib/index.d.ts"
}
-}
\ No newline at end of file
+}
diff --git a/packages/sample-store/package.json b/packages/sample-store/package.json
index b91fabf98..0173983db 100755
--- a/packages/sample-store/package.json
+++ b/packages/sample-store/package.json
@@ -19,7 +19,7 @@
"watch": "yarn build:lib:watch"
},
"dependencies": {
- "@sample-stack/core": "0.0.1",
+ "@sample-stack/core": "link:../sample-core",
"knex": "^2.3.0",
"sequelize": "^5.21.3"
},
@@ -32,4 +32,4 @@
"typescript": {
"definition": "lib/index.d.ts"
}
-}
\ No newline at end of file
+}
diff --git a/portable-devices/browser-extension/package.json b/portable-devices/browser-extension/package.json
index ed18b5679..84cc73ebf 100644
--- a/portable-devices/browser-extension/package.json
+++ b/portable-devices/browser-extension/package.json
@@ -34,14 +34,14 @@
},
"dependencies": {
"@ant-design/icons": "^4.2.2",
- "@apollo/client": "~3.7.1",
+ "@apollo/client": "^3.9.0",
"@apollo/react-common": "^3.1.4",
- "@cdm-logger/client": "^7.0.12",
- "@common-stack/client-core": "0.2.33",
- "@common-stack/client-react": "0.2.33",
- "@common-stack/components-pro": "^0.3.1-alpha.1",
- "@common-stack/core": "0.2.32",
- "@common-stack/env-list-loader": "0.5.1-alpha.1",
+ "@cdm-logger/client": "^9.0.3",
+ "@common-stack/client-core": "6.0.2-alpha.2",
+ "@common-stack/client-react": "6.0.6-alpha.0",
+ "@common-stack/components-pro": "^6.0.2-alpha.2",
+ "@common-stack/core": "6.0.2-alpha.2",
+ "@common-stack/env-list-loader": "6.0.2-alpha.2",
"@workbench-stack/components": "^2.2.1-alpha.3",
"antd": "~4.24.1",
"apollo-link-debounce": "^2.1.0",
@@ -54,7 +54,6 @@
"body-parser": "^1.18.2",
"browser-bunyan": "^1.6.3",
"classnames": "^2.2.6",
- "connected-react-router": "^6.9.1",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"envalid": "~7.2.2",
@@ -62,25 +61,21 @@
"flat": "^4.0.0",
"graphql-tag": "^2.11.0",
"graphql-ws": "^5.11.2",
- "history": "^4.10.1",
"immutability-helper": "^3.0.1",
- "inversify": "^5.0.1",
+ "inversify": "^6.0.2",
"isomorphic-fetch": "^2.2.1",
"js-cookie": "^2.2.1",
"lodash": "^4.17.15",
"nanoid": "^1.3.1",
"ramda": "^0.26.1",
- "react": "18.0.0",
- "react-dom": "18.0.0",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
"react-helmet": "^6.1.0",
"react-highlight": "^0.12.0",
"react-highlight-words": "^0.16.0",
"react-loadable": "^5.5.0",
"react-redux": "^7.1.3",
"react-resizable": "^1.10.1",
- "react-router": "^5.3.3",
- "react-router-config": "^5.1.1",
- "react-router-dom": "^5.1.2",
"react-transition-group": "^4.3.0",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
diff --git a/portable-devices/browser-extension/src/config/base-apollo-client.ts b/portable-devices/browser-extension/src/config/base-apollo-client.ts
index 054226674..365898ef2 100755
--- a/portable-devices/browser-extension/src/config/base-apollo-client.ts
+++ b/portable-devices/browser-extension/src/config/base-apollo-client.ts
@@ -5,7 +5,7 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-underscore-dangle */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-import { ApolloClient, ApolloClientOptions, ApolloLink, gql } from '@apollo/client';
+import { ApolloClient, ApolloClientOptions, ApolloLink, gql } from '@apollo/client/index.js';
import { InMemoryCache } from '@apollo/client/cache';
import { HttpLink, createHttpLink } from '@apollo/client/link/http';
import { BatchHttpLink } from '@apollo/client/link/batch-http';
diff --git a/portable-devices/browser-extension/src/config/newtab/client.service.ts b/portable-devices/browser-extension/src/config/newtab/client.service.ts
index fbfac81d0..302b0161b 100644
--- a/portable-devices/browser-extension/src/config/newtab/client.service.ts
+++ b/portable-devices/browser-extension/src/config/newtab/client.service.ts
@@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClientTypes } from '@common-stack/client-core';
import { Container } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import modules, { container } from '../../modules/popup';
import { createApolloClient } from '../base-apollo-client';
import { PUBLIC_SETTINGS } from '../public-config';
diff --git a/portable-devices/browser-extension/src/config/options/client.service.ts b/portable-devices/browser-extension/src/config/options/client.service.ts
index b85eaef62..b4dfede2c 100644
--- a/portable-devices/browser-extension/src/config/options/client.service.ts
+++ b/portable-devices/browser-extension/src/config/options/client.service.ts
@@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClientTypes } from '@common-stack/client-core';
import { Container } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import { CdmLogger } from '@cdm-logger/core';
import modules, { container, logger } from '../../modules/popup';
import { createApolloClient } from '../base-apollo-client';
diff --git a/portable-devices/browser-extension/src/config/panel/client.service.ts b/portable-devices/browser-extension/src/config/panel/client.service.ts
index bb7d1a918..12bd75983 100644
--- a/portable-devices/browser-extension/src/config/panel/client.service.ts
+++ b/portable-devices/browser-extension/src/config/panel/client.service.ts
@@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClientTypes } from '@common-stack/client-core';
import { Container } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import modules, { container } from '../../modules/popup';
import { createApolloClient } from '../base-apollo-client';
import { PUBLIC_SETTINGS } from '../public-config';
diff --git a/portable-devices/browser-extension/src/config/popup/client.service.ts b/portable-devices/browser-extension/src/config/popup/client.service.ts
index bb7d1a918..12bd75983 100644
--- a/portable-devices/browser-extension/src/config/popup/client.service.ts
+++ b/portable-devices/browser-extension/src/config/popup/client.service.ts
@@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClientTypes } from '@common-stack/client-core';
import { Container } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import modules, { container } from '../../modules/popup';
import { createApolloClient } from '../base-apollo-client';
import { PUBLIC_SETTINGS } from '../public-config';
diff --git a/portable-devices/desktop/package.json b/portable-devices/desktop/package.json
index 9525b6098..9d4c97eb8 100644
--- a/portable-devices/desktop/package.json
+++ b/portable-devices/desktop/package.json
@@ -1,126 +1,121 @@
{
- "name": "sample-stack-desktop-device",
- "version": "0.0.1",
- "private": true,
- "description": "App is based on Electron, React, Redux and NodeJS as a back end",
- "homepage": "https://github.com/cdmbase/fullstack-pro#readme",
- "bugs": {
- "url": "https://github.com/cdmbase/fullstack-pro/issues"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/cdmbase/fullstack-pro.git"
- },
- "license": "MIT",
- "author": {
- "name": "CDMBase LLC",
- "email": "jteidforyou@gmail.com"
- },
- "main": "index.js",
- "scripts": {
- "build": "cross-env NODE_OPTIONS='--max_old_space_size=4096' NODE_ENV=production electron-webpack",
- "build:clean": "rimraf dist",
- "electron": "electron dist/main/main.js",
- "package": "electron-builder",
- "release": "yarn build && electron-builder build --mac",
- "release:linux": "yarn build && electron-builder build --linux",
- "release:mac": "yarn build && electron-builder build --mac",
- "release:win": "electron-builder build --win",
- "start": "cross-env NODE_ENV=production electron dist/main/main.js",
- "start:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env electron dist/main/main.js",
- "start:prod": "cross-env NODE_ENV=production ENV_FILE=../../config/development/dev.env electron dist/main/main.js",
- "start:staging": "cross-env NODE_ENV=staging ENV_FILE=../../config/staging/staging.env electron dist/main/main.js",
- "test": "echo Skipped.",
- "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env electron-webpack dev",
- "watch:staging": "cross-env ENV_FILE=../../config/staging/staging.env electron-webpack dev"
- },
- "resolutions": {
- "webpack-sources": "^1.1.0"
- },
- "dependencies": {
- "@ant-design/compatible": "^1.0.5",
- "@ant-design/icons": "^4.2.2",
- "@apollo/client": "~3.7.1",
- "@cdm-logger/client": "^7.0.12",
- "@cdm-logger/electron": "^7.0.12",
- "@cdm-logger/server": "^7.0.12",
- "@common-stack/client-core": "0.5.1",
- "@common-stack/client-react": "0.5.6",
- "@common-stack/core": "0.5.1",
- "@common-stack/server-core": "0.5.1",
- "@sample-stack/core": "0.0.1",
- "@sample-stack/counter-module-browser": "0.0.1",
- "@sample-stack/counter-module-electron": "0.0.1",
- "@sample-stack/platform-browser": "0.0.1",
- "antd": "~5.1.7",
- "apollo-link-debounce": "^3.0.0",
- "apollo-link-logger": "^2.0.0",
- "apollo-server-errors": "^3.3.1",
- "check-internet-connected": "^2.0.5",
- "classnames": "^2.2.6",
- "connected-react-router": "^6.9.1",
- "cors": "^2.8.5",
- "cross-env": "^7.0.3",
- "dotenv": "^8.2.0",
- "electron-json-storage": "^2.0.0",
- "electron-positioner": "^4.1.0",
- "electron-redux": "^1.5.4",
- "electron-updater": "4.3.9",
- "envalid": "~7.2.2",
- "esm": "^3.2.25",
- "graphql": "^15.0.0",
- "graphql-tag": "^2.11.0",
- "graphql-ws": "^5.11.2",
- "history": "^4.10.1",
- "immutability-helper": "^3.0.1",
- "inversify": "^5.0.1",
- "inversify-binding-decorators": "^4.0.0",
- "isomorphic-fetch": "^2.2.1",
- "js-cookie": "^2.2.1",
- "lodash": "^4.17.15",
- "os-name": "^4.0.0",
- "pify": "^2.3.0",
- "ramda": "^0.26.1",
- "react": "18.0.0",
- "react-dom": "18.0.0",
- "react-helmet": "^6.1.0",
- "react-loadable": "^5.5.0",
- "react-redux": "^7.1.3",
- "react-router": "^5.3.3",
- "react-router-config": "^5.1.1",
- "react-router-dom": "^5.3.3",
- "react-transition-group": "^4.3.0",
- "redux": "^4.0.5",
- "redux-logger": "^3.0.6",
- "redux-observable": "^1.2.0",
- "redux-persist": "^6.0.0",
- "redux-thunk": "^2.3.0",
- "reflect-metadata": "^0.1.13",
- "reselect": "^4.0.0",
- "rxjs": "^6.5.3",
- "rxjs-compat": "^6.5.3",
- "rxjs-hooks": "^0.5.2",
- "source-map-support": "^0.5.19",
- "sqlite3": "^5.0.2",
- "typeorm": "^0.2.32"
- },
- "devDependencies": {
- "@jest-runner/electron": "^3.0.1",
- "cross-env": "^7.0.3",
- "electron": "11.4.10",
- "electron-builder": "^22.11.7",
- "electron-debug": "^3.1.0",
- "electron-devtools-installer": "^3.2.0",
- "electron-is": "^3.0.0",
- "electron-log": "^4.3.5",
- "electron-webpack": "^2.8.2",
- "electron-webpack-ts": "^4.0.1",
- "pm2": "^5.2.2",
- "rimraf": "^3.0.2",
- "workspaces-utils": "^1.2.1"
- },
- "buildAbout": {
- "appName": "Fullstack-Pro",
- "apiApp": "https://time-tracker-api.herokuapp.com/"
- }
-}
\ No newline at end of file
+ "name": "sample-stack-desktop-device",
+ "version": "0.0.1",
+ "private": true,
+ "description": "App is based on Electron, React, Redux and NodeJS as a back end",
+ "homepage": "https://github.com/cdmbase/fullstack-pro#readme",
+ "bugs": {
+ "url": "https://github.com/cdmbase/fullstack-pro/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/cdmbase/fullstack-pro.git"
+ },
+ "license": "MIT",
+ "author": {
+ "name": "CDMBase LLC",
+ "email": "jteidforyou@gmail.com"
+ },
+ "main": "index.js",
+ "scripts": {
+ "build": "cross-env NODE_OPTIONS='--max_old_space_size=4096' NODE_ENV=production electron-webpack",
+ "build:clean": "rimraf dist",
+ "electron": "electron dist/main/main.js",
+ "package": "electron-builder",
+ "release": "yarn build && electron-builder build --mac",
+ "release:linux": "yarn build && electron-builder build --linux",
+ "release:mac": "yarn build && electron-builder build --mac",
+ "release:win": "electron-builder build --win",
+ "start": "cross-env NODE_ENV=production electron dist/main/main.js",
+ "start:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env electron dist/main/main.js",
+ "start:prod": "cross-env NODE_ENV=production ENV_FILE=../../config/development/dev.env electron dist/main/main.js",
+ "start:staging": "cross-env NODE_ENV=staging ENV_FILE=../../config/staging/staging.env electron dist/main/main.js",
+ "test": "echo Skipped.",
+ "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env electron-webpack dev",
+ "watch:staging": "cross-env ENV_FILE=../../config/staging/staging.env electron-webpack dev"
+ },
+ "resolutions": {
+ "webpack-sources": "^1.1.0"
+ },
+ "dependencies": {
+ "@ant-design/compatible": "^1.0.5",
+ "@ant-design/icons": "^4.2.2",
+ "@apollo/client": "^3.9.0",
+ "@cdm-logger/client": "^9.0.3",
+ "@cdm-logger/electron": "^9.0.3",
+ "@cdm-logger/server": "^9.0.3",
+ "@common-stack/client-core": "6.0.2-alpha.2",
+ "@common-stack/client-react": "6.0.6-alpha.0",
+ "@common-stack/core": "6.0.2-alpha.2",
+ "@common-stack/server-core": "6.0.6-alpha.0",
+ "@sample-stack/core": "link:../../packages/sample-core",
+ "@sample-stack/counter-module-browser": "link:../../packages-modules/counter/browser",
+ "@sample-stack/counter-module-electron": "link:../../packages-modules/counter/electron",
+ "@sample-stack/platform-browser": "link:../../packages/sample-platform/browser",
+ "antd": "^5.14.0",
+ "apollo-link-debounce": "^3.0.0",
+ "apollo-link-logger": "^2.0.0",
+ "apollo-server-errors": "^3.3.1",
+ "check-internet-connected": "^2.0.5",
+ "classnames": "^2.2.6",
+ "cors": "^2.8.5",
+ "cross-env": "^7.0.3",
+ "dotenv": "^8.2.0",
+ "electron-json-storage": "^2.0.0",
+ "electron-positioner": "^4.1.0",
+ "electron-redux": "^1.5.4",
+ "electron-updater": "4.3.9",
+ "envalid": "~7.2.2",
+ "esm": "^3.2.25",
+ "graphql": "^15.0.0",
+ "graphql-tag": "^2.11.0",
+ "graphql-ws": "^5.11.2",
+ "immutability-helper": "^3.0.1",
+ "inversify": "^6.0.2",
+ "inversify-binding-decorators": "^4.0.0",
+ "isomorphic-fetch": "^2.2.1",
+ "js-cookie": "^2.2.1",
+ "lodash": "^4.17.15",
+ "os-name": "^4.0.0",
+ "pify": "^2.3.0",
+ "ramda": "^0.26.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-helmet": "^6.1.0",
+ "react-loadable": "^5.5.0",
+ "react-redux": "^7.1.3",
+ "react-transition-group": "^4.3.0",
+ "redux": "^4.0.5",
+ "redux-logger": "^3.0.6",
+ "redux-observable": "^1.2.0",
+ "redux-persist": "^6.0.0",
+ "redux-thunk": "^2.3.0",
+ "reflect-metadata": "^0.1.13",
+ "reselect": "^4.0.0",
+ "rxjs": "^6.5.3",
+ "rxjs-compat": "^6.5.3",
+ "rxjs-hooks": "^0.5.2",
+ "source-map-support": "^0.5.19",
+ "sqlite3": "^5.0.2",
+ "typeorm": "^0.2.32"
+ },
+ "devDependencies": {
+ "@jest-runner/electron": "^3.0.1",
+ "cross-env": "^7.0.3",
+ "electron": "11.4.10",
+ "electron-builder": "^22.11.7",
+ "electron-debug": "^3.1.0",
+ "electron-devtools-installer": "^3.2.0",
+ "electron-is": "^3.0.0",
+ "electron-log": "^4.3.5",
+ "electron-webpack": "^2.8.2",
+ "electron-webpack-ts": "^4.0.1",
+ "pm2": "^5.2.2",
+ "rimraf": "^3.0.2",
+ "workspaces-utils": "^1.2.1"
+ },
+ "buildAbout": {
+ "appName": "Fullstack-Pro",
+ "apiApp": "https://time-tracker-api.herokuapp.com/"
+ }
+}
diff --git a/portable-devices/desktop/src/common/config/base-apollo-client.ts b/portable-devices/desktop/src/common/config/base-apollo-client.ts
index 7f6c9b5f6..58b7ff641 100755
--- a/portable-devices/desktop/src/common/config/base-apollo-client.ts
+++ b/portable-devices/desktop/src/common/config/base-apollo-client.ts
@@ -2,7 +2,7 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-underscore-dangle */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-import { ApolloClient, ApolloClientOptions, ApolloLink } from '@apollo/client';
+import { ApolloClient, ApolloClientOptions, ApolloLink } from '@apollo/client/index.js';
import { InMemoryCache } from '@apollo/client/cache';
import { HttpLink, createHttpLink } from '@apollo/client/link/http';
import { BatchHttpLink } from '@apollo/client/link/batch-http';
diff --git a/portable-devices/desktop/src/main/config/client.service.ts b/portable-devices/desktop/src/main/config/client.service.ts
index a31e3dfb4..a80e70e53 100644
--- a/portable-devices/desktop/src/main/config/client.service.ts
+++ b/portable-devices/desktop/src/main/config/client.service.ts
@@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClientTypes } from '@common-stack/client-core';
import { interfaces } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import { CdmLogger } from '@cdm-logger/core';
import modules, { container, logger } from '../modules';
import { createApolloClient } from '../../common/config/base-apollo-client';
diff --git a/portable-devices/desktop/src/renderer/app/Main.tsx b/portable-devices/desktop/src/renderer/app/Main.tsx
index 44bd58512..3ad7f01b6 100755
--- a/portable-devices/desktop/src/renderer/app/Main.tsx
+++ b/portable-devices/desktop/src/renderer/app/Main.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { ApolloProvider } from '@apollo/client';
+import { ApolloProvider } from '@apollo/client/index.js';
import { Provider } from 'react-redux';
import { PluginArea } from '@common-stack/client-react';
import { ConnectedRouter } from 'connected-react-router';
diff --git a/portable-devices/desktop/src/renderer/app/Tray.tsx b/portable-devices/desktop/src/renderer/app/Tray.tsx
index cbc4eb566..e1c0ed9f8 100644
--- a/portable-devices/desktop/src/renderer/app/Tray.tsx
+++ b/portable-devices/desktop/src/renderer/app/Tray.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { ApolloProvider } from '@apollo/client';
+import { ApolloProvider } from '@apollo/client/index.js';
import { Provider } from 'react-redux';
import { createClientContainer } from '../config/main/client.service';
import { epic$ } from '../config/tray/epic-config';
diff --git a/portable-devices/desktop/src/renderer/config/main/client.service.ts b/portable-devices/desktop/src/renderer/config/main/client.service.ts
index 4ce7fc36d..1cddb396c 100644
--- a/portable-devices/desktop/src/renderer/config/main/client.service.ts
+++ b/portable-devices/desktop/src/renderer/config/main/client.service.ts
@@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClientTypes } from '@common-stack/client-core';
import { Container } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import { CdmLogger } from '@cdm-logger/core';
import { logger } from '@cdm-logger/client';
import modules, { container } from '../../modules/main';
diff --git a/portable-devices/desktop/src/renderer/config/tray/client.service.ts b/portable-devices/desktop/src/renderer/config/tray/client.service.ts
index 103330773..bff0de449 100644
--- a/portable-devices/desktop/src/renderer/config/tray/client.service.ts
+++ b/portable-devices/desktop/src/renderer/config/tray/client.service.ts
@@ -3,7 +3,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClientTypes } from '@common-stack/client-core';
import { Container } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { ApolloClient } from '@apollo/client/index.js';
import { CdmLogger } from '@cdm-logger/core';
import { logger } from '@cdm-logger/client';
import modules, { container } from '../../modules/tray';
diff --git a/portable-devices/mobile/.gitignore b/portable-devices/mobile/.gitignore
index 73e9e9457..fef5afeaf 100644
--- a/portable-devices/mobile/.gitignore
+++ b/portable-devices/mobile/.gitignore
@@ -11,3 +11,64 @@ web-build/
# macOS
.DS_Store
+
+# @generated expo-cli sync-e7dcf75f4e856f7b6f3239b3f3a7dd614ee755a8
+# The following patterns were generated by expo-cli
+
+# OSX
+#
+.DS_Store
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+project.xcworkspace
+
+# Android/IntelliJ
+#
+build/
+.idea
+.gradle
+local.properties
+*.iml
+*.hprof
+
+# node.js
+#
+node_modules/
+npm-debug.log
+yarn-error.log
+
+# BUCK
+buck-out/
+\.buckd/
+*.keystore
+!debug.keystore
+
+# Bundle artifacts
+*.jsbundle
+
+# CocoaPods
+/ios/Pods/
+
+# Expo
+.expo/
+web-build/
+dist/
+
+# @end expo-cli
\ No newline at end of file
diff --git a/portable-devices/mobile/App.tsx b/portable-devices/mobile/App.tsx
index 4d94323f0..592b76d01 100644
--- a/portable-devices/mobile/App.tsx
+++ b/portable-devices/mobile/App.tsx
@@ -1,4 +1,7 @@
import './src/config/public-config';
import App from './src/App';
+import 'react-native-reanimated';
+import 'react-native-url-polyfill/auto'
+import 'react-native-get-random-values';
export default App;
diff --git a/portable-devices/mobile/app.json b/portable-devices/mobile/app.json
index f5aff8cbb..f3a5d6f09 100644
--- a/portable-devices/mobile/app.json
+++ b/portable-devices/mobile/app.json
@@ -13,21 +13,6 @@
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
- "plugins": [
- [
- "expo-build-properties",
- {
- "android": {
- "compileSdkVersion": 31,
- "targetSdkVersion": 31,
- "buildToolsVersion": "31.0.0"
- },
- "ios": {
- "deploymentTarget": "13.0"
- }
- }
- ]
- ],
"updates": {
"fallbackToCacheTimeout": 0
},
diff --git a/portable-devices/mobile/babel.config.js b/portable-devices/mobile/babel.config.js
index 75558b534..8537c890b 100644
--- a/portable-devices/mobile/babel.config.js
+++ b/portable-devices/mobile/babel.config.js
@@ -7,6 +7,7 @@ module.exports = function (api) {
'module:react-native-dotenv',
{
moduleName: '@env',
+ "allowUndefined": true,
...(!!process.env.ENV_FILE && {path: process.env.ENV_FILE})
},
],
diff --git a/portable-devices/mobile/index.js b/portable-devices/mobile/index.js
index 8c91580d0..06b4e7915 100644
--- a/portable-devices/mobile/index.js
+++ b/portable-devices/mobile/index.js
@@ -4,6 +4,7 @@
import { registerRootComponent } from 'expo';
import './shim';
import 'react-native-reanimated'; // to fix web crash
+import 'react-native-gesture-handler';
import App from './App';
diff --git a/portable-devices/mobile/package.json b/portable-devices/mobile/package.json
index 29b9ff568..7a8cffdae 100644
--- a/portable-devices/mobile/package.json
+++ b/portable-devices/mobile/package.json
@@ -1,162 +1,163 @@
{
- "name": "sample-stack-mobile-device",
- "version": "0.0.1",
- "private": true,
- "main": "index.js",
- "scripts": {
- "android": "expo run:android",
- "build": "yarn easBuild --profile development",
- "build:all": "yarn build -p all",
- "build:web": "cross-env GENERATE_SOURCEMAP=false expo export:web",
- "build:android": "yarn build -p android --clear-cache",
- "build:auto": "yarn build:all --non-interactive",
- "build:clean": "rimraf build .expo .tmp",
- "build:configure": "eas build:configure",
- "build:ios": "yarn build -p ios --clear-cache",
- "build:preview": "yarn easBuild --profile preview",
- "build:preview:all": "yarn build:preview -p all --non-interactive",
- "build:preview:android": "yarn build:preview -p android --non-interactive",
- "build:preview:ios": "yarn build:preview -p ios --non-interactive",
- "build:previewLocal": "yarn easBuild --profile previewlocal",
- "build:previewLocal:all": "yarn build:previewLocal -p all --non-interactive",
- "build:previewLocal:android": "yarn build:previewLocal -p android --non-interactive",
- "build:previewLocal:ios": "yarn build:previewLocal -p ios --non-interactive",
- "build:previewSubmit": "yarn easBuild --profile previewSubmit --non-interactive",
- "build:previewSubmit:ios": "yarn build:previewSubmit -p ios --auto-submit",
- "build:previewSubmit:android": "yarn build:previewSubmit -p android --auto-submit",
- "build:previewSubmit:all": "yarn build:previewSubmit -p all --auto-submit",
- "build:prod": "yarn easBuild --profile production --non-interactive",
- "build:prod:all": "yarn build:prod -p all",
- "build:prod:android": "yarn build:prod -p android",
- "build:prod:ios": "yarn build:prod -p ios",
- "build:prod:manual": "yarn easBuild --profile production",
- "build:prodSubmit:all": "yarn build:prod:all --auto-submit",
- "build:prodSubmit:android": "yarn build:prod:android --auto-submit",
- "build:prodSubmit:ios": "yarn build:prod:ios --auto-submit",
- "build:stage": "yarn easBuild --profile staging -p ios --non-interactive",
- "cli": "node ../../tools/cli",
- "eas-build-post-install": "lerna exec --scope=@sample-stack/core --scope=@sample-stack/counter-module-mobile yarn build",
- "easBuild": "eas build",
- "eslint": "eslint --fix --ext js --ext jsx --ext json src",
- "exp-login": "cross-env NODE_ENV=production expo login -u $EXP_USERNAME -p $EXP_PASSWORD --non-interactive",
- "exp-publish": "yarn exp-login && yarn expo p --non-interactive",
- "ios": "expo run:ios",
- "lint": "yarn eslint && yarn tslint",
- "start": "expo start --dev-client",
- "submit:all": "eas submit -p all",
- "submit:android": "eas submit -p android",
- "submit:ios": "eas submit -p ios",
- "test": "yarn tests && yarn lint",
- "tests": "jest",
- "tests:watch": "jest --watch",
- "tslint": "tslint --fix -p tsconfig.json -c ../../tslint.json",
- "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env expo start --clear",
- "watch:android": "expo start --android",
- "watch:ios": "expo start --ios"
- },
- "resolutions": {
- "@types/react": "^18.0.0"
- },
- "dependencies": {
- "@apollo/client": "~3.7.1",
- "@cdm-logger/client": "^7.0.12",
- "@common-stack/client-core": "^0.5.1",
- "@common-stack/client-react": "^0.5.6",
- "@common-stack/core": "^0.5.1",
- "@expo/vector-icons": "~13.0.0",
- "@react-native-async-storage/async-storage": "~1.17.3",
- "@react-native-community/cameraroll": "~4.1.2",
- "@react-native-community/masked-view": "~0.1.10",
- "@react-native-community/netinfo": "9.3.0",
- "@react-native-community/picker": "~1.8.1",
- "@react-native-community/segmented-control": "~2.2.2",
- "@react-native-community/slider": "4.2.3",
- "@react-navigation/bottom-tabs": "^6.3.1",
- "@react-navigation/material-top-tabs": "^6.2.1",
- "@react-navigation/native": "^6.0.10",
- "@react-navigation/native-stack": "^6.6.2",
- "@react-navigation/stack": "^6.2.1",
- "@sample-stack/counter-module-mobile": "0.0.1",
- "apollo-link-debounce": "^3.0.0",
- "apollo-link-logger": "^2.0.0",
- "apollo-server-errors": "^3.3.1",
- "big-integer": "^1.6.51",
- "connected-react-router": "^6.9.1",
- "expo": "~46.0.16",
- "expo-asset": "~8.6.1",
- "expo-build-properties": "~0.3.0",
- "expo-constants": "~13.2.4",
- "expo-dev-client": "~1.3.1",
- "expo-device": "~4.3.0",
- "expo-file-system": "~14.1.0",
- "expo-image-picker": "~13.3.1",
- "expo-linking": "~3.2.2",
- "expo-localization": "~13.1.0",
- "expo-notifications": "~0.16.1",
- "expo-random": "~12.3.0",
- "expo-splash-screen": "~0.16.2",
- "expo-status-bar": "~1.4.0",
- "expo-updates": "~0.14.6",
- "expo-web-browser": "~11.0.0",
- "graphql-ws": "^5.11.2",
- "history": "^4.10.1",
- "immutability-helper": "^3.0.1",
- "inversify": "^5.0.1",
- "isomorphic-fetch": "^2.2.1",
- "lodash": "^4.17.4",
- "metro-minify-terser": "^0.56.0",
- "minilog": "^3.1.0",
- "native-base": "~3.2.2",
- "prop-types": "^15.6.0",
- "ramda": "^0.26.1",
- "react": "18.0.0",
- "react-dom": "18.0.0",
- "react-helmet": "^6.1.0",
- "react-loadable": "^5.5.0",
- "react-native": "0.69.6",
- "react-native-dotenv": "^3.3.1",
- "react-native-gesture-handler": "~2.5.0",
- "react-native-keyboard-aware-scroll-view": "^0.9.3",
- "react-native-keyboard-spacer": "^0.4.1",
- "react-native-maps": "~0.31.1",
- "react-native-mime-types": "^2.3.0",
- "react-native-modal": "^11.6.1",
- "react-native-reanimated": "~2.9.1",
- "react-native-safe-area-context": "^4.3.1",
- "react-native-screens": "~3.15.0",
- "react-native-svg": "~12.3.0",
- "react-native-web": "0.18.9",
- "react-native-web-maps": "~0.3.0",
- "react-redux": "^7.1.3",
- "react-router": "^5.3.3",
- "react-router-config": "^5.1.1",
- "react-router-dom": "^5.3.3",
- "react-router-native": "^5.3.3",
- "redux": "^4.0.5",
- "redux-logger": "^3.0.6",
- "redux-observable": "^1.2.0",
- "redux-persist": "^6.0.0",
- "redux-thunk": "^2.3.0",
- "reselect": "^4.0.0",
- "rxjs": "^6.5.3",
- "rxjs-compat": "^6.5.3",
- "rxjs-hooks": "^0.5.2",
- "sentry-expo": "~5.0.0",
- "text-encoding-polyfill": "^0.6.7"
- },
- "devDependencies": {
- "@babel/core": "^7.20.2",
- "@expo/config-plugins": "^5.0.0",
- "@expo/dev-server": "0.1.120",
- "@expo/webpack-config": "~18.0.1",
- "@testing-library/react-native": "^9.1.0",
- "@types/react-native": "~0.64.12",
- "@types/react-native-dotenv": "^0.2.0",
- "@types/react-native-keyboard-spacer": "^0.4.1",
- "@types/react-router-native": "^5.1.0",
- "typescript": "~4.7.3"
- },
- "peerDependencies": {
- "webpack": "*"
- }
-}
\ No newline at end of file
+ "name": "sample-stack-mobile-device",
+ "version": "0.0.1",
+ "private": true,
+ "main": "index.js",
+ "scripts": {
+ "android": "expo run:android",
+ "build": "yarn easBuild --profile development",
+ "build:all": "yarn build -p all",
+ "build:android": "yarn build -p android --clear-cache",
+ "build:auto": "yarn build:all --non-interactive",
+ "build:clean": "rimraf build .expo .tmp",
+ "build:configure": "eas build:configure",
+ "build:ios": "yarn build -p ios --clear-cache",
+ "build:preview": "yarn easBuild --profile preview",
+ "build:preview:all": "yarn build:preview -p all --non-interactive",
+ "build:preview:android": "yarn build:preview -p android --non-interactive",
+ "build:preview:ios": "yarn build:preview -p ios --non-interactive",
+ "build:previewLocal": "yarn easBuild --profile previewlocal",
+ "build:previewLocal:all": "yarn build:previewLocal -p all --non-interactive",
+ "build:previewLocal:android": "yarn build:previewLocal -p android --non-interactive",
+ "build:previewLocal:ios": "yarn build:previewLocal -p ios --non-interactive",
+ "build:previewSubmit": "yarn easBuild --profile previewSubmit --non-interactive",
+ "build:previewSubmit:all": "yarn build:previewSubmit -p all --auto-submit",
+ "build:previewSubmit:android": "yarn build:previewSubmit -p android --auto-submit",
+ "build:previewSubmit:ios": "yarn build:previewSubmit -p ios --auto-submit",
+ "build:prod": "yarn easBuild --profile production --non-interactive",
+ "build:prod:all": "yarn build:prod -p all",
+ "build:prod:android": "yarn build:prod -p android",
+ "build:prod:ios": "yarn build:prod -p ios",
+ "build:prod:manual": "yarn easBuild --profile production",
+ "build:prodSubmit:all": "yarn build:prod:all --auto-submit",
+ "build:prodSubmit:android": "yarn build:prod:android --auto-submit",
+ "build:prodSubmit:ios": "yarn build:prod:ios --auto-submit",
+ "build:stage": "yarn easBuild --profile staging -p ios --non-interactive",
+ "build:web": "cross-env GENERATE_SOURCEMAP=false expo export:web",
+ "cli": "node ../../tools/cli",
+ "eas-build-post-install": "lerna exec --scope=@sample-stack/core --scope=@sample-stack/counter-module-mobile yarn build",
+ "easBuild": "eas build",
+ "eslint": "eslint --fix --ext js --ext jsx --ext json src",
+ "exp-login": "cross-env NODE_ENV=production expo login -u $EXP_USERNAME -p $EXP_PASSWORD --non-interactive",
+ "exp-publish": "yarn exp-login && yarn expo p --non-interactive",
+ "ios": "expo run:ios",
+ "lint": "yarn eslint && yarn tslint",
+ "start": "expo start --dev-client",
+ "submit:all": "eas submit -p all",
+ "submit:android": "eas submit -p android",
+ "submit:ios": "eas submit -p ios",
+ "test": "yarn tests && yarn lint",
+ "tests": "jest",
+ "tests:watch": "jest --watch",
+ "tslint": "tslint --fix -p tsconfig.json -c ../../tslint.json",
+ "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env expo start --clear --localhost",
+ "watch:android": "expo start --android",
+ "watch:ios": "expo start --ios",
+ "watch:mobile": "cross-env NODE_ENV=development ENV_FILE=../../config/development/mobile.dev.env expo start --clear"
+ },
+ "resolutions": {
+ "@expo/config-plugins": "~6.0.0",
+ "@expo/prebuild-config": "~6.0.0",
+ "expo-modules-autolinking": "~1.1.0"
+ },
+ "dependencies": {
+ "@apollo/client": "^3.9.0",
+ "@cdm-logger/client": "^9.0.3",
+ "@common-stack/client-core": "^6.0.2-alpha.2",
+ "@common-stack/client-react": "^6.0.6-alpha.0",
+ "@common-stack/core": "^6.0.2-alpha.2",
+ "@expo/vector-icons": "~13.0.0",
+ "@react-native-async-storage/async-storage": "1.17.11",
+ "@react-native-community/cameraroll": "~4.1.2",
+ "@react-native-community/datetimepicker": "6.7.3",
+ "@react-native-community/masked-view": "~0.1.10",
+ "@react-native-community/netinfo": "9.3.7",
+ "@react-native-community/picker": "~1.8.1",
+ "@react-native-community/segmented-control": "~2.2.2",
+ "@react-native-community/slider": "4.4.2",
+ "@react-navigation/bottom-tabs": "^6.3.1",
+ "@react-navigation/drawer": "6.5.3",
+ "@react-navigation/native": "^6.0.10",
+ "@react-navigation/native-stack": "^6.6.2",
+ "@react-navigation/stack": "^6.2.1",
+ "@sample-stack/counter-module-mobile": "link:../../packages-modules/counter/mobile",
+ "apollo-link-debounce": "^3.0.0",
+ "apollo-link-logger": "^2.0.0",
+ "apollo-server-errors": "^3.3.1",
+ "big-integer": "^1.6.51",
+ "expo": "~48.0.20",
+ "expo-asset": "~8.9.1",
+ "expo-build-properties": "~0.6.0",
+ "expo-constants": "~14.2.1",
+ "expo-dev-client": "~2.2.1",
+ "expo-device": "~5.2.1",
+ "expo-file-system": "~15.2.2",
+ "expo-image-picker": "~14.1.1",
+ "expo-linking": "~4.0.1",
+ "expo-localization": "~14.1.1",
+ "expo-notifications": "~0.18.1",
+ "expo-random": "~13.1.1",
+ "expo-secure-store": "~12.1.1",
+ "expo-splash-screen": "~0.18.2",
+ "expo-status-bar": "~1.4.0",
+ "expo-updates": "~0.16.4",
+ "expo-web-browser": "~12.1.1",
+ "graphql-ws": "^5.11.2",
+ "immutability-helper": "^3.0.1",
+ "inversify": "^6.0.2",
+ "isomorphic-fetch": "^2.2.1",
+ "lodash": "^4.17.4",
+ "metro-minify-terser": "^0.56.0",
+ "minilog": "^3.1.0",
+ "native-base": "~3.4.19",
+ "prop-types": "^15.6.0",
+ "query-string": "7.0.1",
+ "ramda": "^0.26.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-helmet": "^6.1.0",
+ "react-loadable": "^5.5.0",
+ "react-native": "0.71.14",
+ "react-native-dotenv": "^3.3.1",
+ "react-native-gesture-handler": "~2.9.0",
+ "react-native-get-random-values": "~1.10.0",
+ "react-native-keyboard-aware-scroll-view": "^0.9.3",
+ "react-native-keyboard-spacer": "^0.4.1",
+ "react-native-maps": "1.3.2",
+ "react-native-mime-types": "^2.3.0",
+ "react-native-modal": "^11.6.1",
+ "react-native-pager-view": "6.1.2",
+ "react-native-reanimated": "~2.14.4",
+ "react-native-safe-area-context": "4.5.0",
+ "react-native-screens": "~3.20.0",
+ "react-native-svg": "13.4.0",
+ "react-native-url-polyfill": "^2.0.0",
+ "react-native-web": "~0.18.10",
+ "react-native-web-maps": "~0.3.0",
+ "react-redux": "^7.1.3",
+ "redux": "^4.0.5",
+ "redux-logger": "^3.0.6",
+ "redux-observable": "^1.2.0",
+ "redux-persist": "^6.0.0",
+ "redux-thunk": "^2.3.0",
+ "reselect": "^4.0.0",
+ "rxjs": "^6.5.3",
+ "rxjs-compat": "^6.5.3",
+ "rxjs-hooks": "^0.5.2",
+ "sentry-expo": "~6.2.0",
+ "text-encoding-polyfill": "^0.6.7"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.20.2",
+ "@expo/config-plugins": "^6.0.0",
+ "@expo/webpack-config": "^18.0.1",
+ "@testing-library/react-native": "^9.1.0",
+ "@types/react-native-dotenv": "^0.2.0",
+ "@types/react-native-keyboard-spacer": "^0.4.1",
+ "@types/react-router-native": "^5.1.0",
+ "typescript": "~4.9.5"
+ },
+ "peerDependencies": {
+ "webpack": "*"
+ }
+}
diff --git a/portable-devices/mobile/polyfills/browser.js b/portable-devices/mobile/polyfills/browser.js
new file mode 100644
index 000000000..928b792f3
--- /dev/null
+++ b/portable-devices/mobile/polyfills/browser.js
@@ -0,0 +1,53 @@
+(global => {
+
+ const { navigator } = global;
+ if (navigator) {
+ // userAgent
+ //
+ // Required by:
+ // - lib-jitsi-meet/modules/browser/BrowserDetection.js
+ let userAgent = navigator.userAgent || '';
+
+ // react-native/version
+ const { name, version } = require('react-native/package.json');
+ let rn = name || 'react-native';
+
+ version && (rn += `/${version}`);
+ if (userAgent.indexOf(rn) === -1) {
+ userAgent = userAgent ? `${rn} ${userAgent}` : rn;
+ }
+
+ // (OS version)
+ const os = `(${Platform.OS} ${Platform.Version})`;
+
+ if (userAgent.indexOf(os) === -1) {
+ userAgent = userAgent ? `${userAgent} ${os}` : os;
+ }
+
+ navigator.userAgent = userAgent;
+ }
+
+ // // CallStats
+ // //
+ // // Required by:
+ // // - lib-jitsi-meet
+ // require('react-native-callstats/csio-polyfill');
+ // global.callstats = require('react-native-callstats/callstats');
+
+
+ // // Timers
+ // //
+ // // React Native's timers won't run while the app is in the background, this
+ // // is a known limitation. Replace them with a background-friendly
+ // // alternative.
+ // //
+ // // Required by:
+ // // - lib-jitsi-meet
+ // // - Strophe
+ // global.clearTimeout = BackgroundTimer.clearTimeout.bind(BackgroundTimer);
+ // global.clearInterval = BackgroundTimer.clearInterval.bind(BackgroundTimer);
+ // global.setInterval = BackgroundTimer.setInterval.bind(BackgroundTimer);
+ // global.setTimeout = (fn, ms = 0) => BackgroundTimer.setTimeout(fn, ms);
+
+
+})(global || window || this); // eslint-disable-line no-invalid-this
\ No newline at end of file
diff --git a/portable-devices/mobile/src/App.tsx b/portable-devices/mobile/src/App.tsx
index ecaeb9bdb..03ba54884 100644
--- a/portable-devices/mobile/src/App.tsx
+++ b/portable-devices/mobile/src/App.tsx
@@ -1,68 +1,64 @@
import React from 'react';
-import { NativeRouter } from 'react-router-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { StyleSheet } from 'react-native';
-import { ApolloProvider } from '@apollo/client';
+import { ApolloProvider } from '@apollo/client/index.js';
import { Provider } from 'react-redux';
-import { MainRoute } from './modules/modules';
+import { SlotFillProvider } from '@common-stack/components-pro';
+import { NativeBaseProvider } from 'native-base';
+import { InversifyProvider, PluginArea } from '@common-stack/client-react';
+
+import modules, { MainRoute } from './modules/modules';
import { persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
-import { ConnectedRouter } from 'connected-react-router';
-import {
- createReduxStore,
- history,
-} from './config/redux-config';
-import { NativeBaseProvider } from 'native-base';
+import { createReduxStore, history } from './config/redux-config';
import { createClientContainer } from './config/client.service';
-const { apolloClient: client, container } = createClientContainer();
-
-const store = createReduxStore();
+const { apolloClient: client, container, serviceFunc } = createClientContainer();
+const { store } = createReduxStore(history, client, serviceFunc(), container);
export default function App() {
-
- let persistor = persistStore(store as any);
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
+ let persistor = persistStore(store as any);
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
}
const styles = StyleSheet.create({
- container: {
+ container: {
marginTop: 25,
- padding: 10,
- },
- header: {
+ padding: 10,
+ },
+ header: {
fontSize: 20,
- },
- nav: {
+ },
+ nav: {
flexDirection: 'row',
- justifyContent: 'space-around',
- },
- navItem: {
+ justifyContent: 'space-around',
+ },
+ navItem: {
flex: 1,
- alignItems: 'center',
- padding: 10,
- },
- subNavItem: {
+ alignItems: 'center',
+ padding: 10,
+ },
+ subNavItem: {
padding: 5,
- },
- topic: {
+ },
+ topic: {
textAlign: 'center',
- fontSize: 15,
- },
+ fontSize: 15,
+ },
});
diff --git a/portable-devices/mobile/src/config/base-apollo-client.ts b/portable-devices/mobile/src/config/base-apollo-client.ts
index a0a8724d6..6b31074d0 100755
--- a/portable-devices/mobile/src/config/base-apollo-client.ts
+++ b/portable-devices/mobile/src/config/base-apollo-client.ts
@@ -2,7 +2,7 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-underscore-dangle */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-import { ApolloClient, ApolloClientOptions, ApolloLink } from '@apollo/client';
+import { ApolloClient, ApolloClientOptions, ApolloLink } from '@apollo/client/index.js';
import { InMemoryCache } from '@apollo/client/cache';
import { HttpLink, createHttpLink } from '@apollo/client/link/http';
import { BatchHttpLink } from '@apollo/client/link/batch-http';
@@ -104,7 +104,8 @@ export const createApolloClient = ({
return param;
};
- let timedOut, activeSocket;
+ let timedOut: NodeJS.Timeout;
+ let activeSocket: unknown;
const wsLink = new GraphQLWsLink(
createClient({
diff --git a/portable-devices/mobile/src/config/base-redux-config.ts b/portable-devices/mobile/src/config/base-redux-config.ts
index 164bfa3fa..7e4388f02 100644
--- a/portable-devices/mobile/src/config/base-redux-config.ts
+++ b/portable-devices/mobile/src/config/base-redux-config.ts
@@ -14,6 +14,7 @@ import {
Action,
ReducersMapObject,
PreloadedState,
+ Store,
} from 'redux';
import { EpicMiddleware, Epic } from 'redux-observable';
import { persistReducer, PersistConfig } from 'redux-persist';
@@ -88,6 +89,7 @@ export const createReduxStore = ({
((isDev || isDebug) && isBrowser && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
const rootReducer = combineReducers(reducers);
+
const persistedReducer = persistConfig ? persistReducer(persistConfig, rootReducer) : rootReducer;
const store = createStore(persistedReducer, initialState, composeEnhancers(...enhancers()));
diff --git a/portable-devices/mobile/src/config/client.service.ts b/portable-devices/mobile/src/config/client.service.ts
index 8deaf36aa..05adff39c 100644
--- a/portable-devices/mobile/src/config/client.service.ts
+++ b/portable-devices/mobile/src/config/client.service.ts
@@ -1,47 +1,92 @@
+/* eslint-disable jest/require-hook */
/* eslint-disable no-underscore-dangle */
/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable import/no-extraneous-dependencies */
import { ClientTypes } from '@common-stack/client-core';
-import { Container } from 'inversify';
-import { ApolloClient } from '@apollo/client';
+import { Container, interfaces } from 'inversify';
+import { ApolloClient, NormalizedCacheObject } from '@apollo/client/index.js';
import { CdmLogger } from '@cdm-logger/core';
-import modules, { container, logger } from '../modules';
+import { merge } from 'lodash';
+import modules, { UtilityClass, logger } from '../modules';
import { createApolloClient } from './base-apollo-client';
import { PUBLIC_SETTINGS } from './public-config';
let __CLIENT_SERVICE__: {
apolloClient: ApolloClient;
container: Container;
- services: any;
- logger: CdmLogger.ILogger
+ serviceFunc: () => any;
+ logger: CdmLogger.ILogger;
};
-export const createClientContainer = () => {
- if (__CLIENT_SERVICE__) {
- return __CLIENT_SERVICE__;
- }
- const clientState = modules.getStateParams({ resolverContex: () => modules.createService({}, {}) });
- const { cache, apolloClient } = createApolloClient({
+const initialState = __CLIENT__ ? { ...window.__APOLLO_STATE__ } : {};
+const utility = new UtilityClass(modules);
+
+const container = modules.createContainers({}) as Container;
+container.bind(ClientTypes.Logger).toConstantValue(logger);
+container.bind(ClientTypes.UtilityClass).toConstantValue(utility);
+
+export const createClientContainer = (req?: any, res?: any) => {
+ logger.debug('Calling CreateClientContainer');
+
+ // const childContainer = container.createChild();
+ const childContainer = container;
+
+ childContainer
+ .bind(ClientTypes.ApolloClient)
+ .toDynamicValue((context) => new Error('Too early to bind ApolloClient'))
+ .inRequestScope();
+ childContainer
+ .bind<() => ApolloClient>(ClientTypes.ApolloClientFactory)
+ .toFactory>((context: interfaces.Context) => () => {
+ const newClient = childContainer.get>(ClientTypes.ApolloClient);
+ return newClient;
+ });
+ const services = merge(
+ { container: childContainer },
+ ...modules.createServiceFunc.map((serviceFunc) => serviceFunc(childContainer)),
+ );
+ const clientState = modules.getStateParams({
+ resolverContex: () => services,
+ container: childContainer,
+ requestResponsePair: {
+ req,
+ res
+ }
+ });
+ const { apolloClient, cache } = createApolloClient({
httpGraphqlURL: PUBLIC_SETTINGS.GRAPHQL_URL,
- httpLocalGraphqlURL: PUBLIC_SETTINGS.LOCAL_GRAPHQL_URL,
+ httpLocalGraphqlURL: PUBLIC_SETTINGS.LOCAL_GRAPHQL_URL as any,
isDev: process.env.NODE_ENV === 'development',
isDebug: __DEBUGGING__,
isSSR: __SSR__,
- scope: 'browser',
+ scope: __CLIENT__ ? 'browser' : 'server',
clientState,
getDataIdFromObject: (result) => modules.getDataIdFromObject(result),
- initialState: null,
+ initialState,
logger,
});
- // attaching the context to client as a workaround.
- container.bind(ClientTypes.ApolloClient).toConstantValue(apolloClient);
- container.bind(ClientTypes.InMemoryCache).toConstantValue(cache);
- const services = modules.createService({}, {});
- (apolloClient as any).container = services;
+ childContainer
+ .bind(ClientTypes.InMemoryCache)
+ .toDynamicValue((context) => cache)
+ .inRequestScope();
+ childContainer
+ .rebind(ClientTypes.ApolloClient)
+ .toDynamicValue((context) => apolloClient)
+ .inRequestScope();
+ // const services = serviceFunc();
+ const serviceFunc = () => services;
+ (apolloClient as any).container = services;
__CLIENT_SERVICE__ = {
- container,
+ container: childContainer,
apolloClient,
- services,
+ serviceFunc,
logger,
};
+ if ((module as any).hot) {
+ (module as any).hot.dispose(() => {
+ // Force Apollo to fetch the latest data from the server
+ delete window.__APOLLO_STATE__;
+ });
+ }
return __CLIENT_SERVICE__;
};
diff --git a/portable-devices/mobile/src/config/index.ts b/portable-devices/mobile/src/config/index.ts
index b2ca98492..54ddc2749 100644
--- a/portable-devices/mobile/src/config/index.ts
+++ b/portable-devices/mobile/src/config/index.ts
@@ -1,7 +1,9 @@
-import { LOG_LEVEL } from '@env';
+import {
+ LOG_LEVEL
+} from '@env';
const config = {
- LOG_LEVEL,
+ LOG_LEVEL
};
export default config;
diff --git a/portable-devices/mobile/src/config/redux-config.ts b/portable-devices/mobile/src/config/redux-config.ts
index 528ba2340..00450ec90 100644
--- a/portable-devices/mobile/src/config/redux-config.ts
+++ b/portable-devices/mobile/src/config/redux-config.ts
@@ -1,26 +1,28 @@
import storage from '@react-native-async-storage/async-storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import { createEpicMiddleware } from 'redux-observable';
-import { connectRouter, routerMiddleware } from 'connected-react-router';
import { REDUX_PERSIST_KEY } from '@common-stack/client-core';
import { createReduxStore as createBaseReduxStore } from './base-redux-config';
import modules, { logger } from '../modules';
import { rootEpic } from './epic-config';
import history from './router-history';
-import { createClientContainer } from './client.service';
export { history };
-const { apolloClient, container, services } = createClientContainer();
-export const epicMiddleware = createEpicMiddleware({
- dependencies: {
- apolloClient,
- routes: modules.getConfiguredRoutes(),
- services,
- container,
- logger,
- },
-});
+export const epicMiddlewareFunc = (apolloClient, services, container) =>
+ createEpicMiddleware({
+ dependencies: {
+ apolloClient,
+ routes: modules.getConfiguredRoutes(),
+ services,
+ container,
+ logger,
+ config: {
+ loadRoot: true,
+ isMobile: true,
+ },
+ },
+ });
export const persistConfig = {
key: REDUX_PERSIST_KEY,
@@ -33,22 +35,30 @@ export const persistConfig = {
* Add any reducers required for this app dirctly in to
* `combineReducers`
*/
-export const createReduxStore = () => {
+export const createReduxStore = (history, apolloClient, services, container) => {
// middleware
- const router = connectRouter(history);
-
const store = createBaseReduxStore({
scope: 'browser',
isDebug: __DEBUGGING__,
isDev: process.env.NODE_ENV === 'development',
initialState: {},
persistConfig,
- middleware: [routerMiddleware(history)],
- epicMiddleware,
+ middleware: [],
+ epicMiddleware: epicMiddlewareFunc(apolloClient, services, container),
rootEpic: rootEpic as any,
- reducers: { router, ...modules.reducers },
+ reducers: { ...modules.reducers },
});
- container.bind('ReduxStore').toConstantValue(store);
+ if (container.isBound('ReduxStore')) {
+ container
+ .rebind('ReduxStore')
+ .toDynamicValue(() => store)
+ .inRequestScope();
+ } else {
+ container
+ .bind('ReduxStore')
+ .toDynamicValue(() => store)
+ .inRequestScope();
+ }
- return store;
+ return { store };
};
diff --git a/portable-devices/mobile/src/modules/index.ts b/portable-devices/mobile/src/modules/index.ts
index ff3d29cef..c08565f92 100644
--- a/portable-devices/mobile/src/modules/index.ts
+++ b/portable-devices/mobile/src/modules/index.ts
@@ -1,14 +1,13 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable import/no-cycle */
/* eslint-disable @typescript-eslint/no-var-requires */
-import { ClientTypes } from '@common-stack/client-react';
-import { logger } from '@cdm-logger/client';
+import { ClientLogger } from '@cdm-logger/client';
import modules, { MainRoute } from './modules';
import { navigate } from './navigator';
Object.assign(global, require('../../build.config'));
-
-class UtilityClass {
+export class UtilityClass {
// tslint:disable-next-line:no-shadowed-variable
constructor(private modules) {}
@@ -16,16 +15,14 @@ class UtilityClass {
return this.modules.getDataIdFromObject(storeObj);
}
- public navigate(name: string, params: never){
+ public navigate(name: string, params: never) {
return navigate(name, params);
}
}
-const utility = new UtilityClass(modules);
-// additional bindings to container
-const container = modules.createContainers({}) as any;
-container.bind(ClientTypes.Logger).toConstantValue(logger);
-container.bind(ClientTypes.UtilityClass).toConstantValue(utility);
+const logger = ClientLogger.create(process.env.APP_NAME || 'Fullstack-Pro', {
+ level: (process.env.LOG_LEVEL as any) || 'info',
+});
export default modules;
-export { MainRoute, container, logger };
+export { MainRoute, logger };
diff --git a/portable-devices/mobile/webpack.config.js b/portable-devices/mobile/webpack.config.js
index 813439406..5bcaee619 100644
--- a/portable-devices/mobile/webpack.config.js
+++ b/portable-devices/mobile/webpack.config.js
@@ -35,6 +35,7 @@ module.exports = async function (env, argv) {
new EnvListPlugin.Plugin(),
);
config.plugins.push(
+ new EnvListPlugin.Plugin(),
new webpack.DefinePlugin({
__CLIENT__: true,
__DEBUGGING__: false,
diff --git a/rollup.config.base.mjs b/rollup.config.base.mjs
new file mode 100644
index 000000000..20f78f7be
--- /dev/null
+++ b/rollup.config.base.mjs
@@ -0,0 +1,147 @@
+// rollup.config.base.js
+import graphql from '@rollup/plugin-graphql';
+import image from '@rollup/plugin-image';
+import typescript from '@rollup/plugin-typescript';
+import { string } from 'rollup-plugin-string';
+import { copy } from '@web/rollup-plugin-copy';
+import modifyLibFilesPlugin from '@common-stack/rollup-vite-utils/lib/rollup/rollupPluginModifyLibFiles.js';
+import generateJsonFromObject from '@common-stack/rollup-vite-utils/lib/rollup/rollupPluginGenerateJson.js';
+import addJsExtensionToImportsPlugin from '@common-stack/rollup-vite-utils/lib/rollup/rollupPluginAddJsExtension.js';
+// Define any additional plugins specific to this bundle
+const additionalPlugins = [copy({ patterns: '**/cdm-locales/**/*', rootDir: './src' })];
+
+function deepMergeConfigs(baseConfig, specificConfig) {
+ const mergedConfig = { ...baseConfig, ...specificConfig };
+
+ // Assuming both configs have a plugins array; adjust logic as needed
+ if (baseConfig.plugins && specificConfig.plugins) {
+ mergedConfig.plugins = [...baseConfig.plugins, ...specificConfig.plugins];
+ }
+
+ return mergedConfig;
+}
+
+// Base configuration
+const baseConfig = {
+ plugins: [
+ image(),
+ graphql({ include: '**/*.gql' }),
+ string({
+ include: ['**/*.ejs', '**/*.graphql'],
+ }),
+ addJsExtensionToImportsPlugin({
+ packages: '*',
+ needToAddIndexJs: [],
+ excludeImports: ['@emotion/react/jsx-runtime'],
+ }),
+ typescript(), // TypeScript at the top as per best practices
+ modifyLibFilesPlugin({
+ include: ['**/**/compute.js'], // Adjust to target specific files or patterns
+ outputDir: 'lib', // Ensure this matches your actual output directory
+ }),
+ generateJsonFromObject({}),
+ ...additionalPlugins,
+ ],
+ external: (id) => !/^[./]/.test(id),
+ globals: { react: 'React' },
+};
+
+// Function to create a configuration by extending the base
+function createRollupConfig(overrides) {
+ return deepMergeConfigs(baseConfig, overrides);
+}
+function watch(watchOptions, buildMode = '') {
+ const filename = path.basename(watchOptions.input);
+ message(
+ 'note',
+ `${dt()} Rollup: Watcher Starting - watching for changes starting with: "${filename}" buildMode="${buildMode}"...`,
+ 'WATCH ',
+ true,
+ );
+ const watcher = rollup.watch(watchOptions);
+
+ watcher.on('event', (event) => {
+ // event.code can be one of:
+ // START — the watcher is (re)starting
+ // BUNDLE_START — building an individual bundle
+ // * event.input will be the input options object if present
+ // * event.output contains an array of the "file" or
+ // "dir" option values of the generated outputs
+ // BUNDLE_END — finished building a bundle
+ // * event.input will be the input options object if present
+ // * event.output contains an array of the "file" or
+ // "dir" option values of the generated outputs
+ // * event.duration is the build duration in milliseconds
+ // * event.result contains the bundle object that can be
+ // used to generate additional outputs by calling
+ // bundle.generate or bundle.write. This is especially
+ // important when the watch.skipWrite option is used.
+ // You should call "event.result.close()" once you are done
+ // generating outputs, or if you do not generate outputs.
+ // This will allow plugins to clean up resources via the
+ // "closeBundle" hook.
+ // END — finished building all bundles
+ // ERROR — encountered an error while bundling
+ // * event.error contains the error that was thrown
+ // * event.result is null for build errors and contains the
+ // bundle object for output generation errors. As with
+ // "BUNDLE_END", you should call "event.result.close()" if
+ // present once you are done.
+ // If you return a Promise from your event handler, Rollup will wait until the
+ // Promise is resolved before continuing.
+ // console.log(`rollup: ${event.code}`)
+ if (event.code === 'BUNDLE_END') {
+ const outputFiles = event.output.map((o) => path.basename(o)).join(', .../');
+ const msg = `${dt()} Rollup: wrote bundle${event.output.length > 1 ? 's' : ''}: ".../${outputFiles}"`;
+ if (NOTIFY) {
+ notifier.notify({
+ title: 'React Component Build',
+ message: msg,
+ });
+ }
+ // messenger: success, warn, critical, note, log
+ message('success', msg, 'SUCCESS', true);
+ } else if (event.code === 'ERROR') {
+ message('critical', `!!!!!!!!!!!!!!!\nRollup ${event.error}\n!!!!!!!!!!!!!!!\n`, 'ERROR', true);
+ if (NOTIFY) {
+ notifier.notify({
+ title: 'NotePlan Plugins Build',
+ message: `An error occurred during build process.\nSee console for more information`,
+ });
+ }
+ }
+ });
+
+ // This will make sure that bundles are properly closed after each run
+ watcher.on('event', ({ result }) => {
+ if (result) {
+ result.close();
+ }
+ });
+
+ // Additionally, you can hook into the following. Again, return a Promise to
+ // make Rollup wait at that stage:
+ watcher.on('change', (id /* , { event } */) => {
+ const filename = path.basename(id);
+ message('info', `${dt()} Rollup: file: "${filename}" changed`, 'CHANGE', true);
+ /* a file was modified */
+ });
+ watcher.on('restart', () => {
+ // console.log(`rollup: restarting`)
+ /* a new run was triggered (usually a watched file change) */
+ });
+ watcher.on('close', () => {
+ console.log(`rollup: closing`);
+ /* the watcher was closed, see below */
+ });
+ process.on('SIGINT', async function () {
+ console.log('\n\n');
+ console.log(colors.yellow('Quitting...\n'));
+ if (watcher) {
+ await watcher.close();
+ }
+ process.exit();
+ });
+}
+
+export { createRollupConfig, baseConfig };
diff --git a/servers/backend-server/Dockerfile b/servers/backend-server/Dockerfile
index 5994e4c07..d4aea9390 100755
--- a/servers/backend-server/Dockerfile
+++ b/servers/backend-server/Dockerfile
@@ -1,5 +1,5 @@
# The official nodejs docker image
-FROM node:16.17
+FROM node:20.16-bullseye
ENV PYTHON /usr/bin/python
@@ -11,6 +11,7 @@ COPY .npmrc /tmp/.npmrc
ADD package.json /tmp/package.json
RUN set -ex \
&& cd /tmp \
+ && npm install -g node-gyp \
&& yarn config set network-timeout 300000 \
&& yarn install \
&& rm -f /tmp/.npmrc \
@@ -23,7 +24,7 @@ WORKDIR /home/app
# Copy the rest of the files to the container workdir
ADD . /home/app
-ENV PORT=8080
+ENV PORT=9090
EXPOSE ${PORT}
CMD ["yarn", "start"]
diff --git a/servers/backend-server/__tests__/test.ts b/servers/backend-server/__tests__/test.ts
index 6c69ee903..016c65d90 100644
--- a/servers/backend-server/__tests__/test.ts
+++ b/servers/backend-server/__tests__/test.ts
@@ -1,44 +1,45 @@
-import { createServer } from "http";
-import express from "express";
-import { ApolloServer, gql } from "apollo-server-express";
-import { ApolloServerPluginDrainHttpServer } from "apollo-server-core";
-import { PubSub } from "graphql-subscriptions";
-import { makeExecutableSchema } from "@graphql-tools/schema";
-import { WebSocketServer } from "ws";
-import { useServer } from "graphql-ws/lib/use/ws";
+import { createServer } from 'http';
+import express from 'express';
+import { gql } from 'graphql';
+import { ApolloServer } from '@apollo/server';
+import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
+import { PubSub } from 'graphql-subscriptions';
+import { makeExecutableSchema } from '@graphql-tools/schema';
+import { WebSocketServer } from 'ws';
+import { useServer } from 'graphql-ws/lib/use/ws';
const PORT = 8080;
const pubsub = new PubSub();
// Schema definition
const typeDefs = gql`
- type Query {
- currentNumber: Int
- }
+ type Query {
+ currentNumber: Int
+ }
- type Subscription {
- numberIncremented: Int
- }
+ type Subscription {
+ numberIncremented: Int
+ }
`;
// Resolver map
const resolvers = {
- Query: {
- currentNumber() {
- return currentNumber;
+ Query: {
+ currentNumber() {
+ return currentNumber;
+ },
},
- },
- Subscription: {
- numberIncremented: {
- subscribe: () => pubsub.asyncIterator(["NUMBER_INCREMENTED"]),
+ Subscription: {
+ numberIncremented: {
+ subscribe: () => pubsub.asyncIterator(['NUMBER_INCREMENTED']),
+ },
},
- },
};
// Create schema, which will be used separately by ApolloServer and
// the WebSocket server.
const schema = makeExecutableSchema({ typeDefs, resolvers });
-console.log('--schema--', schema)
+console.log('--schema--', schema);
// Create an Express app and HTTP server; we will attach the WebSocket
// server and the ApolloServer to this HTTP server.
const app = express();
@@ -46,50 +47,46 @@ const httpServer = createServer(app);
// Set up WebSocket server.
const wsServer = new WebSocketServer({
- server: httpServer,
- path: "/graphql",
+ server: httpServer,
+ path: '/graphql',
});
const serverCleanup = useServer({ schema }, wsServer);
// Set up ApolloServer.
const server = new ApolloServer({
- schema,
- plugins: [
- // Proper shutdown for the HTTP server.
- ApolloServerPluginDrainHttpServer({ httpServer }),
+ schema,
+ plugins: [
+ // Proper shutdown for the HTTP server.
+ ApolloServerPluginDrainHttpServer({ httpServer }),
- // Proper shutdown for the WebSocket server.
- {
- async serverWillStart() {
- return {
- async drainServer() {
- await serverCleanup.dispose();
- },
- };
- },
- },
- ],
+ // Proper shutdown for the WebSocket server.
+ {
+ async serverWillStart() {
+ return {
+ async drainServer() {
+ await serverCleanup.dispose();
+ },
+ };
+ },
+ },
+ ],
});
await server.start();
server.applyMiddleware({ app });
// Now that our HTTP server is fully set up, actually listen.
httpServer.listen(PORT, () => {
- console.log(
- `🚀 Query endpoint ready at http://localhost:${PORT}${server.graphqlPath}`
- );
- console.log(
- `🚀 Subscription endpoint ready at ws://localhost:${PORT}${server.graphqlPath}`
- );
+ console.log(`🚀 Query endpoint ready at http://localhost:${PORT}${server.graphqlPath}`);
+ console.log(`🚀 Subscription endpoint ready at ws://localhost:${PORT}${server.graphqlPath}`);
});
// In the background, increment a number every second and notify subscribers when
// it changes.
let currentNumber = 0;
function incrementNumber() {
- currentNumber++;
- pubsub.publish("NUMBER_INCREMENTED", { numberIncremented: currentNumber });
- setTimeout(incrementNumber, 10000);
+ currentNumber++;
+ pubsub.publish('NUMBER_INCREMENTED', { numberIncremented: currentNumber });
+ setTimeout(incrementNumber, 10000);
}
// Start incrementing
incrementNumber();
diff --git a/servers/backend-server/build.config.mjs b/servers/backend-server/build.config.mjs
new file mode 100644
index 000000000..474f1121a
--- /dev/null
+++ b/servers/backend-server/build.config.mjs
@@ -0,0 +1,27 @@
+if (process.env.ENV_FILE !== null) {
+ import('dotenv').then(({ config }) => config({ path: process.env.ENV_FILE }));
+}
+
+const __API_SERVER_PORT__ = process.env.GRAPHQL_URL ? new URL(process.env.GRAPHQL_URL).port : 8080;
+const __SERVER_PROTOCOL__ = 'http';
+const __LOCAL_SERVER_HOST__ = 'localhost';
+const __GRAPHQL_ENDPOINT__ = process.env.GRAPHQL_URL ? new URL(process.env.GRAPHQL_URL).pathname : '/graphql';
+
+const config = {
+ __CLIENT__: false,
+ __SERVER__: true,
+ __DEV__: process.env.NODE_ENV !== 'production',
+ __TEST__: false,
+ 'process.env.NODE_ENV': process.env.NODE_ENV || 'development',
+ __GRAPHQL_URL__: process.env.GRAPHQL_URL || '/graphql',
+ __CDN_URL__: process.env.CDN_URL || '',
+ __FRONTEND_BUILD_DIR__: process.env.FRONTEND_BUILD_DIR || '../frontend-server/dist/web',
+ __API_SERVER_PORT__,
+ __GRAPHQL_ENDPOINT__,
+ __LOCAL_SERVER_HOST__,
+ __API_URL__:
+ process.env.API_URL ||
+ `${__SERVER_PROTOCOL__}://${__LOCAL_SERVER_HOST__}:${__API_SERVER_PORT__}${__GRAPHQL_ENDPOINT__}`,
+};
+
+export default config;
diff --git a/servers/backend-server/config.json b/servers/backend-server/config.json
new file mode 100644
index 000000000..50118cb78
--- /dev/null
+++ b/servers/backend-server/config.json
@@ -0,0 +1,5 @@
+{
+ "modules": ["@sample-stack/counter-module-server"],
+ "devModules": [],
+ "externalModules": []
+}
diff --git a/servers/backend-server/package.json b/servers/backend-server/package.json
index c4867554b..631885325 100755
--- a/servers/backend-server/package.json
+++ b/servers/backend-server/package.json
@@ -1,133 +1,86 @@
{
- "name": "sample-stack-backend-server",
- "version": "0.0.1",
- "private": true,
- "description": "Starter kit for apollo server using webpack and typescript",
- "keywords": [
- "apollo",
- "apollo-server",
- "backend",
- "express",
- "graphiql",
- "graphql",
- "typescript",
- "webpack"
- ],
- "homepage": "https://github.com/cdmbase/fullstack-pro#readme",
- "bugs": {
- "url": "https://github.com/cdmbase/fullstack-pro/issues"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/cdmbase/fullstack-pro.git"
- },
- "license": "MIT",
- "author": "CDMBase LLC",
- "main": "dist/index.js",
- "typings": "dist/main.d.ts",
- "scripts": {
- "build": "cross-env NODE_ENV=production webpack",
- "build:clean": "rimraf dist .awcache",
- "build:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env webpack",
- "db:migrate": "knex -- migrate:latest --cwd . --knexfile ./knexfile.js",
- "db:migrate:rollback": "knex -- migrate:rollback --cwd . --knexfile ./knexfile.js",
- "db:seed": "yarn db:migrate && knex -- seed:run --cwd . --knexfile ./knexfile.js",
- "docker:build": "yarn build && docker build . -t $npm_package_name:$npm_package_version",
- "docker:build:debug": "yarn build:debug && docker build . -t $npm_package_name:$npm_package_version",
- "docker:run": "docker run --env-file ../../config/staging/docker-staging.env -p 8080:8080 -it $npm_package_name:$npm_package_version",
- "docker:run:debug": "cross-env NODE_ENV=development docker run --env-file ../../config/staging/docker-staging.env -p 8080:8080 -it $npm_package_name:$npm_package_version",
- "proddb:migrate": "NODE_ENV=production yarn db:migrate",
- "proddb:migrate:rollback": "NODE_ENV=production yarn db:migrate:rollback",
- "proddb:seed": "NODE_ENV=production yarn db:seed",
- "prepublish": "yarn build:clean",
- "stagedb:migrate": "cross-env ENV_FILE=../../config/test/test.env NODE_ENV=test yarn db:migrate",
- "stagedb:migrate:rollback": "cross-env ENV_FILE=../../config/test/test.env NODE_ENV=test yarn db:migrate:rollback",
- "stagedb:seed": "cross-env ENV_FILE=../../config/test/test.env NODE_ENV=test yarn db:seed",
- "start": "cross-env NODE_ENV=production pm2-runtime dist/index.js",
- "start:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env node --harmony dist",
- "start:staging": "cross-env NODE_ENV=staging ENV_FILE=../../config/staging/staging.env node --harmony dist",
- "start:test": "cross-env NODE_ENV=test ENV_FILE=../../config/test/test.env node --harmony dist",
- "test": "jest",
- "test:notify": "yarn test:watch -- --notify",
- "test:watch": "npm test -- --watch",
- "preupver": "npm test",
- "upver": "standard-version",
- "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env webpack --watch --stats-error-details",
- "watch:debug": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env yarn zen:watch -- -v",
- "watch:staging": "cross-env NODE_ENV=test ENV_FILE=../../config/staging/staging.env yarn zen:watch",
- "watch:test": "cross-env NODE_ENV=test ENV_FILE=../../config/test/test.env yarn zen:watch",
- "zen:watch": "zen watch -x"
- },
- "resolutions": {
- "html-to-text": "^8.0.0"
- },
- "dependencies": {
- "@apollo/client": "~3.7.1",
- "@cdm-logger/server": "^7.0.12",
- "@common-stack/core": "0.5.1",
- "@common-stack/server-core": "0.5.1",
- "@common-stack/store-mongo": "0.5.3",
- "@babel/runtime": "^7.20.1",
- "@graphql-tools/links": "^8.3.21",
- "@graphql-tools/utils": "^8.0.0",
- "@graphql-tools/schema": "^8.3.14",
- "@graphql-tools/stitch": "^8.7.29",
- "@graphql-tools/wrap": "^8.4.20",
- "@sample-stack/core": "0.0.1",
- "@sample-stack/counter-module-server": "0.0.1",
- "@sample-stack/platform-server": "0.0.1",
- "@sample-stack/store": "0.0.1",
- "apollo-datasource": "^3.3.1",
- "apollo-datasource-rest": "^3.3.1",
- "apollo-errors": "^1.9.0",
- "apollo-server-cache-memcached": "^3.3.1",
- "apollo-server-cache-redis": "^3.3.1",
- "apollo-server-caching": "^3.3.0",
- "apollo-server-core": "^3.11.1",
- "apollo-server-errors": "^3.3.1",
- "apollo-server-express": "^3.11.1",
- "apollo-server-plugin-response-cache": "^3.8.1",
- "app-root-path": "^3.0.0",
- "body-parser": "^1.19.0",
- "cors": "^2.8.5",
- "dataloader": "^2.0.0",
- "dotenv": "^8.2.0",
- "envalid": "~7.2.2",
- "esm": "^3.2.25",
- "express": "^4.17.1",
- "graphql": "^15.0.0",
- "graphql-ws": "^5.11.2",
- "graphql-bigint": "^1.0.0",
- "graphql-nats-subscriptions": "^1.5.0",
- "graphql-subscriptions": "^2.0.0",
- "graphql-tools": "^8.0.0",
- "graphql-type-json": "^0.3.1",
- "inversify": "^5.0.1",
- "ioredis": "^4.14.0",
- "isomorphic-fetch": "^2.2.1",
- "lodash": "^4.17.15",
- "moleculer": "^0.14.2",
- "moleculer-zipkin": "0.2.2",
- "mongoose": "^6.3.3",
- "morgan": "^1.9.1",
- "nats": "^1.3.2",
- "react": "18.0.0",
- "reflect-metadata": "^0.1.13",
- "rxjs": "^6.5.3",
- "rxjs-compat": "^6.5.3",
- "subscriptions-transport-ws": "^0.11.0",
- "universal-cookie-express": "^4.0.1",
- "ws": "^8.11.0"
- },
- "devDependencies": {
- "cross-env": "^7.0.3",
- "pm2": "^5.2.2",
- "rimraf": "^3.0.2"
- },
- "peerDependencies": {
- "@cdm-logger/core": "*"
- },
- "typescript": {
- "definition": "dist/main.d.ts"
- }
-}
\ No newline at end of file
+ "name": "sample-stack-backend-server",
+ "version": "0.0.1",
+ "private": true,
+ "description": "Starter kit for apollo server using webpack and typescript",
+ "keywords": [
+ "apollo",
+ "apollo-server",
+ "backend",
+ "express",
+ "graphiql",
+ "graphql",
+ "typescript",
+ "webpack"
+ ],
+ "homepage": "https://github.com/cdmbase/fullstack-pro#readme",
+ "bugs": {
+ "url": "https://github.com/cdmbase/fullstack-pro/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/cdmbase/fullstack-pro.git"
+ },
+ "license": "MIT",
+ "author": "CDMBase LLC",
+ "main": "dist/index.js",
+ "typings": "dist/main.d.ts",
+ "scripts": {
+ "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
+ "build:clean": "rimraf dist .awcache",
+ "build:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env webpack --config webpack.config.js",
+ "db:migrate": "knex -- migrate:latest --cwd . --knexfile ./knexfile.js",
+ "db:migrate:rollback": "knex -- migrate:rollback --cwd . --knexfile ./knexfile.js",
+ "db:seed": "yarn db:migrate && knex -- seed:run --cwd . --knexfile ./knexfile.js",
+ "docker:build": "yarn build && docker build . -t $npm_package_name:$npm_package_version",
+ "docker:build:debug": "yarn build:debug && docker build . -t $npm_package_name:$npm_package_version",
+ "docker:run": "docker run --env-file ../../config/staging/docker-staging.env -p 8080:8080 -it $npm_package_name:$npm_package_version",
+ "docker:run:debug": "cross-env NODE_ENV=development docker run --env-file ../../config/staging/docker-staging.env -p 8080:8080 -it $npm_package_name:$npm_package_version",
+ "proddb:migrate": "NODE_ENV=production yarn db:migrate",
+ "proddb:migrate:rollback": "NODE_ENV=production yarn db:migrate:rollback",
+ "proddb:seed": "NODE_ENV=production yarn db:seed",
+ "prepublish": "yarn build:clean",
+ "stagedb:migrate": "cross-env ENV_FILE=../../config/test/test.env NODE_ENV=test yarn db:migrate",
+ "stagedb:migrate:rollback": "cross-env ENV_FILE=../../config/test/test.env NODE_ENV=test yarn db:migrate:rollback",
+ "stagedb:seed": "cross-env ENV_FILE=../../config/test/test.env NODE_ENV=test yarn db:seed",
+ "start": "cross-env NODE_ENV=production tsx dist/index.js",
+ "start:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env tsx watch dist/index.js",
+ "start:staging": "cross-env NODE_ENV=staging ENV_FILE=../../config/staging/staging.env tsx dist/index.js",
+ "start:test": "cross-env NODE_ENV=test ENV_FILE=../../config/test/test.env tsx dist/index.js",
+ "test": "jest",
+ "test:notify": "yarn test:watch -- --notify",
+ "test:watch": "npm test -- --watch",
+ "preupver": "npm test",
+ "upver": "standard-version",
+ "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env yarn build:dev && yarn start:dev",
+ "watch:staging": "cross-env NODE_ENV=test ENV_FILE=../../config/staging/staging.env yarn build && yarn start:stage",
+ "watch:test": "cross-env NODE_ENV=test ENV_FILE=../../config/test/test.env yarn build:test && yarn start:test",
+ "zen:watch": "zen watch -x"
+ },
+ "resolutions": {
+ "html-to-text": "^8.0.0"
+ },
+ "dependencies": {
+ "@apollo/client": "^3.9.0",
+ "@babel/runtime": "^7.20.1",
+ "@common-stack/server-stack": "6.0.6-alpha.0",
+ "@remix-run/node": "^2.8.1",
+ "@sample-stack/counter-module-server": "link:../../packages-modules/counter/server",
+ "@sample-stack/platform-server": "link:../../packages/sample-platform/server",
+ "@sample-stack/store": "link:../../packages/sample-store",
+ "lodash": "^4.17.15",
+ "react": "18.2.0",
+ "rxjs": "^6.5.3",
+ "rxjs-compat": "^6.5.3"
+ },
+ "devDependencies": {
+ "cross-env": "^7.0.3",
+ "esbuild-loader": "^4.2.2",
+ "pm2": "^5.2.2",
+ "rimraf": "^3.0.2",
+ "tsx": "^4.7.0"
+ },
+ "typescript": {
+ "definition": "dist/main.d.ts"
+ }
+}
diff --git a/servers/backend-server/src/api/remote-config.ts b/servers/backend-server/src/api/remote-config.ts
deleted file mode 100755
index 7a856b22b..000000000
--- a/servers/backend-server/src/api/remote-config.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-interface ISchemaConfig {
- uri: string;
- wsUri: string;
-}
-
-export const remoteSchemaDetails: ISchemaConfig[] = [
- // {
- // uri: 'http://localhost:8085/graphql',
- // wsUri: 'ws://localhost:8085/graphql',
- // },
-];
diff --git a/servers/backend-server/src/api/resolver.ts b/servers/backend-server/src/api/resolver.ts
deleted file mode 100755
index 1fec41193..000000000
--- a/servers/backend-server/src/api/resolver.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import GraphQLJSON, { GraphQLJSONObject } from 'graphql-type-json';
-
-export const resolvers = {
- JSON: GraphQLJSON,
- JSONObject: GraphQLJSONObject,
-};
diff --git a/servers/backend-server/src/api/root-schema.graphqls b/servers/backend-server/src/api/root-schema.graphqls
index 240600750..6a7551dc0 100755
--- a/servers/backend-server/src/api/root-schema.graphqls
+++ b/servers/backend-server/src/api/root-schema.graphqls
@@ -1,13 +1,65 @@
scalar AnyObject
+scalar Date
+scalar Time
+scalar DateTime
+scalar Timestamp
+scalar URI
+scalar URIInput
+scalar Observable
+
scalar JSON
scalar JSONObject
+
+directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT | INTERFACE
+enum CacheControlScope {
+ PUBLIC
+ PRIVATE
+}
+
+"""
+An object with an ID.
+"""
+interface Node {
+ """
+ The ID of the node.
+ """
+ id: ID!
+}
+
+# Pagination information. See https://facebook.github.io/relay/graphql/connections.htm#sec-undefined.PageInfo.
+type PageInfo {
+ # Whether there is a next page of nodes in the connection.
+ hasNextPage: Boolean!
+}
+
+"""
+Represents a null return value.
+"""
+type EmptyResponse {
+ # A dummy null value.
+ alwaysNil: String
+}
+
type FieldError {
- field: String!
- message: String!
+ field: String!
+ message: String!
+}
+
+input Sort {
+ key: String!
+ value: SortEnum!
+}
+
+enum SortEnum {
+ ASC
+ DESC
}
type Query {
- dummy: Int
+ """
+ Looks up a node by ID.
+ """
+ node(id: ID!): Node
}
type Mutation {
@@ -18,13 +70,47 @@ type Subscription {
dummy: Int
}
-interface Node {
- id: ID!
+type AdminIdeSettings {
+ dummy: Int
+}
+
+"""
+All Moleculer Topic names are extended from this.
+"""
+enum MoleculerServiceName {
+ dummy
+}
+
+interface IResourceUtilizationSettings {
+ subTopic: String
+ adminApiNamespace: String
}
+"""
+Input geometry of the location.
+List the `longitude` first and then `latitude`
+ - Validate longitude values are between `-180` and `180`
+ - Validate latitude values are between `-90` and `90`
+"""
+input GeoLocation_Input {
+ type: String = "Point"
+ coordinates: [Float]
+}
+
+type GeoLocation {
+ coordinates: [Float]
+}
+
+enum MailTemplateId {
+ dummy
+}
+
+enum MoleculerCronServiceName {
+ dummy
+}
schema {
query: Query
mutation: Mutation
subscription: Subscription
-}
\ No newline at end of file
+}
diff --git a/servers/backend-server/src/api/scalar.ts b/servers/backend-server/src/api/scalar.ts
deleted file mode 100755
index dbb43d5bc..000000000
--- a/servers/backend-server/src/api/scalar.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-// add any scalar types
-import { GraphQLError, GraphQLScalarType, Kind } from 'graphql';
-
-// https://stackoverflow.com/questions/41557536/custom-map-keys-in-graphql-response
-export const GraphQLAnyObject = new GraphQLScalarType({
- name: 'AnyObject',
- description: 'Any JSON object. This type bypasses type checking.',
- serialize: (value) => value,
- parseValue: (value) => value,
- parseLiteral: (ast) => {
- if (ast.kind !== Kind.OBJECT) {
- throw new GraphQLError(`Query error: Can only parse object but got a: ${ast.kind}`, [ast]);
- }
- return ast.fields;
- },
-});
diff --git a/servers/backend-server/src/api/schema-builder.ts b/servers/backend-server/src/api/schema-builder.ts
deleted file mode 100755
index 366c7f4cc..000000000
--- a/servers/backend-server/src/api/schema-builder.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-/* eslint-disable class-methods-use-this */
-/* eslint-disable no-useless-constructor */
-/* eslint-disable import/no-extraneous-dependencies */
-import * as fs from 'fs';
-import { GraphQLSchema, OperationDefinitionNode } from 'graphql';
-import { stitchSchemas } from '@graphql-tools/stitch';
-import { makeExecutableSchema } from '@graphql-tools/schema';
-import { linkToExecutor } from '@graphql-tools/links';
-import { introspectSchema, wrapSchema } from '@graphql-tools/wrap';
-// import { transformSchema } from '@graphql-tools/delegate';
-import * as ws from 'ws';
-import { getMainDefinition } from '@apollo/client/utilities';
-import { WebSocketLink } from '@apollo/client/link/ws';
-import { split } from '@apollo/client';
-import { logger } from '@common-stack/server-core';
-import { HttpLink } from '@apollo/client/link/http';
-import * as fetch from 'isomorphic-fetch';
-import { CdmLogger } from '@cdm-logger/core';
-import { remoteSchemaDetails } from './remote-config';
-import rootSchemaDef from './root-schema.graphqls';
-import { resolvers as rootResolver } from './resolver';
-import { attachDirectiveResolvers } from './utils';
-
-interface IGraphqlOptions {
- schema: string | string[];
- resolvers: any;
- directives: any[];
- directiveResolvers: { [key: string]: any};
- logger: CdmLogger.ILogger;
-}
-export class GatewaySchemaBuilder {
- constructor(private options: IGraphqlOptions) {}
-
- public async build(): Promise {
- let gatewaySchema;
- let ownSchema;
- try {
- ownSchema = this.createOwnSchema();
- const remoteSchema = await this.load();
- // techSchema = this.patchSchema(techSchema, 'TechService');
-
- gatewaySchema = stitchSchemas({
- subschemas: [ownSchema],
- });
- // TODO after updating graphql-tools to v8
- // addErrorLoggingToSchema(schema, { log: (e) => logger.error(e as Error) });
- } catch (err) {
- logger.error('[Graphql Schema Errors] when building schema:', err.message);
- gatewaySchema = ownSchema;
- }
-
- return gatewaySchema;
- }
-
- private async load() {
- const schemas = [];
- // eslint-disable-next-line no-plusplus
- for (let i = 0; i < remoteSchemaDetails.length; i++) {
- // eslint-disable-next-line no-await-in-loop
- const schema = await this.loadRemoteSchema(remoteSchemaDetails[i]);
- schemas.push(schema);
- }
- return schemas;
- }
-
- private async createRemoteSchema(service: string, iteration?: number): Promise {
- logger.info('Fetch service [%s] iteration [%s]', service, iteration);
- const services = remoteSchemaDetails;
- if (!services.length) {
- console.warn(`Service ${services} is undefined`);
- if (iteration && iteration > 2) {
- return Promise.reject(`tried upto ${iteration} attempts, now failing...`);
- }
- return new Promise((resolve, reject) => {
- const timeout = iteration ? 1000 * iteration : 1000;
- logger.info('Wait for service startup %s', timeout);
- setTimeout(() => {
- this.createRemoteSchema(service, iteration ? iteration + 1 : 1)
- .then(resolve)
- .catch(reject);
- }, timeout);
- });
- }
- // instead need to loop it
- // https://github.com/j-colter/graphql-gateway/blob/9c64d90a74727d2002d10b06f47e1f4a316070fc/src/schema.js#L50
- const url = services[0].uri;
- logger.info('fetch service [%s]', url);
- // 1. Create apollo Link that's connected to the underlying GraphQL API
- const link = new HttpLink({ uri: url, fetch });
- const executor: any = linkToExecutor(link);
- // 2. Retrieve schema definition of the underlying GraphQL API
- const remoteSchema = await introspectSchema(link as any);
-
- // 3. Create the executable schema based on schema definition and Apollo Link
- return wrapSchema({
- schema: remoteSchema,
- executor,
- });
- }
-
- private async loadRemoteSchema({ uri, wsUri }) {
- try {
- const httpLink = new HttpLink({ uri, fetch });
- let link = null;
-
- if (wsUri) {
- const wsLink = new WebSocketLink({
- uri: wsUri,
- options: {
- reconnect: true,
- },
- webSocketImpl: ws,
- });
- link = split(
- // split based on operatino type
- ({ query }) => {
- const { kind, operation } = getMainDefinition(query) as OperationDefinitionNode;
- return kind === 'OperationDefinition' && operation === 'subscription';
- },
- wsLink,
- httpLink,
- );
- } else {
- link = httpLink;
- }
- const executor: any = linkToExecutor(link);
- const remoteSchema = await introspectSchema(link);
- const executableSchema = wrapSchema({
- schema: remoteSchema,
- executor,
- });
- return executableSchema;
- } catch (err) {
- this.options.logger.error('fetching schema error: ', err);
- return {};
- }
- }
-
- // disabled after updating to apollo-client to v3 and graphql-tools to v8
- // private patchSchema(schema: GraphQLSchema, systemName: string) {
- // return transformSchema(schema, [
- // new RenameTypes((name: string) => (name === 'StatusInfo' ? `${systemName}StatusInfo` : undefined)),
- // new RenameRootFields((_operation: string, name: string) =>
- // name === 'status'
- // ? `${systemName.substring(0, 1).toLowerCase()}${systemName.substring(1)}Status`
- // : name,
- // ),
- // ]);
- // }
-
- private createOwnSchema(): GraphQLSchema {
- const typeDefs = [rootSchemaDef, this.options.schema].join('\n');
- if (__DEV__) {
- import('../modules/module').then(
- ({ ExternalModules }) => {
- const externalSchema = ExternalModules?.schemas || ``;
- const writeData = `${externalSchema}`;
- fs.writeFileSync('./generated-schema.graphql', writeData);
- }
- )
- }
- let mergedSchema = makeExecutableSchema({
- resolvers: [rootResolver, this.options.resolvers],
- typeDefs,
- resolverValidationOptions: {
- requireResolversForResolveType: 'warn',
- },
- });
- // mergedSchema = this.options.directives.reduce((curSchema,transform) => transform(curSchema), mergedSchema);
- if (this.options.directiveResolvers && Object.keys(this.options.directiveResolvers).length !== 0 ) {
- this.options.logger.warn('directiveResolvers deprecated replaced with directives');
- mergedSchema = attachDirectiveResolvers(mergedSchema, this.options.directiveResolvers);
- }
- return mergedSchema;
- }
-}
diff --git a/servers/backend-server/src/api/utils.ts b/servers/backend-server/src/api/utils.ts
deleted file mode 100644
index 45ae046dd..000000000
--- a/servers/backend-server/src/api/utils.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { defaultFieldResolver, GraphQLSchema } from 'graphql';
-import { mapSchema, MapperKind, getDirectives } from '@graphql-tools/utils';
-
-export function attachDirectiveResolvers(
- schema: GraphQLSchema,
- directiveResolvers: {[key: string]: Function},
-): GraphQLSchema {
- // ... argument validation ...
-
- return mapSchema(schema, {
- [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
- const newFieldConfig = { ...fieldConfig };
-
- const directives = getDirectives(schema, fieldConfig);
- for (const directive of directives) {
- const directiveName = directive.name;
- if (directiveResolvers[directiveName]) {
- const resolver = directiveResolvers[directiveName];
- const originalResolver =
- newFieldConfig.resolve != null ? newFieldConfig.resolve : defaultFieldResolver;
- const directiveArgs = directive.args;
- newFieldConfig.resolve = (source, originalArgs, context, info) => {
- return resolver(
- () =>
- new Promise((resolve, reject) => {
- const result = originalResolver(source, originalArgs, context, info);
- if (result instanceof Error) {
- reject(result);
- }
- resolve(result);
- }),
- source,
- directiveArgs,
- context,
- info,
- );
- };
- }
- }
-
- return newFieldConfig;
- },
- });
-}
diff --git a/servers/backend-server/src/config/env-config.ts b/servers/backend-server/src/config/env-config.ts
index 1874e8800..584a383d8 100755
--- a/servers/backend-server/src/config/env-config.ts
+++ b/servers/backend-server/src/config/env-config.ts
@@ -1,28 +1,12 @@
///
-import * as envalid from 'envalid';
+import { str, cleanEnv } from 'envalid';
-const { str, bool, json } = envalid;
-
-export const config = envalid.cleanEnv(process.env, {
+export const config = cleanEnv(process.env, {
NODE_ENV: str({ default: 'production', choices: ['production', 'staging', 'development', 'test'] }),
- NATS_URL: str({ devDefault: 'nats://localhost:4222/' }),
- NATS_USER: str({ devDefault: 'test' }),
- NATS_PW: str({ devDefault: 'test' }),
- MONGO_URL: str({ devDefault: 'mongodb://localhost:27017/sample-stack' }),
- LOG_LEVEL: str({ default: 'info', devDefault: 'trace', choices: ['info', 'debug', 'trace'] }),
- REDIS_CLUSTER_URL: json({
- devDefault: '[{"port":6379,"host":"localhost"}]',
- example: '[{"port":6379,"host":"localhost"}]',
- }),
- REDIS_URL: str({ devDefault: 'localhost' }),
- REDIS_CLUSTER_ENABLED: bool({ devDefault: false }),
- REDIS_SENTINEL_ENABLED: bool({ devDefault: true }),
- HEMERA_LOG_LEVEL: str({ default: 'info' }),
- BACKEND_URL: str({ devDefault: __BACKEND_URL__ }),
- GRAPHQL_URL: str({ devDefault: __GRAPHQL_URL__ }),
- CLIENT_URL: str({ devDefault: __BACKEND_URL__ }),
CONNECTION_ID: str({ devDefault: 'CONNECTION_ID' }),
NAMESPACE: str({ default: 'default' }),
+ ACTIVITY_NAMESPACE: str({ devDefault: 'default' }),
API_NAMESPACE: str({ devDefault: 'default' }),
ADMIN_API_NAMESPACE: str({ devDefault: 'default' }),
+ BACKEND_URL: str({ devDefault: __BACKEND_URL__ }),
});
diff --git a/servers/backend-server/src/config/moleculer.config.ts b/servers/backend-server/src/config/moleculer.config.ts
deleted file mode 100755
index cb61b4605..000000000
--- a/servers/backend-server/src/config/moleculer.config.ts
+++ /dev/null
@@ -1,227 +0,0 @@
-/* eslint-disable @typescript-eslint/no-empty-function */
-import { BrokerOptions, Errors } from 'moleculer';
-import { config } from './env-config';
-
-/**
- * Moleculer ServiceBroker configuration file
- *
- * More info about options:
- * https://moleculer.services/docs/0.14/configuration.html
- *
- *
- * Overwrite options in production:
- * ================================
- * You can overwrite any option with environment variables.
- * For example to overwrite the 'logLevel', use `LOGLEVEL=warn` env var.
- * To overwrite a nested parameter, e.g. retryPolicy.retries, use `RETRYPOLICY_RETRIES=10` env var.
- *
- * To overwrite broker’s deeply nested default options, which are not presented in 'moleculer.config.ts',
- * via environment variables, use the `MOL_` prefix and double underscore `__` for nested properties in .env file.
- * For example, to set the cacher prefix to `MYCACHE`, you should declare an env var as `MOL_CACHER__OPTIONS__PREFIX=MYCACHE`.
- */
-const brokerConfig: BrokerOptions = {
- // Namespace of nodes to segment your nodes on the same network.
- namespace: config.NAMESPACE,
- // namespace: null,
- // Unique node identifier. Must be unique in a namespace.
- // nodeID: config.CONNECTION_ID,
-
- // Enable/disable logging or use custom logger. More info: https://moleculer.services/docs/0.14/logging.html
- // Available logger types: 'Console', 'File', 'Pino', 'Winston', 'Bunyan', 'debug', 'Log4js', 'Datadog'
- logger: {
- type: 'Console',
- options: {
- // Using colors on the output
- colors: true,
- // Print module names with different colors (like docker-compose for containers)
- moduleColors: false,
- // Line formatter. It can be 'json', 'short',
- // 'simple', 'full', a `Function` or a template string like '{timestamp} {level} {nodeID}/{mod}: {msg}'
- formatter: 'full',
- // Custom object printer. If not defined, it uses the `util.inspect` method.
- objectPrinter: null,
- // Auto-padding the module name in order to messages begin at the same column.
- autoPadding: false,
- },
- },
- // Default log level for built-in console logger. It can be overwritten in logger options above.
- // Available values: trace, debug, info, warn, error, fatal
- logLevel: config.LOG_LEVEL as any,
-
- // Define transporter.
- // More info: https://moleculer.services/docs/0.14/networking.html
- // Note: During the development, you don't need to define it because all services will be loaded locally.
- // In production you can set it via `TRANSPORTER=nats://localhost:4222` environment variable.
- transporter:
- config.NODE_ENV === 'development'
- ? 'TCP'
- : {
- type: 'NATS',
- options: {
- url: config.NATS_URL,
- user: config.NATS_USER,
- pass: config.NATS_PW,
- reconnectTimeWait: 1000,
- },
- },
-
- // Define a cacher.
- // More info: https://moleculer.services/docs/0.14/caching.html
- // cacher: {
- // type: 'Redis',
- // enabled: false,
- // options: {
-
- // // Redis settings
- // redis: {
-
- // }
- // }
- // },
-
- // Define a serializer.
- // Available values: 'JSON', 'Avro', 'ProtoBuf', 'MsgPack', 'Notepack', 'Thrift'.
- // More info: https://moleculer.services/docs/0.13/networking.html
- serializer: 'JSON',
-
- // Number of milliseconds to wait before reject a request with a RequestTimeout error. Disabled: 0
- requestTimeout: 10 * 1000,
-
- // Retry policy settings. More info: https://moleculer.services/docs/0.13/fault-tolerance.html#Retry
- retryPolicy: {
- // Enable feature
- enabled: false,
- // Count of retries
- retries: 5,
- // First delay in milliseconds.
- delay: 100,
- // Maximum delay in milliseconds.
- maxDelay: 1000,
- // Backoff factor for delay. 2 means exponential backoff.
- factor: 2,
- // A function to check failed requests.
- check: (err: Errors.MoleculerRetryableError) => err && !!err.retryable,
- },
-
- // Limit of calling level. If it reaches the limit, broker will throw an MaxCallLevelError error. (Infinite loop protection)
- maxCallLevel: 100,
-
- // Number of seconds to send heartbeat packet to other nodes.
- heartbeatInterval: 5,
- // Number of seconds to wait before setting node to unavailable status.
- heartbeatTimeout: 15,
-
- // tslint:disable-next-line:max-line-length
- // Tracking requests and waiting for running requests before shutdowning. More info: https://moleculer.services/docs/0.13/fault-tolerance.html
- tracking: {
- // Enable feature
- enabled: false,
- // Number of milliseconds to wait before shutdowning the process
- shutdownTimeout: 5000,
- },
-
- // Disable built-in request & emit balancer. (Transporter must support it, as well.)
- disableBalancer: false,
-
- // Settings of Service Registry. More info: https://moleculer.services/docs/0.14/registry.html
- registry: {
- // Define balancing strategy. More info: https://moleculer.services/docs/0.14/balancing.html
- // Available values: 'RoundRobin', 'Random', 'CpuUsage', 'Latency'
- strategy: 'RoundRobin',
- // Enable local action call preferring.
- preferLocal: true,
- },
-
- // Settings of Circuit Breaker. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Circuit-Breaker
- circuitBreaker: {
- // Enable feature
- enabled: false,
- // Threshold value. 0.5 means that 50% should be failed for tripping.
- threshold: 0.5,
- // Minimum request count. Below it, CB does not trip.
- minRequestCount: 20,
- // Number of seconds for time window.
- windowTime: 60,
- // Number of milliseconds to switch from open to half-open state
- halfOpenTime: 10 * 1000,
- // A function to check failed requests.
- check: (err: Errors.MoleculerRetryableError) => err && err.code >= 500,
- },
-
- // Settings of bulkhead feature. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Bulkhead
- bulkhead: {
- // Enable feature.
- enabled: false,
- // Maximum concurrent executions.
- concurrency: 10,
- // Maximum size of queue
- maxQueueSize: 100,
- },
-
- // Enable action & event parameter validation. More info: https://moleculer.services/docs/0.14/validating.html
- validator: true,
-
- errorHandler: null,
-
- // Enable/disable built-in metrics function. More info: https://moleculer.services/docs/0.14/metrics.html
- metrics: {
- enabled: false,
- // Available built-in reporters: 'Console', 'CSV', 'Event', 'Prometheus', 'Datadog', 'StatsD'
- reporter: {
- type: 'Prometheus',
- options: {
- // HTTP port
- port: 3030,
- // HTTP URL path
- path: '/metrics',
- // Default labels which are appended to all metrics labels
- defaultLabels: (registry) => ({
- namespace: registry.broker.namespace,
- nodeID: registry.broker.nodeID,
- }),
- },
- },
- },
-
- // Enable built-in tracing function. More info: https://moleculer.services/docs/0.14/tracing.html
- tracing: {
- enabled: true,
- // Available built-in exporters: 'Console', 'Datadog', 'Event', 'EventLegacy', 'Jaeger', 'Zipkin'
- exporter: {
- type: 'Console', // Console exporter is only for development!
- options: {
- // Custom logger
- logger: null,
- // Using colors
- colors: true,
- // Width of row
- width: 100,
- // Gauge width in the row
- gaugeWidth: 40,
- },
- },
- },
-
- // Register internal services ('$node'). More info: https://moleculer.services/docs/0.13/services.html#Internal-services
- internalServices: true,
- // Register internal middlewares. More info: https://moleculer.services/docs/0.13/middlewares.html#Internal-middlewares
- internalMiddlewares: true,
-
- // Watch the loaded services and hot reload if they changed.
- // You can also enable it in Moleculer Runner with `--hot` argument
- hotReload: false,
-
- // Register custom middlewares
- middlewares: [],
-
- // Called after broker created.
- created(broker) {},
-
- // Called after broker starte.
- started(broker) {},
-
- // Called after broker stopped.
- stopped(broker) {},
-};
-
-export { brokerConfig };
diff --git a/servers/backend-server/src/connectors/connection-broker.ts b/servers/backend-server/src/connectors/connection-broker.ts
deleted file mode 100755
index 317b12abf..000000000
--- a/servers/backend-server/src/connectors/connection-broker.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-underscore-dangle */
-
-import { Transporter, GenericObject } from 'moleculer';
-import { CdmLogger } from '@cdm-logger/core';
-import { MongoConnector } from './mongo-connector';
-import { NatsConnector } from './nats-connector';
-import { RedisConnector } from './redis-connector';
-import { config } from '../config';
-import { GraphqlPubSubConnector } from './graphql-pubsub-connector';
-
-type ILogger = CdmLogger.ILogger;
-
-/**
- * Connection broker class
- *
- * @class ConnectionBroker
- */
-export class ConnectionBroker {
- private _mongoConnector: MongoConnector;
-
- private _redisConnector: RedisConnector;
-
- private _natsConnector: NatsConnector;
-
- private _graphqlPubsubConnector: GraphqlPubSubConnector;
-
- /**
- * Creates an instance of ConnectionBroker.
- * @param {*} options
- * @memberof ConnectionBroker
- */
- constructor(transporter: string | GenericObject, logger: ILogger) {
- if (typeof transporter === 'string') {
- if (transporter === 'TCP') {
- this._graphqlPubsubConnector = new GraphqlPubSubConnector({ logger, type: 'TCP' });
- } else if (transporter === 'NATS') {
- this._natsConnector = new NatsConnector({});
- this._graphqlPubsubConnector = new GraphqlPubSubConnector({
- logger,
- type: 'NATS',
- client: this._natsConnector,
- });
- }
- } else if (transporter.type === 'NATS') {
- this._natsConnector = new NatsConnector(transporter.options);
- this._graphqlPubsubConnector = new GraphqlPubSubConnector({
- logger,
- ...transporter,
- client: this._natsConnector,
- });
- }
-
- this._mongoConnector = new MongoConnector(config.MONGO_URL);
- this._redisConnector = new RedisConnector(); // TODO pass constructor options
- }
-
- public get mongoConnection() {
- return this._mongoConnector.connect();
- }
-
- public get redisDataloaderClient() {
- return this._redisConnector.getRedisDataloaderClient();
- }
-
- public get natsConnection() {
- return this._natsConnector.connect();
- }
-
- public get graphqlPubsub() {
- return this._graphqlPubsubConnector.getClient();
- }
-
- public async stop() {
- this._mongoConnector && (await this._mongoConnector.disconnect());
- this._redisConnector && (await this._redisConnector.disconnect());
- this._natsConnector && (await this._natsConnector.disconnect());
- }
-}
diff --git a/servers/backend-server/src/connectors/graphql-pubsub-connector.ts b/servers/backend-server/src/connectors/graphql-pubsub-connector.ts
deleted file mode 100755
index b90324d72..000000000
--- a/servers/backend-server/src/connectors/graphql-pubsub-connector.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/* eslint-disable no-return-assign */
-import { PubSub, PubSubEngine } from 'graphql-subscriptions';
-import { NatsPubSub } from 'graphql-nats-subscriptions';
-import { logger } from '@cdm-logger/server';
-import { GenericObject } from 'moleculer';
-import { CdmLogger } from '@cdm-logger/core';
-
-type ILogger = CdmLogger.ILogger;
-
-type PubSubOptions = {
- logger: ILogger;
-} & GenericObject;
-
-export class GraphqlPubSubConnector {
- private client: PubSubEngine | NatsPubSub;
-
- private opts: PubSubOptions;
-
- private logger: ILogger;
-
- /**
- * Creates an instance of GraphqlPubSubConnector.
- * @param {*} opts
- * @memberof GraphqlPubSubConnector
- */
- constructor(opts?: PubSubOptions) {
- this.opts = opts;
- this.logger = opts.logger.child({ className: 'GraphqlPubSubConnector' });
- }
-
- public async getClient() {
- if (this.opts.type === 'TCP') {
- return (this.client = new PubSub());
- }
- if (this.opts.type === 'NATS') {
- // console.log('--this.copts', this.opts.client)
- const natsClient = await this.opts.client.connect();
- return (this.client = new NatsPubSub({ client: natsClient, logger }));
- }
- this.logger.warn('Did not defined known transporter [%s], return default pubsub', this.opts.type);
- return (this.client = new PubSub());
- }
-}
diff --git a/servers/backend-server/src/connectors/mongo-connector.ts b/servers/backend-server/src/connectors/mongo-connector.ts
deleted file mode 100755
index 743b0f831..000000000
--- a/servers/backend-server/src/connectors/mongo-connector.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { createConnection, connection, Connection, ConnectOptions, plugin } from 'mongoose';
-import * as _ from 'lodash';
-import { Db } from 'mongodb';
-import { logger } from '@cdm-logger/server';
-import { CdmLogger } from '@cdm-logger/core';
-
-type ILogger = CdmLogger.ILogger;
-
-export class MongoConnector {
- private client: Connection;
-
- private db: Db;
-
- private opts: ConnectOptions;
-
- private uri: string;
-
- private logger: ILogger;
-
- constructor(uri: string, opts?: ConnectOptions) {
- this.opts = _.defaultsDeep(opts, {});
- this.uri = uri;
- this.logger = logger.child({ className: 'MongoConnector' });
- }
-
- /**
- * Connect to database
- *
- * @memberof MongoConnector
- */
- public async connect(): Promise {
- if (this.client) {
- return this.client;
- }
- const conn = createConnection(this.uri, this.opts).asPromise();
-
- conn.then((result) => {
- this.client = result;
- this.db = result.db;
- this.logger.info(' MongoDB has connected successfully.');
- result.on('disconnected', () => this.logger.warn('Mongoose has disconnected.'));
- result.on('error', (err) => this.logger.error('MongoDB error.', err));
- result.on('reconnect', () => this.logger.info('Mongoose has reconnected.'));
- });
-
- // eslint-disable-next-line @typescript-eslint/no-var-requires,global-require
- // plugin(require('@kolinalabs/mongoose-consistent'), {
- // actionDefault: 'no_action',
- // });
- return conn;
- }
-
- /**
- * Disconnect from database
- *
- * @memberof MongoConnector
- */
- public async disconnect() {
- if (!this.client) {
- return;
- }
- await connection.close();
- }
-}
diff --git a/servers/backend-server/src/connectors/nats-connector.ts b/servers/backend-server/src/connectors/nats-connector.ts
deleted file mode 100755
index 156fd2e28..000000000
--- a/servers/backend-server/src/connectors/nats-connector.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import * as nats from 'nats';
-import * as _ from 'lodash';
-import { logger } from '@cdm-logger/server';
-import { CdmLogger } from '@cdm-logger/core';
-
-type ILogger = CdmLogger.ILogger;
-
-export class NatsConnector {
- private opts: nats.ClientOpts;
-
- private client: nats.Client;
-
- private logger: ILogger;
-
- private connected: boolean;
-
- constructor(opts: nats.ClientOpts) {
- this.opts = _.defaultsDeep(opts, {});
- this.logger = logger.child({ className: 'NatsConnector' });
- }
-
- /**
- * Connect to a NATS server
- *
- * @memberof NatsConnector
- */
- public connect() {
- if (this.client) {
- return this.client;
- }
- return new Promise((resolve, reject) => {
- const client = nats.connect(this.opts);
-
- client.on('connect', () => {
- this.client = client;
- this.connected = true;
- this.logger.info('NATS client is connected.');
- resolve(client);
- });
-
- client.on('reconnect', () => {
- this.logger.info('NATS client is reconnected.');
- this.connected = true;
- });
-
- client.on('reconnecting', () => {
- this.logger.warn('NATS client is reconnecting...');
- });
-
- client.on('disconnect', () => {
- if (this.connected) {
- this.logger.warn('NATS client is disconnected.');
- this.connected = false;
- }
- });
-
- client.on('error', (e) => {
- this.logger.error('NATS error.', e.message);
- this.logger.debug(e);
- reject(e);
- });
-
- client.on('close', () => {
- this.logger.fatal('NATS connection close.');
- });
- });
- }
-
- /**
- * Disconnect from a NATS server
- *
- * @memberof NatsTransporter
- */
- public disconnect() {
- if (this.client) {
- this.client.flush(() => {
- this.client.close();
- this.client = null;
- });
- }
- }
-}
diff --git a/servers/backend-server/src/connectors/redis-connector.ts b/servers/backend-server/src/connectors/redis-connector.ts
deleted file mode 100755
index 950508046..000000000
--- a/servers/backend-server/src/connectors/redis-connector.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-import * as _ from 'lodash';
-import { RedisClusterCache, RedisCache } from 'apollo-server-cache-redis';
-import * as IORedis from 'ioredis';
-import { logger } from '@cdm-logger/server';
-import { config } from '../config';
-import { CdmLogger } from '@cdm-logger/core';
-type ILogger = CdmLogger.ILogger;
-
-export class RedisConnector {
-
-
- private client: RedisClusterCache | RedisCache;
- private opts: IORedis.ClusterOptions | IORedis.RedisOptions;
- private logger: ILogger;
-
- /**
- * Creats an instance of Redis.
- *
- * @param {object} opts
- */
- constructor(opts?: IORedis.ClusterOptions | IORedis.RedisOptions) {
- this.opts = _.defaultsDeep(opts, {
- prefix: null,
- });
- this.logger = logger.child({ className: 'RedisConnector' });
- }
-
- /**
- * Connect to the server
- *
- * @memberof RedisConnector
- */
- public connect() {
- return new Promise((resolve, reject) => {
- reject('this method not implemented');
- });
- }
-
-
- /**
- * Return redis or redis.cluster Dataloader Client
- *
- * @memberof RedisConnection
- */
- public getRedisDataloaderClient() {
- let client: RedisClusterCache | RedisCache;
- if (config.REDIS_CLUSTER_ENABLED) {
- if (!config.REDIS_CLUSTER_URL) {
- throw new Error(`No nodes defined for cluster, ${config.REDIS_CLUSTER_URL}`);
- }
- this.logger.info('Setting Redis.Cluster connection');
- client = new RedisClusterCache(config.REDIS_CLUSTER_URL as any, this.opts);
- } else {
- this.logger.info('Setting Redis connection');
- client = new RedisCache(config.REDIS_URL as any || this.opts);
- }
- return client;
- }
-
- /**
- * Close Redis client connection.
- *
- * @memberof RedisConnection
- */
- public disconnect() {
- if (!this.client) {
- return;
- }
- return this.client.close();
- }
-}
diff --git a/servers/backend-server/src/env.ts b/servers/backend-server/src/env.ts
new file mode 100644
index 000000000..12f15ea26
--- /dev/null
+++ b/servers/backend-server/src/env.ts
@@ -0,0 +1,5 @@
+/* eslint-disable jest/require-hook */
+import * as dotenv from 'dotenv';
+if (process.env.ENV_FILE) {
+ dotenv.config({ path: process.env.ENV_FILE });
+}
\ No newline at end of file
diff --git a/servers/backend-server/src/express-app.ts b/servers/backend-server/src/express-app.ts
deleted file mode 100755
index 2861c409e..000000000
--- a/servers/backend-server/src/express-app.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/* eslint-disable @typescript-eslint/no-var-requires */
-import * as express from 'express';
-
-import modules from './modules';
-import { errorMiddleware } from './middleware/error';
-import { contextServicesMiddleware } from './middleware/services';
-import { IModuleService } from './interfaces';
-
-const cookiesMiddleware = require('universal-cookie-express');
-
-export function expressApp(options: IModuleService, middlewares, http?) {
- const app: express.Express = express();
-
- app.use(contextServicesMiddleware(options.createContext, options.serviceContext));
-
- for (const applyBeforeware of modules.beforewares) {
- applyBeforeware(app);
- }
-
- app.use(cookiesMiddleware());
-
- // Don't rate limit heroku
- app.enable('trust proxy');
-
- if (middlewares !== null) {
- app.use(middlewares);
- }
-
- app.use('/', express.static(__FRONTEND_BUILD_DIR__, { maxAge: '180 days' }));
- app.use('/apollo-server-n-client/counter', express.static(__FRONTEND_BUILD_DIR__, { maxAge: '180 days' }));
-
- // app.use(corsMiddleware);
- app.use((req, res, next) => {
- res.header('Access-Control-Allow-Credentials', JSON.stringify(true));
- res.header('Access-Control-Allow-Origin', req.headers.origin as string);
- res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
- res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
- next();
- });
-
-
- const corsOptions = {
- origin: true,
- credentials: true,
- };
-
- for (const applyMiddleware of modules.middlewares) {
- applyMiddleware(app);
- }
-
- if (__DEV__) {
- app.use(errorMiddleware);
- }
-
- return app;
-}
diff --git a/servers/backend-server/src/index.ts b/servers/backend-server/src/index.ts
index ba7f2e90e..282ac7565 100755
--- a/servers/backend-server/src/index.ts
+++ b/servers/backend-server/src/index.ts
@@ -1,10 +1,6 @@
///
-import * as dotenv from 'dotenv';
+import './env';
import 'reflect-metadata';
-
-if (process.env.ENV_FILE) {
- dotenv.config({ path: process.env.ENV_FILE })
-}
import { logger } from '@cdm-logger/server';
import { Service } from './service';
diff --git a/servers/backend-server/src/interfaces/index.ts b/servers/backend-server/src/interfaces/index.ts
deleted file mode 100755
index 6e2ea68c1..000000000
--- a/servers/backend-server/src/interfaces/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './module-interface';
diff --git a/servers/backend-server/src/interfaces/module-interface.ts b/servers/backend-server/src/interfaces/module-interface.ts
deleted file mode 100755
index 7a27f2b40..000000000
--- a/servers/backend-server/src/interfaces/module-interface.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { GraphQLSchema } from 'graphql';
-import { CdmLogger } from '@cdm-logger/core';
-type ILogger = CdmLogger.ILogger;
-
-
-export interface IModuleService {
- serviceContainer: any;
- serviceContext: any;
- dataSource: any;
- defaultPreferences: any;
- createContext: any;
- schema: GraphQLSchema;
- logger: ILogger;
-}
-
-
diff --git a/servers/backend-server/src/main.spec.ts b/servers/backend-server/src/main.spec.ts
deleted file mode 100755
index 03d85636f..000000000
--- a/servers/backend-server/src/main.spec.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-// import {GRAPHQL_ROUTE, GRAPHIQL_ROUTE, main} from './main';
-// import {get as httpGet, Server} from 'http';
-// import 'jest';
-
-// const ERRNO_KEY = 'errno';
-// const PORT: number = 8080;
-
-// function getFromServer(uri) {
-// return new Promise((resolve, reject) => {
-// httpGet(`http://localhost:${PORT}${uri}`, (res) => {
-// resolve(res);
-// }).on('error', (err: Error) => {
-// reject(err);
-// });
-// });
-// }
-
-// describe('main', () => {
-// it('should be able to Initialize a server (production)', () => {
-// return main({
-// enableCors: false,
-// enableGraphiql: false,
-// env: 'production',
-// port: PORT,
-// })
-// .then(([server]) => {
-// return (server).close();
-// });
-// });
-
-// it('should be able to Initialize a server (development)', () => {
-// return main({
-// enableCors: true,
-// enableGraphiql: true,
-// env: 'dev',
-// port: PORT,
-// })
-// .then(([server]) => {
-// return (server).close();
-// });
-// });
-
-// it('should have a working GET graphql (developemnt)', () => {
-// return main({
-// enableCors: true,
-// enableGraphiql: true,
-// env: 'dev',
-// port: PORT,
-// })
-// .then(([server]) => {
-// return getFromServer(GRAPHQL_ROUTE).then((res: any) => {
-// (server).close();
-// // GET without query returns 400
-// expect(res.statusCode).toBe(400);
-// });
-// });
-// });
-
-// it('should have a working GET graphql (production)', () => {
-// return main({
-// enableCors: false,
-// enableGraphiql: false,
-// env: 'production',
-// port: PORT,
-// })
-// .then(([server]) => {
-// return getFromServer(GRAPHQL_ROUTE).then((res: any) => {
-// (server).close();
-// // GET without query returns 400
-// expect(res.statusCode).toBe(400);
-// });
-// });
-// });
-
-// it('should have a working graphiql (developemnt)', () => {
-// return main({
-// enableCors: true,
-// enableGraphiql: true,
-// env: 'dev',
-// port: PORT,
-// })
-// .then(([server]) => {
-// return getFromServer(GRAPHIQL_ROUTE).then((res: any) => {
-// (server).close();
-// expect(res.statusCode).toBe(200);
-// });
-// });
-// });
-
-// it('should have block graphiql (production)', () => {
-// return main({
-// enableCors: false,
-// enableGraphiql: false,
-// env: 'production',
-// port: PORT,
-// })
-// .then(([server]) => {
-// return getFromServer(GRAPHIQL_ROUTE).then((res: any) => {
-// (server).close();
-// expect(res.statusCode).toBe(404);
-// });
-// });
-// });
-
-// it('should reject twice on same port', () => {
-// return main({
-// enableCors: false,
-// enableGraphiql: false,
-// env: 'production',
-// port: PORT,
-// })
-// .then(([server]) => {
-// return main({
-// enableCors: false,
-// enableGraphiql: false,
-// env: 'production',
-// port: PORT,
-// })
-// .then(([secondServer]) => {
-// (server).close();
-// (secondServer).close();
-// throw new Error('Was able to listen twice!');
-// }, (err: Error) => {
-// (server).close();
-// expect(err[ERRNO_KEY]).toBe('EADDRINUSE');
-// });
-// });
-// });
-// });
diff --git a/servers/backend-server/src/middleware/cors.ts b/servers/backend-server/src/middleware/cors.ts
deleted file mode 100755
index 8f2ae69db..000000000
--- a/servers/backend-server/src/middleware/cors.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import * as cors from 'cors';
-import * as express from 'express';
-import { config } from '../config';
-import { logger } from '@cdm-logger/server';
-
-const CLIENT_URL = config.CLIENT_URL;
-const BACKEND_URL = config.BACKEND_URL;
-
-const corsWhitelist = [
- BACKEND_URL,
- CLIENT_URL,
- config.GRAPHQL_URL,
-];
-logger.info('Cors whitelist: %j', corsWhitelist);
-const corsOptions = {
- origin: (origin, callback) => {
- if (corsWhitelist.indexOf(origin) !== -1) {
- callback(null, true);
- } else {
- // TODO: only throw when in debug mode
- logger.error('url (%s) is not in the whitelist', origin);
- // callback(new Error('Not allowed by CORS'))
- logger.warn('allowing all origins temporarily, you need to disable it.');
- callback(null, true);
- }
- },
- credentails: false,
-};
-
-export const corsMiddleware = cors(corsOptions);
diff --git a/servers/backend-server/src/middleware/error.ts b/servers/backend-server/src/middleware/error.ts
deleted file mode 100755
index 719239079..000000000
--- a/servers/backend-server/src/middleware/error.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-///
-
-import * as path from 'path';
-import * as fs from 'fs';
-import * as url from 'url';
-import { logger } from '@cdm-logger/server';
-
-
-let assetMap;
-
-const stripCircular = (from, seen?: any) => {
- const to = Array.isArray(from) ? [] : {};
- seen = seen || [];
- seen.push(from);
- Object.getOwnPropertyNames(from).forEach(key => {
- if (!from[key] || (typeof from[key] !== 'object' && !Array.isArray(from[key]))) {
- to[key] = from[key];
- } else if (seen.indexOf(from[key]) < 0) {
- to[key] = stripCircular(from[key], seen.slice(0));
- } else { to[key] = '[Circular]'; }
- });
- return to;
-};
-
-const { pathname } = url.parse(__BACKEND_URL__);
-
-export const errorMiddleware =
- (e, req, res, next) => {
- if (req.path === pathname) {
- const stack = e.stack.toString().replace(/[\n]/g, '\\n');
- res.status(200).send(`[{"data": {}, "errors":[{"message": "${stack}"}]}]`);
- } else {
- logger.error(e);
-
- if (__DEV__ || !assetMap) {
- assetMap = JSON.parse(fs.readFileSync(path.join(__FRONTEND_BUILD_DIR__, 'assets.json')).toString());
- }
-
- const serverErrorScript = ``;
- const vendorScript = assetMap['vendor.js']
- ? ``
- : '';
-
- res.status(200).send(
- `${serverErrorScript}
- ${vendorScript}
-
- `,
- );
- }
- };
-
-
diff --git a/servers/backend-server/src/middleware/moleculer-inter-namespace.ts b/servers/backend-server/src/middleware/moleculer-inter-namespace.ts
deleted file mode 100644
index 4c6f1d8b1..000000000
--- a/servers/backend-server/src/middleware/moleculer-inter-namespace.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-/* eslint-disable no-param-reassign */
-import { ServiceBroker, Middleware } from 'moleculer';
-import * as _ from 'lodash';
-
-export const InterNamespaceMiddleware = function (options): Middleware {
- if (!Array.isArray(options)) {
- throw new Error('Must be an Array');
- }
-
- let thisBroker: ServiceBroker;
- const brokers: { [key: string]: ServiceBroker } = {};
-
- return {
- created(broker: ServiceBroker) {
- thisBroker = broker;
- options.forEach((nsOpts) => {
- if (_.isString(nsOpts)) {
- nsOpts = {
- namespace: nsOpts,
- };
- }
- const ns = nsOpts.namespace;
-
- const brokerOpts = _.defaultsDeep(
- {},
- nsOpts,
- { nodeID: null, middlewares: null, created: null, started: null },
- broker.options,
- );
- brokers[ns] = new ServiceBroker(brokerOpts);
- });
- },
-
- started() {
- return Promise.all(Object.values(brokers).map((b) => b.start()));
- },
-
- stopped() {
- return Promise.all(Object.values(brokers).map((b) => b.stop()));
- },
-
- call(next) {
- return function (actionName, params, opts = {}) {
- if (_.isString(actionName) && actionName.includes('@')) {
- const [action, namespace] = actionName.split('@');
-
- if (brokers[namespace]) {
- return brokers[namespace].call(action, params, opts);
- }
- if (namespace === thisBroker.namespace) {
- return next(action, params, opts);
- }
- throw new Error(`Unknown namespace: ${namespace}`);
- }
-
- return next(actionName, params, opts);
- };
- },
- };
-};
diff --git a/servers/backend-server/src/middleware/persistedQuery.ts b/servers/backend-server/src/middleware/persistedQuery.ts
deleted file mode 100755
index a392c8728..000000000
--- a/servers/backend-server/src/middleware/persistedQuery.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { invert, isArray } from 'lodash';
-import { GRAPHIQL_ROUTE } from '../ENDPOINTS';
-import { logger } from '@cdm-logger/server';
-
-let reqlib: any = require('app-root-path');
-
-let persistCache = true;
-let queryMap;
-try {
- queryMap = reqlib.require('@sample-stack/platform-browser/extracted_queries.json');
-
-} catch (err) {
- logger.warn('extracted_queries.json file is unavailable, disabling persist queries');
-}
-export const persistedQueryMiddleware = (req, res, next) => {
-
- if (queryMap) {
- const invertedMap = invert(queryMap);
-
- if (isArray(req.body)) {
- req.body = req.body.map(body => {
- const id = body['id'];
- return {
- query: invertedMap[id],
- ...body,
- };
- });
- next();
- } else {
- if (!__DEV__ || (req.get('Referer') || '').indexOf(GRAPHIQL_ROUTE) < 0) {
- res.status(500).send('Unknown GraphQL query has been received, rejecting...');
- } else {
- next();
- }
- }
- } else {
- next();
- }
-};
-
diff --git a/servers/backend-server/src/middleware/services.ts b/servers/backend-server/src/middleware/services.ts
deleted file mode 100755
index 4dc7cfcc3..000000000
--- a/servers/backend-server/src/middleware/services.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import 'isomorphic-fetch';
-
-
-export const contextServicesMiddleware = (createContext, serviceContext) => (req, res, next) => {
- Promise.all([
- createContext(req, res),
- serviceContext(req, res),
- ])
- .then(([ context, services ]) => {
- req.context = context;
- req.services = services;
-
- next();
- })
- .catch((err) => next());
-};
diff --git a/servers/backend-server/src/server-setup/graphql-server.ts b/servers/backend-server/src/server-setup/graphql-server.ts
deleted file mode 100755
index 39409ed5f..000000000
--- a/servers/backend-server/src/server-setup/graphql-server.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-import { ApolloServer, ApolloServerExpressConfig } from 'apollo-server-express';
-import 'isomorphic-fetch';
-import { Express } from 'express';
-import * as http from 'http';
-import { RedisClusterCache, RedisCache } from 'apollo-server-cache-redis';
-import { CdmLogger } from '@cdm-logger/core';
-import { ApolloServerPluginDrainHttpServer, ApolloServerPluginLandingPageDisabled } from 'apollo-server-core';
-import { WebSocketServer } from 'ws';
-import { IModuleService } from '../interfaces';
-import { GraphqlWs } from './graphql-ws';
-
-type ILogger = CdmLogger.ILogger;
-
-let debug = false;
-if ((process.env.LOG_LEVEL && process.env.LOG_LEVEL === 'trace') || process.env.LOG_LEVEL === 'debug') {
- debug = true;
-}
-
-// @workaround as the `dataSources` not available in Subscription (websocket) Context.
-// https://github.com/apollographql/apollo-server/issues/1526 need to revisit in Apollo-Server v3.
-const constructDataSourcesForSubscriptions = (context, cache, dataSources) => {
- const intializeDataSource = (instance) => {
- instance.initialize({ context, cache });
- };
- // tslint:disable-next-line:forin
- // eslint-disable-next-line guard-for-in
- for (const prop in dataSources) {
- // tslint:disable-next-line:no-console
- intializeDataSource(dataSources[prop]);
- }
- return dataSources;
-};
-
-let wsServerCleanup: any;
-export class GraphqlServer {
- private logger: ILogger;
-
- // private wsServerCleanup: any;
- constructor(
- private app: Express,
- private httpServer: http.Server,
- private cache: RedisCache | RedisClusterCache,
- private moduleService: IModuleService,
- private enableSubscription = true,
- ) {
- this.logger = this.moduleService.logger.child({ className: 'GraphqlServer' });
- if (enableSubscription) {
- const wsServer = new WebSocketServer({
- server: this.httpServer,
- path: __GRAPHQL_ENDPOINT__,
- });
- const graphqlWs = new GraphqlWs(wsServer, this.moduleService, this.cache);
- wsServerCleanup = graphqlWs.create();
- // wsServerCleanup = useServer({ schema: this.moduleService.schema}, wsServer)
- }
- }
-
- public async initialize() {
- this.logger.info('GraphqlServer initializing...');
- const apolloServer = this.configureApolloServer();
- await apolloServer.start();
- apolloServer.applyMiddleware({ app: this.app });
- this.logger.info('GraphqlServer initialized');
- }
-
- getUserIpAddress(req) {
- let ip = (req?.headers['x-forwarded-for'] || '').split(',')[0] || req?.connection?.remoteAddress;
- if (ip === '::1') {
- ip = '127.0.0.1';
- }
- return ip;
- }
-
- private configureApolloServer(): ApolloServer {
- const serverConfig: ApolloServerExpressConfig = {
- debug,
- schema: this.moduleService.schema,
- dataSources: () => this.moduleService.dataSource,
- cache: this.cache,
- context: async ({
- req,
- res,
- connection,
- }: {
- req: Express.Request;
- res: Express.Response;
- connection: any;
- }) => {
- let context;
- let addons = {};
- try {
- if (connection) {
- context = connection.context;
- if (!context.dataSources) {
- addons = {
- // @workaround for apollo server issue #1526
- dataSources: constructDataSourcesForSubscriptions(
- connection.context,
- this.cache,
- this.moduleService.dataSource,
- ),
- };
- } else {
- addons = {
- // @workaround for apollo server issue #1526
- dataSources: context.dataSources,
- };
- }
- } else {
- const pureContext = await this.moduleService.createContext(req, res);
- const contextServices = await this.moduleService.serviceContext(req, res);
- context = {
- ...pureContext,
- ...contextServices,
- preferences: this.moduleService.defaultPreferences,
- // update: updateContainers,
- };
- }
- context.userIp = this.getUserIpAddress(req);
- } catch (err) {
- this.logger.error('adding context to graphql failed due to [%o]', err);
- throw err;
- }
- return {
- req,
- // res,
- ...context,
- ...addons,
- };
- },
- plugins: [
- // process.env.NODE_ENV === 'production'
- // ? ApolloServerPluginLandingPageDisabled()
- // :
- // ApolloServerPluginLandingPageGraphQLPlayground(),
- // ApolloServerPluginLandingPageDisabled(),
- ApolloServerPluginDrainHttpServer({ httpServer: this.httpServer }),
- ],
- };
- if (this.enableSubscription) {
- serverConfig.plugins.push({
- async serverWillStart() {
- return {
- drainServer: async () => {
- await wsServerCleanup.dispose();
- },
- };
- },
- });
- }
- return new ApolloServer(serverConfig);
- }
-}
diff --git a/servers/backend-server/src/server-setup/graphql-subscription-server.ts b/servers/backend-server/src/server-setup/graphql-subscription-server.ts
deleted file mode 100755
index 5710beecf..000000000
--- a/servers/backend-server/src/server-setup/graphql-subscription-server.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-// import { SubscriptionServer, ConnectionContext, ExecutionParams } from 'subscriptions-transport-ws';
-// import { execute, subscribe, ExecutionResult } from 'graphql';
-// // import { GraphQLServerOptions } from 'apollo-server-core';
-// import { formatApolloErrors } from 'apollo-server-errors';
-// import { GraphQLServerOptions } from 'apollo-server-core/dist/graphqlOptions';
-// import { Context } from 'apollo-server-core';
-// import { RedisClusterCache, RedisCache } from 'apollo-server-cache-redis';
-// import { CdmLogger } from '@cdm-logger/core';
-// import { IModuleService } from '../interfaces';
-
-// type ILogger = CdmLogger.ILogger;
-
-// // @workaround as the `dataSources` not available in Subscription (websocket) Context.
-// // https://github.com/apollographql/apollo-server/issues/1526 need to revisit in Apollo-Server v3.
-// const constructDataSourcesForSubscriptions = (context, cache, dataSources) => {
-// const intializeDataSource = (instance) => {
-// instance.initialize({ context, cache });
-// };
-// // tslint:disable-next-line:forin
-// for (const prop in dataSources) {
-// // tslint:disable-next-line:no-console
-// intializeDataSource(dataSources[prop]);
-// }
-// return dataSources;
-// };
-
-// export class GraphqlSubscriptionServer {
-// private subscriptionServer: SubscriptionServer;
-
-// private context: Context;
-
-// private logger: ILogger;
-
-// constructor(
-// private moduleService: IModuleService,
-// private cache: RedisCache | RedisClusterCache,
-// private requestOptions: Partial> = Object.create(null),
-// ) {
-// this.logger = this.moduleService.logger.child({ className: 'GraphqlSubscriptionServer' });
-// }
-
-// public create() {
-// this.subscriptionServer = SubscriptionServer.create(
-// {
-// schema: this.moduleService.schema as any,
-// execute,
-// subscribe,
-// onConnect: async (connectionParams: any, webSocket: any, ctx: ConnectionContext) => {
-// try {
-// this.logger.debug(`Subscription client connected using built-in SubscriptionServer.`);
-// const pureContext = await this.moduleService.createContext(connectionParams, webSocket);
-// const contextServices = await this.moduleService.serviceContext(connectionParams, webSocket);
-// const context = {
-// ...contextServices,
-// ...pureContext,
-// preferences: this.moduleService.defaultPreferences,
-// // update: updateContainers,
-// wsCtx: ctx,
-// };
-// const addons = {
-// dataSources: constructDataSourcesForSubscriptions(
-// context,
-// this.cache,
-// this.moduleService.dataSource,
-// ),
-// };
-// return {
-// ...context,
-// ...addons,
-// };
-// } catch (e) {
-// this.logger.error(e);
-// }
-// },
-// onOperation: async (message: { payload: any }, connection: ExecutionParams) => {
-// connection.formatResponse = (value: ExecutionResult) => ({
-// ...value,
-// errors:
-// value.errors &&
-// formatApolloErrors([...value.errors], {
-// formatter: this.requestOptions.formatError,
-// debug: this.requestOptions.debug,
-// }),
-// });
-// let context: Context = this.context ? this.context : { connection };
-// try {
-// context =
-// typeof this.context === 'function'
-// ? await this.context({ connection, payload: message.payload })
-// : context;
-// } catch (e) {
-// throw formatApolloErrors([e], {
-// formatter: this.requestOptions.formatError,
-// debug: this.requestOptions.debug,
-// })[0];
-// }
-
-// return { ...connection }; // TODO: we didn't add `context`
-// },
-// },
-// {
-// noServer: true,
-// },
-// );
-// return this.subscriptionServer;
-// }
-
-// public disconnect() {
-// if (this.subscriptionServer) {
-// this.subscriptionServer.close();
-// }
-// }
-// }
diff --git a/servers/backend-server/src/server-setup/graphql-ws.ts b/servers/backend-server/src/server-setup/graphql-ws.ts
deleted file mode 100644
index 8563a79bb..000000000
--- a/servers/backend-server/src/server-setup/graphql-ws.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-import { useServer } from 'graphql-ws/lib/use/ws';
-import { GraphQLSchema, parse, getOperationAST, GraphQLError, validate } from 'graphql';
-import { GraphQLServerOptions } from 'apollo-server-core/dist/graphqlOptions';
-import { Context } from 'apollo-server-core';
-import { RedisClusterCache, RedisCache } from 'apollo-server-cache-redis';
-import { CdmLogger } from '@cdm-logger/core';
-import { Disposable, SubscribeMessage } from 'graphql-ws';
-import { WebSocketServer } from 'ws';
-import { IModuleService } from '../interfaces';
-import { createContextFromConnectionParams } from './utils';
-
-type ILogger = CdmLogger.ILogger;
-
-// @workaround as the `dataSources` not available in Subscription (websocket) Context.
-// https://github.com/apollographql/apollo-server/issues/1526 need to revisit in Apollo-Server v3.
-const constructDataSourcesForSubscriptions = (context, cache, dataSources) => {
- const intializeDataSource = (instance) => {
- instance.initialize({ context, cache });
- };
- // tslint:disable-next-line:forin
- for (const prop in dataSources) {
- // tslint:disable-next-line:no-console
- intializeDataSource(dataSources[prop]);
- }
- return dataSources;
-};
-
-/**
- * Accept only subscription operations
- * Code from graphql-ws recipes:
- * https://github.com/enisdenjo/graphql-ws/blob/master/README.md#recipes
- */
-function allowOnlySub(schema: GraphQLSchema, msg: SubscribeMessage) {
- // construct the execution arguments
- const args = {
- schema,
- operationName: msg.payload.operationName,
- document: parse(msg.payload.query),
- variableValues: msg.payload.variables,
- };
-
- const operationAST = getOperationAST(args.document, args.operationName);
- if (!operationAST) {
- // returning `GraphQLError[]` sends an `ErrorMessage` and stops the subscription
- return [new GraphQLError('Unable to identify operation')];
- }
-
- // handle mutation and query requests
- if (operationAST.operation !== 'subscription') {
- // returning `GraphQLError[]` sends an `ErrorMessage` and stops the subscription
- // return [new GraphQLError('Only subscription operations are supported')];
-
- // or if you want to be strict and terminate the connection on illegal operations
- throw new Error('Only subscription operations are supported');
- }
-
- // dont forget to validate
- const errors = validate(args.schema, args.document);
- if (errors.length > 0) {
- // returning `GraphQLError[]` sends an `ErrorMessage` and stops the subscription
- return errors;
- }
-
- // ready execution arguments
- return args;
-}
-
-export class GraphqlWs {
- private subscriptionServer: Disposable;
-
- private logger: ILogger;
-
- constructor(
- private wsServer: WebSocketServer,
- private moduleService: IModuleService,
- protected cache: RedisCache | RedisClusterCache,
- ) {}
-
- public create() {
- this.subscriptionServer = useServer(
- {
- schema: this.moduleService.schema,
- // Adding a context property lets you add data to your GraphQL operation context
- context: async (ctx) => {
- // Returning an object here will add that information to our
- // GraphQL context, which all of our resolvers have access to.
- // ctx is the `graphql-ws` Context where connectionParams live
- try {
- const pureContext = await this.moduleService.createContext(ctx.connectionParams, null);
- const contextServices = await this.moduleService.serviceContext(ctx.connectionParams, null);
- const context = {
- ...contextServices,
- ...pureContext,
- preferences: this.moduleService.defaultPreferences,
- // update: updateContainers,
- ...ctx,
- };
- const addons = {
- dataSources: constructDataSourcesForSubscriptions(
- context,
- this.cache,
- this.moduleService.dataSource,
- ),
- };
- return {
- ...context,
- ...addons,
- ...ctx,
- ...pureContext,
- preferences: this.moduleService.defaultPreferences,
- };
- } catch (err) {
- this.logger.error(err);
- }
- },
- // onConnect: async (ctx) => {
- // // do anything when connected
- // },
- // onOperation: (ctx, msg) => {
-
- // }
- // onOperation: async (message: { payload: any }, connection: ExecutionParams) => {
- // connection.formatResponse = (value: ExecutionResult) => ({
- // ...value,
- // errors:
- // value.errors &&
- // formatApolloErrors([...value.errors], {
- // formatter: this.requestOptions.formatError,
- // debug: this.requestOptions.debug,
- // }),
- // });
- // let context: Context = this.context ? this.context : { connection };
- // try {
- // context =
- // typeof this.context === 'function'
- // ? await this.context({ connection, payload: message.payload })
- // : context;
- // } catch (e) {
- // throw formatApolloErrors([e], {
- // formatter: this.requestOptions.formatError,
- // debug: this.requestOptions.debug,
- // })[0];
- // }
-
- // return { ...connection }; // TODO: we didn't add `context`
- // },
- },
- this.wsServer,
- );
- return this.subscriptionServer;
- }
-
- public disconnect() {
- if (this.subscriptionServer) {
- this.subscriptionServer.dispose();
- }
- }
-}
diff --git a/servers/backend-server/src/server-setup/utils.ts b/servers/backend-server/src/server-setup/utils.ts
deleted file mode 100644
index d531c09c5..000000000
--- a/servers/backend-server/src/server-setup/utils.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { RedisCache } from 'apollo-server-cache-redis';
-import { CdmLogger } from '@cdm-logger/core';
-
-type ILogger = CdmLogger.ILogger;
-
-// @workaround as the `dataSources` not available in Subscription (websocket) Context.
-// https://github.com/apollographql/apollo-server/issues/1526 need to revisit in Apollo-Server v3.
-const constructDataSourcesForSubscriptions = (context, cache, dataSources) => {
- const intializeDataSource = (instance) => {
- instance.initialize({ context, cache });
- };
- // tslint:disable-next-line:forin
- for (const prop in dataSources) {
- // tslint:disable-next-line:no-console
- intializeDataSource(dataSources[prop]);
- }
- return dataSources;
-};
-
-/**
- * It'll get messy below but there's an issue currently with the state of the protocols that can be used (subscriptions-transport-ws vs graphql-ws).
- * Read more from: https://www.apollographql.com/docs/apollo-server/data/subscriptions/#the-graphql-ws-transport-library
- *
- * Bottomline is, if we use the newer and actively maintained `graphql-ws` lib, then the GraphQL Playground will not work because it uses the old protocol.
- *
- * The approach below tries to support both based on the template provided here but adjusted for our setup here.
- * https://github.com/enisdenjo/graphql-ws#ws-backwards-compat
- */
-export async function createContextFromConnectionParams(
- context: any,
- datasources: any,
- cache: RedisCache,
- logger: ILogger,
-): Promise {
- // logger.debug(`Subscription client connected using built-in SubscriptionServer.`);
- const addons = {
- dataSources: constructDataSourcesForSubscriptions(context, cache, datasources),
- };
- return {
- ...context,
- ...addons,
- };
-}
\ No newline at end of file
diff --git a/servers/backend-server/src/server-setup/websocket-multipath-update.ts b/servers/backend-server/src/server-setup/websocket-multipath-update.ts
deleted file mode 100755
index 1cb518aa8..000000000
--- a/servers/backend-server/src/server-setup/websocket-multipath-update.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import * as url from 'url';
-// import { GraphqlSubscriptionServer } from './graphql-subscription-server';
-import { GraphqlWs } from './graphql-ws';
-import { WebSocketServer } from 'ws';
-import { Server } from 'http';
-import { RedisClusterCache, RedisCache } from 'apollo-server-cache-redis';
-import { IModuleService } from '../interfaces';
-import { useServer } from 'graphql-ws/lib/use/ws';
-
-interface WebSocketsCache {
- [key: string]: WebSocketServer;
-}
-
-interface MultiWebsocketConfig {
- [key: string]: any;
-}
-export class WebsocketMultiPathServer {
- private webSockets: WebSocketsCache = {};
- // private graphqlSubscriptionServer: GraphqlSubscriptionServer;
- private _graphqlWs: WebSocketServer;
- constructor(
- public moduleService: IModuleService,
- public cache: RedisCache | RedisClusterCache,
- multiplePathConfig?: MultiWebsocketConfig,
- ) {
- this._graphqlWs = new WebSocketServer({ noServer: true, path: __GRAPHQL_ENDPOINT__ });
- this.webSockets[__GRAPHQL_ENDPOINT__] = this._graphqlWs;
- this.webSockets[__GRAPHQL_ENDPOINT__].on('connection', (ws, request) => {
- console.log('--REQUESTED CONNECTION--', this._graphqlWs)
- useServer({
- schema: moduleService.schema,
- }, this._graphqlWs);
- });
-
- for (let key in multiplePathConfig) {
- if (!multiplePathConfig.hasOwnProperty(key)) {
- continue;
- }
-
- if (!this.webSockets[key]) {
- this.webSockets[key] = new WebSocketServer({ noServer: true });
- this.webSockets[key].on('connection', (ws, request) => {
- Promise.all([
- moduleService.createContext(request, null),
- moduleService.serviceContext(request, null),
-
- ]).then(multiplePathConfig[key](ws));
- });
- }
- }
- }
-
- public httpServerUpgrade(httpServer: Server) {
- httpServer.on('upgrade', (request, socket, head) => {
- const pathname = url.parse(request.url).pathname;
- console.log('--UPGRADE', request.url)
-
- if (!this.webSockets[pathname]) {
- // in development
- if (pathname !== '/sockjs-node') {
- // need to destroy
- socket.destroy();
- }
- }
-
- // code to run when a new connection is made
- this.webSockets[pathname].handleUpgrade(request, socket, head, (ws) => {
- this.webSockets[pathname].emit('connection', ws, request);
- });
- });
-
- // (new GraphqlWs(this.graphqlWs, this.moduleService, this.cache)).create();
- // useServer({
- // schema: this.moduleService.schema,
- // }, this.graphqlWs);
-
- return httpServer;
- }
-
- public get graphqlWs() {
- return this._graphqlWs;
- }
- public close() {
- for (const key in this.webSockets) {
- this.webSockets[key].close();
- }
- }
-}
diff --git a/servers/backend-server/src/service.ts b/servers/backend-server/src/service.ts
index 6f9ef5d36..33c8a9627 100755
--- a/servers/backend-server/src/service.ts
+++ b/servers/backend-server/src/service.ts
@@ -1,17 +1,16 @@
-import { StackServer } from './stack-server';
import { logger } from '@cdm-logger/server';
import * as url from 'url';
+import modules, { settings } from './modules';
+import { MainStackServer } from '@common-stack/server-stack';
import { config } from './config';
const { port: serverPort, pathname, hostname } = url.parse(config.BACKEND_URL);
export class Service {
-
- private app: StackServer;
+ private app: MainStackServer;
public async initialize() {
-
- this.app = new StackServer();
+ this.app = new MainStackServer(modules, settings);
await this.app.initialize();
}
diff --git a/servers/backend-server/src/stack-server.ts b/servers/backend-server/src/stack-server.ts
deleted file mode 100755
index e24923faa..000000000
--- a/servers/backend-server/src/stack-server.ts
+++ /dev/null
@@ -1,263 +0,0 @@
-/* eslint-disable import/namespace */
-/* eslint-disable import/no-unresolved */
-/* eslint-disable import/no-extraneous-dependencies */
-// version 08/25/2021
-import * as http from 'http';
-import * as express from 'express';
-import { logger as serverLogger } from '@cdm-logger/server';
-import { Feature } from '@common-stack/server-core';
-import { ContainerModule, interfaces, Container } from 'inversify';
-import { ServiceBroker, ServiceSettingSchema } from 'moleculer';
-import { CommonType } from '@common-stack/core';
-import * as _ from 'lodash';
-import { CdmLogger } from '@cdm-logger/core';
-import { expressApp } from './express-app';
-import { GraphqlServer } from './server-setup/graphql-server';
-import { config } from './config';
-import { ConnectionBroker } from './connectors/connection-broker';
-import { brokerConfig } from './config/moleculer.config';
-import modules, { settings } from './modules';
-import { GatewaySchemaBuilder } from './api/schema-builder';
-import { WebsocketMultiPathServer } from './server-setup/websocket-multipath-update';
-import { IModuleService } from './interfaces';
-import { migrate } from './utils/migrations';
-import { InterNamespaceMiddleware } from './middleware/moleculer-inter-namespace';
-// This is temp and will be replaced one we add support for rules in Feature
-
-type ILogger = CdmLogger.ILogger;
-
-function startListening(port) {
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- const server = this;
- return new Promise((resolve) => {
- server.listen(port, resolve);
- });
-}
-
-const infraModule = ({ broker, pubsub, mongoClient, logger }) =>
- new ContainerModule((bind: interfaces.Bind) => {
- bind('Logger').toConstantValue(logger);
- bind(CommonType.LOGGER).toConstantValue(logger);
- bind('Environment').toConstantValue(config.NODE_ENV || 'development');
- bind(CommonType.ENVIRONMENT).toConstantValue(config.NODE_ENV || 'development');
- bind('PubSub').toConstantValue(pubsub);
- bind(CommonType.PUBSUB).toConstantValue(pubsub);
- bind(CommonType.MOLECULER_BROKER).toConstantValue(broker);
- bind('MoleculerBroker').toConstantValue(broker);
- bind('MongoDBConnection').toConstantValue(mongoClient);
- });
-
-/**
- * Controls the lifecycle of the Application Server
- *
- * @export
- * @class StackServer
- */
-export class StackServer {
- public httpServer: http.Server & { startListening?: (port) => void };
-
- private app: express.Express;
-
- private logger: ILogger;
-
- private connectionBroker: ConnectionBroker;
-
- private mainserviceBroker: ServiceBroker;
-
- private microserviceBroker: ServiceBroker;
-
- private multiPathWebsocket: WebsocketMultiPathServer;
-
- private serviceContainer: Container;
-
- private microserviceContainer: Container;
-
- constructor() {
- this.logger = serverLogger.child({ className: 'StackServer' });
- }
-
- public async initialize() {
- this.logger.info('StackServer initializing');
-
- // eslint-disable-next-line import/namespace
- this.connectionBroker = new ConnectionBroker(brokerConfig.transporter, this.logger);
- const redisClient = this.connectionBroker.redisDataloaderClient;
-
- const mongoClient = await this.connectionBroker.mongoConnection;
-
- // Moleculer Broker Setup
- this.mainserviceBroker = new ServiceBroker({
- ...brokerConfig,
- middlewares: [
- InterNamespaceMiddleware([
- {
- namespace: 'api-admin',
- transporter: brokerConfig.transporter,
- },
- ]),
- ],
- started: async () => {
- await modules.preStart(this.serviceContainer);
- if (config.NODE_ENV === 'development') {
- // await modules.microservicePreStart(this.micorserviceContainer);
- }
-
- try {
- this.logger.info('Starting Migration');
- await migrate(mongoClient, this.serviceContainer, this.logger);
- this.logger.info('End Migration');
- } catch (e) {
- this.logger.error('Error while running migrations', e);
- this.logger.error(e.stack);
- }
-
- try {
- await modules.postStart(this.serviceContainer);
- } catch (e) {
- this.logger.error('Error while running Post Start', e);
- this.logger.error(e.stack);
- }
- // start DB migration
-
- if (config.NODE_ENV === 'development') {
- // await modules.microservicePostStart(this.micorserviceContainer);
- }
- },
-
- // created,
- async created() {
- return Promise.resolve();
- },
- });
-
- if (config.NODE_ENV === 'development') {
- this.microserviceBroker = new ServiceBroker({
- ...brokerConfig,
- nodeID: 'node-broker-2',
- started: async () => {
- await modules.microservicePreStart(this.microserviceContainer);
- await modules.microservicePostStart(this.microserviceContainer);
- },
- // created,
- created: async () => Promise.resolve(),
- });
- }
- const pubsub = await this.connectionBroker.graphqlPubsub;
- const InfraStructureFeature = new Feature({
- createContainerFunc: [
- () =>
- infraModule({
- broker: this.mainserviceBroker,
- pubsub,
- mongoClient,
- logger: serverLogger,
- }),
- ],
- createServiceFunc: (container) => ({ moleculerBroker: container.get(CommonType.MOLECULER_BROKER) }),
- createHemeraContainerFunc: [
- () =>
- infraModule({
- broker: this.mainserviceBroker,
- pubsub,
- mongoClient,
- logger: serverLogger,
- }),
- ],
- });
-
- const allModules = new Feature(InfraStructureFeature, modules as Feature);
- const executableSchema = await new GatewaySchemaBuilder({
- schema: allModules.schemas,
- resolvers: allModules.createResolvers({
- pubsub,
- logger: serverLogger,
- subscriptionID: `${settings.subTopic}`,
- }),
- directives: [],
- directiveResolvers: allModules.createDirectives({ logger: this.logger }),
- logger: serverLogger,
- }).build();
-
- // set the service container
- this.serviceContainer = await allModules.createContainers({ ...settings, mongoConnection: mongoClient });
- const createServiceContext = allModules.createServiceContext({ ...settings, mongoConnection: mongoClient });
- const serviceBroker: IModuleService = {
- serviceContainer: this.serviceContainer,
- serviceContext: createServiceContext,
- dataSource: allModules.createDataSource(),
- defaultPreferences: allModules.createDefaultPreferences(),
- createContext: async (req, res) => allModules.createContext(req, res),
- logger: serverLogger,
- schema: executableSchema,
- };
- allModules.loadMainMoleculerService({
- broker: this.mainserviceBroker,
- container: this.serviceContainer,
- settings,
- });
- if (config.NODE_ENV === 'development') {
- this.microserviceContainer = await allModules.createHemeraContainers({
- ...settings,
- mongoConnection: mongoClient,
- });
- allModules.loadClientMoleculerService({
- broker: this.microserviceBroker,
- container: this.microserviceContainer,
- settings,
- });
- }
-
- // initialize Servers
- this.httpServer = http.createServer();
- this.app = await expressApp(serviceBroker, null, this.httpServer);
-
- this.httpServer.startListening = startListening.bind(this.httpServer);
- this.httpServer.on('request', this.app);
- this.httpServer.on('close', () => {
- this.httpServer = undefined;
- });
-
- const customWebsocket = allModules.getWebsocketConfig();
- const customWebsocketEnable = !_.isEmpty(customWebsocket);
-
- if (customWebsocketEnable) {
- this.multiPathWebsocket = new WebsocketMultiPathServer(serviceBroker, redisClient, customWebsocket);
- this.httpServer = this.multiPathWebsocket.httpServerUpgrade(this.httpServer);
- }
- const graphqlServer = new GraphqlServer(
- this.app,
- this.httpServer,
- redisClient,
- serviceBroker,
- !customWebsocketEnable,
- );
-
- await graphqlServer.initialize();
- }
-
- public async start() {
- if (config.NODE_ENV === 'development') {
- await Promise.all([this.mainserviceBroker.start(), this.microserviceBroker.start()]);
- } else {
- await this.mainserviceBroker.start();
- }
- }
-
- public async cleanup() {
- if (this.multiPathWebsocket) {
- this.multiPathWebsocket.close();
- }
- if (this.httpServer) {
- await this.httpServer.close();
- }
- if (this.connectionBroker) {
- await this.connectionBroker.stop();
- }
- if (this.mainserviceBroker) {
- await this.mainserviceBroker.stop();
- }
- if (this.microserviceBroker) {
- await this.microserviceBroker.stop();
- }
- }
-}
diff --git a/servers/backend-server/src/utils/migrations.ts b/servers/backend-server/src/utils/migrations.ts
deleted file mode 100644
index 8301f25c0..000000000
--- a/servers/backend-server/src/utils/migrations.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable consistent-return */
-/* eslint-disable @typescript-eslint/no-unsafe-return */
-/* eslint-disable @typescript-eslint/no-unsafe-assignment */
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
-/* eslint-disable @typescript-eslint/no-unsafe-call */
-/* eslint-disable no-console */
-/* eslint-disable @typescript-eslint/restrict-template-expressions */
-import { Schema, Connection } from 'mongoose';
-import { Container } from 'inversify';
-import { CdmLogger } from '@cdm-logger/core';
-
-export const MigrationSchema = new Schema({
- migrated_at: Date,
- name: { required: true, type: String },
-});
-
-export async function migrate(db: Connection, container: Container, logger: CdmLogger.ILogger) {
- try {
- const migrations = container.getAll<{ up: any; id: any }>('MongodbMigration');
- const model = db.model('Migration', MigrationSchema);
- return await Promise.all(
- migrations.map(async (migration) => {
- const exists = await model.findOne({ name: migration.id });
- if (!exists) {
- logger.info('Migrating %s', migration.id);
- try {
- await migration.up();
- await model.create({ name: migration.id, migrated_at: new Date() });
- } catch (e) {
- console.log(`Can not process migration ${migration.id}: `, e);
- }
- }
- return migration.id;
- }),
- );
- } catch (err) {
- console.warn('ignoring migrate database due to ', err.message);
- }
-}
diff --git a/servers/backend-server/tsconfig.base.json b/servers/backend-server/tsconfig.base.json
new file mode 100755
index 000000000..ac196d55d
--- /dev/null
+++ b/servers/backend-server/tsconfig.base.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "es2017",
+ "module": "ESNext",
+ "esModuleInterop": true, // Important for ESM interoperability
+ "moduleResolution": "node",
+ "jsx": "react",
+ "declaration": true,
+ "experimentalDecorators": true,
+ "preserveConstEnums": true,
+ "sourceMap": true,
+ "noImplicitAny": false,
+ "skipLibCheck": true,
+ "allowSyntheticDefaultImports": false,
+ "pretty": true,
+ "removeComments": false,
+ "lib": ["es2017", "dom", "esnext.asynciterable"],
+ "types": ["@types/node", "@types/jest"]
+ },
+ "include": ["../../typings/*.d.ts"]
+}
diff --git a/servers/backend-server/tsconfig.json b/servers/backend-server/tsconfig.json
index 4eb65fc98..4f5dca92c 100755
--- a/servers/backend-server/tsconfig.json
+++ b/servers/backend-server/tsconfig.json
@@ -1,19 +1,13 @@
{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "sourceMap": true,
- "declaration": false,
- "allowSyntheticDefaultImports": true,
- "rootDirs": ["./src","../knexfile.ts"],
- "outDir": "./dist"
- },
- "include": [
- "../../typings/*.d.ts",
- ],
- "exclude": [
- "node_modules",
- "lib",
- "dist",
- "webpack.config.js"
- ]
-}
\ No newline at end of file
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "sourceMap": true,
+ "declaration": false,
+ "allowSyntheticDefaultImports": true,
+ "rootDirs": ["./src", "../knexfile.ts"],
+ "outDir": "./dist"
+ }
+}
diff --git a/servers/backend-server/webpack.config.js b/servers/backend-server/webpack.config.js
index 5d90d2c24..dbfc4c158 100755
--- a/servers/backend-server/webpack.config.js
+++ b/servers/backend-server/webpack.config.js
@@ -1,17 +1,37 @@
+process.env.ENV_FILE !== null && require('dotenv').config({ path: process.env.ENV_FILE });
const webpack = require('webpack');
const path = require('path');
-const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
-const Dotenv = require('dotenv-webpack');
const NodemonPlugin = require('nodemon-webpack-plugin'); // Ding
const EnvListPlugin = require('@common-stack/env-list-loader');
+const { writeBackendModuleFile } = require('@common-stack/rollup-vite-utils/lib/utils/utils.cjs');
+const packageConfig = require('./config.json');
const buildConfig = require('./build.config');
-const modulenameExtra = process.env.MODULENAME_EXTRA ? `${process.env.MODULENAME_EXTRA}|` : '';
-const modulenameRegex = new RegExp(
- `(${modulenameExtra}@sample-stack*|ts-invariant|webpack/hot/poll)|(\\.(css|less|scss|png|ico|jpg|gif|xml|woff|woff2|otf|ttf|eot|svg)(\\?[0-9a-z]+)?$)`,
-);
+const modulenameExtra = process.env.BUILD_MODULE_TO_INCLUDE ? `${process.env.BUILD_MODULE_TO_INCLUDE}|` : '';
+let modulenameRegex;
+
+try {
+ modulenameRegex = new RegExp(
+ `(${modulenameExtra}ts-invariant|@common-stack/server-stack|webpack/hot/poll)|(\\.(css|less|scss|png|ico|jpg|gif|xml|woff|woff2|otf|ttf|eot|svg)(\\?[0-9a-z]+)?$)`,
+ );
+ console.log('Module Name Regex: ', modulenameRegex);
+} catch (error) {
+ console.error('Error creating regex for module name: ', error);
+}
+
+if (process.env.BUILD_MODULE_TO_INCLUDE) {
+ console.log('Build Module to include (BUILD_MODULE_TO_INCLUDE): ', process.env.BUILD_MODULE_TO_INCLUDE);
+} else {
+ console.log('BUILD_MODULE_TO_INCLUDE is not set.');
+}
+
+try {
+ writeBackendModuleFile(path.join(__dirname, 'src/modules'), packageConfig);
+} catch (e) {
+ console.error(e);
+}
const config = {
entry: {
@@ -61,14 +81,32 @@ const config = {
{ loader: 'less-loader', options: { javascriptEnabled: true, sourceMap: true } },
],
},
- { test: /\.graphqls/, use: { loader: 'raw-loader' } },
+ { test: /\.graphqls$/, use: { loader: 'raw-loader' } },
{ test: /\.(graphql|gql)$/, use: [{ loader: 'graphql-tag/loader' }] },
+ // {
+ // test: /\.[tj]sx?$/,
+ // use: {
+ // loader: 'babel-loader',
+ // options: { babelrc: true, rootMode: 'upward-optional' },
+ // },
+ // },
{
- test: /\.[tj]sx?$/,
- use: {
- loader: 'babel-loader',
- options: { babelrc: true, rootMode: 'upward-optional' },
+ test: /\.tsx?$/, // for TypeScript
+ loader: 'esbuild-loader',
+ options: {
+ loader: 'tsx', // Or 'ts' for TypeScript without JSX
+ target: 'es2015', // Specify ECMAScript target version
},
+ exclude: /node_modules/,
+ },
+ {
+ test: /\.jsx?$/, // for JavaScript
+ loader: 'esbuild-loader',
+ options: {
+ loader: 'jsx', // Or 'js' for plain JavaScript
+ target: 'es2015',
+ },
+ exclude: /node_modules/,
},
{
// searches for files ends with /config/env-config.js or /config/public-config.js
@@ -82,6 +120,10 @@ const config = {
unsafeCache: false,
},
resolve: {
+ alias: {
+ // Define your alias here
+ '@src': path.resolve(__dirname, 'src'),
+ },
symlinks: true,
cacheWithContext: false,
unsafeCache: false,
@@ -102,7 +144,7 @@ const config = {
watchOptions: { ignored: /dist/ },
output: {
pathinfo: false,
- filename: 'main.js',
+ filename: 'index.js',
path: path.join(__dirname, 'dist'),
publicPath: '/',
sourceMapFilename: '[name].[chunkhash].js.map',
@@ -129,14 +171,14 @@ const config = {
})),
),
),
- new CopyWebpackPlugin({
- patterns: [
- {
- from: '../../tools/esm-wrapper.js',
- to: 'index.js',
- },
- ],
- }),
+ // new CopyWebpackPlugin({
+ // patterns: [
+ // {
+ // from: '../../tools/esm-wrapper.js',
+ // to: 'index.js',
+ // },
+ // ],
+ // }),
]),
target: 'node',
externals: [
diff --git a/servers/backend-server/webpack.config.mjs b/servers/backend-server/webpack.config.mjs
new file mode 100644
index 000000000..0eb0953cf
--- /dev/null
+++ b/servers/backend-server/webpack.config.mjs
@@ -0,0 +1,215 @@
+import 'source-map-support/register.js';
+import webpack from 'webpack';
+import path from 'path';
+import { fileURLToPath } from 'url';
+import CopyWebpackPlugin from 'copy-webpack-plugin';
+import { CleanWebpackPlugin } from 'clean-webpack-plugin';
+import nodeExternals from 'webpack-node-externals';
+import Dotenv from 'dotenv-webpack';
+import NodemonPlugin from 'nodemon-webpack-plugin';
+import EnvListPlugin from '@common-stack/env-list-loader';
+import { writeBackendModuleFile } from '@common-stack/rollup-vite-utils/lib/utils/utils.cjs';
+import buildConfig from './build.config.mjs';
+
+const modulenameExtra = process.env.BUILD_MODULE_TO_INCLUDE ? `${process.env.BUILD_MODULE_TO_INCLUDE}|` : '';
+let modulenameRegex;
+
+// Get the directory name of the current module
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+try {
+ modulenameRegex = new RegExp(
+ `(${modulenameExtra}ts-invariant|webpack/hot/poll)|(\\.(css|less|scss|png|ico|jpg|gif|xml|woff|woff2|otf|ttf|eot|svg)(\\?[0-9a-z]+)?$)`,
+ );
+ console.log('Module Name Regex: ', modulenameRegex);
+} catch (error) {
+ console.error('Error creating regex for module name: ', error);
+}
+
+if (process.env.BUILD_MODULE_TO_INCLUDE) {
+ console.log('Build Module to include (BUILD_MODULE_TO_INCLUDE): ', process.env.BUILD_MODULE_TO_INCLUDE);
+} else {
+ console.log('BUILD_MODULE_TO_INCLUDE is not set.');
+}
+
+try {
+ writeBackendModuleFile(path.join(__dirname, 'src/modules'), packageConfig);
+} catch (e) {
+ console.error(e);
+}
+
+const config = {
+ entry: {
+ // index: (process.env.NODE_ENV !== 'production' ? ['webpack/hot/poll?200'] : []).concat([
+ // // 'raf/polyfill',
+ // './src/index.ts',
+ // ]),
+ server: {
+ import: './src/index.ts',
+ /*
+ * This prevents code-splitting of async imports into separate chunks.
+ * We can't allow that for the server, because Webpack will duplicate
+ * certain modules that must be shared into each chunk (context,
+ * gettext, DBDefs, linkedEntities, ...).
+ */
+ chunkLoading: false,
+ },
+ },
+ name: 'server',
+ module: {
+ rules: [
+ {
+ test: /\.(png|ico|jpg|gif|xml)$/,
+ use: { loader: 'url-loader', options: { name: '[hash].[ext]', limit: 100000 } },
+ },
+ {
+ test: /\.woff(2)?(\?[0-9a-z]+)?$/,
+ use: { loader: 'url-loader', options: { name: '[hash].[ext]', limit: 100000 } },
+ },
+ {
+ test: /\.(otf|ttf|eot|svg)(\?[0-9a-z]+)?$/,
+ use: { loader: 'file-loader', options: { name: '[hash].[ext]' } },
+ },
+ {
+ test: /\.css$/,
+ use: [
+ { loader: 'isomorphic-style-loader' },
+ { loader: 'css-loader', options: { sourceMap: true } },
+ { loader: 'postcss-loader', options: { sourceMap: true } },
+ ],
+ },
+ {
+ test: /\.scss$/,
+ use: [
+ { loader: 'isomorphic-style-loader' },
+ { loader: 'css-loader', options: { sourceMap: true } },
+ { loader: 'postcss-loader', options: { sourceMap: true } },
+ { loader: 'sass-loader', options: { sourceMap: true } },
+ ],
+ },
+ {
+ test: /\.less$/,
+ use: [
+ { loader: 'isomorphic-style-loader' },
+ { loader: 'css-loader', options: { sourceMap: true } },
+ { loader: 'postcss-loader', options: { sourceMap: true } },
+ { loader: 'less-loader', options: { javascriptEnabled: true, sourceMap: true } },
+ ],
+ },
+ { test: /\.graphqls/, use: { loader: 'raw-loader' } },
+ { test: /\.(graphql|gql)$/, use: [{ loader: 'graphql-tag/loader' }] },
+ // {
+ // test: /\.[tj]sx?$/,
+ // use: {
+ // loader: 'babel-loader',
+ // options: { babelrc: true, rootMode: 'upward-optional' },
+ // },
+ // },
+ {
+ test: /\.tsx?$/, // for TypeScript
+ loader: 'esbuild-loader',
+ options: {
+ loader: 'tsx', // Or 'ts' for TypeScript without JSX
+ target: 'es2015', // Specify ECMAScript target version
+ },
+ exclude: /node_modules/,
+ },
+ {
+ test: /\.jsx?$/, // for JavaScript
+ loader: 'esbuild-loader',
+ options: {
+ loader: 'jsx', // Or 'js' for plain JavaScript
+ target: 'es2015',
+ },
+ exclude: /node_modules/,
+ },
+ {
+ // searches for files ends with /config/env-config.js or /config/public-config.js
+ test: /config\/(env-config|public-config)\.(j|t)s/,
+ use: {
+ loader: '@common-stack/env-list-loader',
+ },
+ },
+ { test: /locales/, use: { loader: '@alienfast/i18next-loader' } },
+ ],
+ unsafeCache: false,
+ },
+ resolve: {
+ symlinks: true,
+ cacheWithContext: false,
+ unsafeCache: false,
+ extensions: [
+ '.web.mjs',
+ '.web.js',
+ '.web.jsx',
+ '.web.ts',
+ '.web.tsx',
+ '.mjs',
+ '.js',
+ '.jsx',
+ '.ts',
+ '.tsx',
+ '.json',
+ ],
+ },
+ watchOptions: { ignored: /dist/ },
+ output: {
+ pathinfo: false,
+ filename: 'index.js',
+ path: path.join(__dirname, 'dist'),
+ // publicPath: '/',
+ sourceMapFilename: '[name].[chunkhash].js.map',
+ module: true, // Enable outputting ESM
+ library: {
+ type: 'module', // Specify library target as module
+ },
+ },
+ devtool: process.env.NODE_ENV === 'production' ? 'nosources-source-map' : 'cheap-module-source-map',
+ mode: process.env.NODE_ENV || 'development',
+ performance: { hints: false },
+ plugins: (process.env.NODE_ENV !== 'production'
+ ? [
+ // new Dotenv(),
+ new webpack.HotModuleReplacementPlugin(),
+ new NodemonPlugin({ script: './dist/index.js' }),
+ ]
+ : []
+ ).concat([
+ // The plugin lists the environment that required as well recommendation about the keys used.
+ new EnvListPlugin.Plugin(),
+ new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: ['dist'] }),
+ new webpack.DefinePlugin(
+ Object.assign(
+ ...Object.entries(buildConfig).map(([k, v]) => ({
+ [k]: typeof v !== 'string' ? v : `"${v.replace(/\\/g, '\\\\')}"`,
+ })),
+ ),
+ ),
+ // new CopyWebpackPlugin({
+ // patterns: [
+ // {
+ // from: '../../tools/esm-wrapper.js',
+ // to: 'index.js',
+ // },
+ // ],
+ // }),
+ ]),
+ target: 'node18',
+ experiments: {
+ outputModule: true,
+ },
+ externals: [
+ nodeExternals(),
+ nodeExternals({
+ modulesDir: path.resolve(__dirname, '../../node_modules'),
+ allowlist: [modulenameRegex],
+ }),
+ ],
+ optimization: {
+ concatenateModules: false,
+ minimize: false,
+ },
+ // node: { __dirname: true, __filename: true },
+};
+
+export default config;
diff --git a/servers/frontend-server/.dockerignore b/servers/frontend-server/.dockerignore
index 91e38de1d..e970f7fc4 100755
--- a/servers/frontend-server/.dockerignore
+++ b/servers/frontend-server/.dockerignore
@@ -1,5 +1,11 @@
*
+!app/
+!public/
+!tools/
!dist/
+!build/
+!server.ts
+!src
!*.js
!*.json
!.npmrc
\ No newline at end of file
diff --git a/servers/frontend-server/.eslintrc.cjs b/servers/frontend-server/.eslintrc.cjs
new file mode 100644
index 000000000..6bd1baae9
--- /dev/null
+++ b/servers/frontend-server/.eslintrc.cjs
@@ -0,0 +1,83 @@
+/**
+ * This is intended to be a basic starting point for linting in your app.
+ * It relies on recommended configs out of the box for simplicity, but you can
+ * and should modify this configuration to best suit your team's needs.
+ */
+
+/** @type {import('eslint').Linter.Config} */
+module.exports = {
+ root: true,
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ env: {
+ browser: true,
+ commonjs: true,
+ es6: true,
+ },
+
+ // Base config
+ extends: ["eslint:recommended"],
+
+ overrides: [
+ // React
+ {
+ files: ["**/*.{js,jsx,ts,tsx}"],
+ plugins: ["react", "jsx-a11y"],
+ extends: [
+ "plugin:react/recommended",
+ "plugin:react/jsx-runtime",
+ "plugin:react-hooks/recommended",
+ "plugin:jsx-a11y/recommended",
+ ],
+ settings: {
+ react: {
+ version: "detect",
+ },
+ formComponents: ["Form"],
+ linkComponents: [
+ { name: "Link", linkAttribute: "to" },
+ { name: "NavLink", linkAttribute: "to" },
+ ],
+ "import/resolver": {
+ typescript: {},
+ },
+ },
+ },
+
+ // Typescript
+ {
+ files: ["**/*.{ts,tsx}"],
+ plugins: ["@typescript-eslint", "import"],
+ parser: "@typescript-eslint/parser",
+ settings: {
+ "import/internal-regex": "^~/",
+ "import/resolver": {
+ node: {
+ extensions: [".ts", ".tsx"],
+ },
+ typescript: {
+ alwaysTryTypes: true,
+ },
+ },
+ },
+ extends: [
+ "plugin:@typescript-eslint/recommended",
+ "plugin:import/recommended",
+ "plugin:import/typescript",
+ ],
+ },
+
+ // Node
+ {
+ files: [".eslintrc.cjs", "server.js"],
+ env: {
+ node: true,
+ },
+ },
+ ],
+};
diff --git a/servers/frontend-server/.gitignore b/servers/frontend-server/.gitignore
new file mode 100644
index 000000000..d236ff75d
--- /dev/null
+++ b/servers/frontend-server/.gitignore
@@ -0,0 +1,2 @@
+app/*
+public/cdm-locales/*
\ No newline at end of file
diff --git a/servers/frontend-server/Dockerfile b/servers/frontend-server/Dockerfile
index 7c582b257..7fba7469a 100755
--- a/servers/frontend-server/Dockerfile
+++ b/servers/frontend-server/Dockerfile
@@ -1,5 +1,5 @@
# The official nodejs docker image
-FROM node:16.17-alpine
+FROM node:20.16-bullseye
ENV PYTHON /usr/bin/python
# Copy package.json only to temp folder, install its dependencies,
@@ -10,6 +10,7 @@ COPY .npmrc /tmp/.npmrc
ADD package.json /tmp/package.json
RUN set -ex \
&& cd /tmp \
+ && npm install -g node-gyp \
&& yarn config set network-timeout 300000 \
&& yarn install \
&& rm -f /tmp/.npmrc \
@@ -17,6 +18,7 @@ RUN set -ex \
&& cp -a /tmp/node_modules /home/app/ \
&& rm -Rf /tmp/*
+
WORKDIR /home/app
# Copy the rest of the files to the container workdir
diff --git a/servers/frontend-server/babel.config.js b/servers/frontend-server/babel.config.js
deleted file mode 100644
index c7513fd62..000000000
--- a/servers/frontend-server/babel.config.js
+++ /dev/null
@@ -1,48 +0,0 @@
-module.exports = (api) => {
- const isTest = api.env('test');
- api.cache(true);
- if (isTest) {
- return {
- compact: false,
- presets: [
- '@babel/preset-typescript',
- '@babel/preset-react',
- ['@babel/preset-env', { modules: 'commonjs' }],
- ],
- plugins: [
- 'babel-plugin-dynamic-import-node',
- '@babel/plugin-transform-destructuring',
- '@babel/plugin-transform-modules-commonjs',
- ['@babel/plugin-transform-for-of'],
- '@babel/plugin-transform-regenerator',
- '@babel/plugin-transform-runtime',
- ['@babel/plugin-proposal-decorators', { legacy: true }],
- '@babel/plugin-proposal-class-properties',
- '@babel/plugin-proposal-object-rest-spread',
- '@babel/plugin-proposal-optional-chaining',
- ],
- };
- }
- return {
- compact: false,
- presets: ['@babel/preset-typescript', '@babel/preset-react', ['@babel/preset-env', { modules: false }]],
- plugins: [
- '@babel/plugin-syntax-dynamic-import',
- '@loadable/babel-plugin',
- '@babel/plugin-transform-modules-commonjs',
- '@babel/plugin-transform-destructuring',
- ['@babel/plugin-transform-for-of'],
- '@babel/plugin-transform-regenerator',
- '@babel/plugin-transform-runtime',
- ['@babel/plugin-proposal-decorators', { legacy: true }],
- '@babel/plugin-proposal-class-properties',
- '@babel/plugin-proposal-object-rest-spread',
- '@babel/plugin-proposal-optional-chaining',
- ],
- env: {
- production: {
- compact: true,
- },
- },
- };
-};
diff --git a/servers/frontend-server/build.config.js b/servers/frontend-server/build.config.js
deleted file mode 100644
index 6f5c9ee57..000000000
--- a/servers/frontend-server/build.config.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const config = {
- ...require('../../build.config'),
- __CLIENT__: true,
- __SERVER__: false,
- __DEV__: process.env.NODE_ENV !== 'production',
- __TEST__: false,
- __CDN_URL__: process.env.CDN_URL || '',
- __GRAPHQL_URL__: process.env.GRAPHQL_URL || '/graphql',
- __API_URL__: process.env.API_URL || '/graphql',
- __FRONTEND_BUILD_DIR__: process.env.FRONTEND_BUILD_DIR || './dist/web',
-};
-
-module.exports = config;
diff --git a/servers/frontend-server/codecept.json b/servers/frontend-server/codecept.json
new file mode 100644
index 000000000..5b3b62c80
--- /dev/null
+++ b/servers/frontend-server/codecept.json
@@ -0,0 +1,28 @@
+{
+ "output": "./e2e/output",
+ "helpers": {
+ "Puppeteer": {
+ "show": true,
+ "url": "http://localhost:3000"
+ }
+ },
+ "include": {
+ "I": "./e2e/steps_file.js",
+ "loginPage": "./e2e/pages/Login.js",
+ "dashboardPage": "./e2e/pages/Dashboard.js",
+ "workspaceFormPage": "./e2e/pages/WorkspaceForm.js"
+ },
+ "mocha": {},
+ "bootstrap": false,
+ "teardown": null,
+ "hooks": [],
+ "gherkin": {},
+ "plugins": {
+ "screenshotOnFail": {
+ "enabled": true
+ }
+ },
+ "tests": "./e2e/**/*_test.js",
+ "timeout": 10000,
+ "name": "frontend-server"
+}
diff --git a/servers/frontend-server/config.json b/servers/frontend-server/config.json
new file mode 100644
index 000000000..78bf08f1f
--- /dev/null
+++ b/servers/frontend-server/config.json
@@ -0,0 +1,45 @@
+{
+ "commonPaths": {
+ "appPath": "app",
+ "frontendStackPath": "frontend-stack-react"
+ },
+ "copyOperations": [
+ {
+ "packageName": "@common-stack/frontend-stack-react",
+ "destPath": "$.commonPaths.frontendStackPath",
+ "generateModule": true
+ }
+ ],
+ "i18n": {
+ "enabled": true,
+ "fallbackLng": "en",
+ "supportedLngs": ["en", "de", "es"],
+ "defaultNS": "common",
+ "react": {
+ "useSuspense": false
+ },
+ "backend": {
+ "loadPath": "/cdm-locales/{{lng}}/{{ns}}.json",
+ "loadServerPath": "./public/cdm-locales/{{lng}}/{{ns}}.json"
+ },
+ "packages": []
+ },
+ "modules": ["@sample-stack/counter-module-browser"],
+ "buildConfig": {
+ "__CLIENT__": false,
+ "__SERVER__": true,
+ "__DEV__": false,
+ "__TEST__": false,
+ "__CDN_URL__": "",
+ "__GRAPHQL_URL__": "http://localhost:8080/graphql",
+ "__DEBUGGING__": false,
+ "__SSR__": true,
+ "__API_URL__": "/graphql",
+ "__FRONTEND_BUILD_DIR__": "./dist/client",
+ "__WEB_DEV_SERVER_PORT__": 3000,
+ "__GRAPHQL_ENDPOINT__": "/graphql",
+ "__LOCAL_SERVER_HOST__": "localhost",
+ "__BACKEND_URL__": "http://localhost:3000"
+ },
+ "uiFramework": "antui"
+}
diff --git a/servers/frontend-server/env.d.ts b/servers/frontend-server/env.d.ts
new file mode 100644
index 000000000..2b08b07f7
--- /dev/null
+++ b/servers/frontend-server/env.d.ts
@@ -0,0 +1,9 @@
+///
+///
+
+interface Window {
+ __ENV__: any,
+ __APOLLO_STATE__: any,
+ __PRELOADED_STATE__: any,
+ __SLOT_FILLS__: any,
+}
\ No newline at end of file
diff --git a/servers/frontend-server/env.js b/servers/frontend-server/env.js
new file mode 100644
index 000000000..5d86f0435
--- /dev/null
+++ b/servers/frontend-server/env.js
@@ -0,0 +1,5 @@
+/* eslint-disable jest/require-hook */
+import * as dotenv from 'dotenv-esm';
+if (process.env.ENV_FILE) {
+ dotenv.config({ path: process.env.ENV_FILE });
+}
\ No newline at end of file
diff --git a/servers/frontend-server/favicon.ico b/servers/frontend-server/favicon.ico
new file mode 100644
index 000000000..d91e2d351
Binary files /dev/null and b/servers/frontend-server/favicon.ico differ
diff --git a/servers/frontend-server/jest.config.js b/servers/frontend-server/jest.config.js
new file mode 100644
index 000000000..dabe5f226
--- /dev/null
+++ b/servers/frontend-server/jest.config.js
@@ -0,0 +1,33 @@
+const base = require('../../jest.config.base');
+const packageJson = require('./package');
+const merge = require('merge')
+const baseConfig = require('../../jest.config.base');
+const mongodbConfig = require('../../jest.config.mongodb');
+
+const mergeData = merge.recursive(
+ baseConfig,
+ {
+ "transform": {
+ "\\.(js|jsx)?$": "../../transform.js",
+ },
+ moduleNameMapper: {
+ '^__mocks__/(.*)$': '/../../__mocks__/$1',
+ // we'll use commonjs version of lodash for tests 👌
+ // because we don't need to use any kind of tree shaking right?!
+ '^lodash-es$': '/../../node_modules/lodash/index.js',
+ '@adminide-stack\/core': '/../core/src/index.ts',
+ },
+ roots: [
+ // "src",
+ "loader"
+ ],
+ },
+ mongodbConfig,
+ {
+ globals: {
+
+ }
+ }
+);
+
+module.exports = mergeData;
\ No newline at end of file
diff --git a/servers/frontend-server/package.json b/servers/frontend-server/package.json
index 724822096..66177f294 100755
--- a/servers/frontend-server/package.json
+++ b/servers/frontend-server/package.json
@@ -1,119 +1,105 @@
{
- "name": "sample-stack-frontend-server",
- "version": "0.0.1",
- "private": true,
- "description": "Sample Client server",
- "homepage": "https://github.com/cdmbase/fullstack-pro#readme",
- "bugs": {
- "url": "https://github.com/cdmbase/fullstack-pro/issues"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/cdmbase/fullstack-pro.git"
- },
- "license": "MIT",
- "author": "CDMBase LLC",
- "main": "index.js",
- "scripts": {
- "prebuild": "yarn build:clean",
- "build": "cross-env NODE_ENV=production webpack",
- "build:clean": "rimraf dist .awcache",
- "build:debug": "cross-env DEBUGGING=true NODE_ENV=production webpack",
- "build:debug:verbose": "yarn build:debug -- -v",
- "build:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env webpack",
- "build:stats": "cross-env BUNDLE_STATS=true yarn build:debug",
- "docker:build": "cross-env NODE_OPTIONS='--max_old_space_size=4096' yarn build && docker build . -t $npm_package_name:$npm_package_version",
- "docker:build:debug": "yarn build:debug && docker build . -t $npm_package_name:$npm_package_version",
- "docker:run": "docker run --env-file ../../config/staging/docker-staging.env -p 3010:3010 -it $npm_package_name:$npm_package_version",
- "jest": "./node_modules/.bin/jest",
- "start": "cross-env NODE_ENV=production pm2-runtime dist/index.js",
- "start:dev": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env node --harmony dist",
- "start:staging": "cross-env NODE_ENV=staging ENV_FILE=../../config/staging/staging.env node --harmony dist",
- "start:test": "cross-env NODE_ENV=test ENV_FILE=../../config/test/test.env node --harmony dist",
- "test": "jest",
- "test:debug": "npm test -- --runInBand",
- "test:watch": "npm test -- --watch",
- "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env webpack-dev-server",
- "watch:debug": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env yarn webpack-dev-server -- -v",
- "watch:ssr": "cross-env SSR=true && yarn watch",
- "watch:staging": "cross-env ENV_FILE=../../config/staging/staging.env yarn webpack-dev-server",
- "watch:test": "cross-env ENV_FILE=../../config/test/test.env yarn webpack-dev-server"
- },
- "dependencies": {
- "@apollo/client": "~3.7.1",
- "@apollo/react-components": "^4.0.0",
- "@apollo/react-hoc": "^4.0.0",
- "@cdm-logger/client": "^7.0.12",
- "@cdm-logger/server": "^7.0.12",
- "@common-stack/client-core": "0.5.1",
- "@common-stack/client-react": "0.5.6",
- "@common-stack/core": "0.5.1",
- "@common-stack/server-core": "0.5.1",
- "@emotion/css": "^11.10.0",
- "@emotion/react": "^11.10.4",
- "@emotion/server": "^11.10.0",
- "@emotion/styled": "^11.10.4",
- "@sample-stack/assets": "0.0.1",
- "@sample-stack/core": "0.0.1",
- "@sample-stack/counter-module-browser": "0.0.1",
- "@sample-stack/platform-browser": "0.0.1",
- "@loadable/component": "^5.15.2",
- "@loadable/server": "^5.15.2",
- "apollo-link-debounce": "^3.0.0",
- "apollo-link-logger": "^2.0.0",
- "apollo-server-errors": "^3.3.1",
- "antd": "~5.1.7",
- "classnames": "^2.2.6",
- "compression": "^1.7.4",
- "connected-react-router": "^6.9.1",
- "cors": "^2.8.5",
- "dotenv": "^8.2.0",
- "envalid": "~7.2.2",
- "error-stack-parser": "^2.0.4",
- "esm": "^3.2.25",
- "express": "^4.17.1",
- "graphql": "^15.0.0",
- "graphql-tag": "^2.11.0",
- "graphql-ws": "^5.11.2",
- "history": "^4.10.1",
- "immutability-helper": "^3.0.1",
- "inversify": "^5.0.1",
- "isomorphic-fetch": "^2.2.1",
- "js-cookie": "^2.2.1",
- "lodash": "^4.17.15",
- "ramda": "^0.26.1",
- "react": "18.0.0",
- "react-dom": "18.0.0",
- "react-helmet": "^6.1.0",
- "react-loadable": "^5.5.0",
- "react-redux": "^7.1.3",
- "react-router": "^5.3.3",
- "react-router-config": "^5.1.1",
- "react-router-dom": "^5.3.3",
- "react-transition-group": "^4.3.0",
- "redux": "^4.0.5",
- "redux-logger": "^3.0.6",
- "redux-observable": "^1.2.0",
- "redux-persist": "^6.0.0",
- "redux-thunk": "^2.3.0",
- "reflect-metadata": "^0.1.13",
- "reselect": "^4.0.0",
- "rxjs": "^6.5.3",
- "rxjs-compat": "^6.5.3",
- "rxjs-hooks": "^0.5.2",
- "serialize-javascript": "^4.0.0",
- "sourcemapped-stacktrace": "^1.1.11",
- "ts-invariant": "^0.10.3",
- "universal-cookie-express": "^4.0.1"
- },
- "devDependencies": {
- "@babel/polyfill": "7.12.1",
- "cross-env": "^7.0.3",
- "pm2": "^5.2.2",
- "raf": "3.4.1",
- "rimraf": "^3.0.2"
- },
- "peerDependencies": {
- "body-parser": "*"
- }
-}
\ No newline at end of file
+ "name": "sample-stack-frontend-server",
+ "version": "0.0.1",
+ "private": true,
+ "description": "Sample Client server",
+ "homepage": "https://github.com/cdmbase/fullstack-pro#readme",
+ "bugs": {
+ "url": "https://github.com/cdmbase/fullstack-pro/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/cdmbase/fullstack-pro.git"
+ },
+ "license": "MIT",
+ "author": "CDMBase LLC",
+ "type": "module",
+ "main": "index.js",
+ "scripts": {
+ "prebuild": "yarn build:clean && yarn genconfig",
+ "build": "cross-env SSR=true NODE_OPTIONS='--max_old_space_size=4096' NODE_ENV=production remix vite:build",
+ "build:SSR": "cross-env SSR=true NODE_ENV=production remix vite:build",
+ "build:clean": "rimraf dist build node_modules/.vite",
+ "build:debug": "cross-env DEBUGGING=true NODE_ENV=production remix vite:build",
+ "build:debug:verbose": "yarn build:debug -- -v",
+ "build:dev": "cross-env ENV_FILE=../../config/development/dev.env yarn build",
+ "build:devSSR": "cross-env SSR=true NODE_ENV=development ENV_FILE=../../config/development/dev.env yarn build",
+ "build:stats": "cross-env BUNDLE_STATS=true yarn build:debug",
+ "dev:vite:ssr": "cross-env SSR=true NODE_ENV=development ENV_FILE=../../config/development/dev.env node ./server.js",
+ "docker:build": "cross-env yarn build && docker build . -t $npm_package_name:$npm_package_version",
+ "docker:build:debug": "yarn build:debug && docker build . -t $npm_package_name:$npm_package_version",
+ "docker:run": "docker run --env-file ../../config/staging/docker-staging.env -p 3000:3000 -it $npm_package_name:$npm_package_version",
+ "genconfig": "node ./tools/mergeConfig.js",
+ "jest": "./node_modules/.bin/jest",
+ "preview": "cross-env SSR=true NODE_ENV=development ENV_FILE=../../config/development/dev.env node ./server.js",
+ "routes": "npx @remix-run/dev routes --json",
+ "prestart": "yarn genconfig",
+ "start": "cross-env NODE_ENV=production node ./server.js",
+ "start:SSR": "yarn build:SSR && yarn start",
+ "start:dev": "cross-env NODE_ENV=production ENV_FILE=../../config/development/dev.env node ./server.js",
+ "start:devSSR": "yarn build:devSSR && yarn start:dev",
+ "start:staging": "cross-env NODE_ENV=production ENV_FILE=../../config/staging/staging.env node ./server.js",
+ "start:test": "cross-env NODE_ENV=test ENV_FILE=../../config/test/test.env node ./server.js",
+ "start:vite:ssr": "cross-env SSR=true NODE_ENV=development ENV_FILE=../../config/development/dev.env yarn build && yarn preview",
+ "test": "jest",
+ "test:debug": "npm test -- --runInBand",
+ "test:watch": "npm test -- --watch",
+ "prewatch": "yarn genconfig",
+ "watch": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env node ./server.js",
+ "watch:debug": "cross-env NODE_ENV=development ENV_FILE=../../config/development/dev.env node ./server.js",
+ "watch:ssr": "cross-env SSR=true yarn watch",
+ "watch:staging": "cross-env ENV_FILE=../../config/staging/staging.env node ./server.js",
+ "watch:test": "cross-env ENV_FILE=../../config/test/test.env node ./server.js"
+ },
+ "dependencies": {
+ "@emotion/react": "^11.10.4",
+ "@emotion/server": "^11.10.0",
+ "@files-stack/core": "3.0.2",
+ "@react-icons/all-files": "^4.1.0",
+ "@sample-stack/counter-module-browser": "link:../../packages-modules/counter/browser",
+ "antd": "^5.14.0",
+ "classnames": "^2.2.6",
+ "compression": "^1.7.4",
+ "glob-all": "^3.3.1",
+ "immutability-helper": "^3.0.1",
+ "is-plain-obj": "^3.0.0",
+ "isomorphic-fetch": "^2.2.1",
+ "lodash": "^4.17.15",
+ "lodash-es": "^4.17.21",
+ "moment": "2.29.1",
+ "ramda": "^0.29.1",
+ "react-ga4": "^2.1.0",
+ "react-helmet": "^6.1.0",
+ "react-helmet-async": "^1.3.0",
+ "react-icons": "~4.3.1",
+ "react-icons-converter": "^1.1.4",
+ "react-transition-group": "^4.3.0",
+ "react-use": "^17.2.4",
+ "reselect": "^4.0.0",
+ "rxjs": "^6.5.3",
+ "rxjs-compat": "^6.5.3",
+ "rxjs-hooks": "^0.5.2",
+ "vite-env-only": "^2.2.1"
+ },
+ "devDependencies": {
+ "@cdmbase/vite-plugin-i18next-loader": "^2.0.12",
+ "@common-stack/frontend-stack-react": "6.0.6-alpha.0",
+ "@common-stack/rollup-vite-utils": "6.0.6-alpha.0",
+ "@remix-run/dev": "^2.8.1",
+ "@remix-run/serve": "^2.8.1",
+ "cross-env": "^7.0.3",
+ "dotenv-esm": "^16.0.3-4",
+ "pm2": "^5.2.2",
+ "raf": "3.4.1",
+ "rimraf": "^3.0.2",
+ "tsx": "^4.7.0",
+ "typescript": "^5.4.5",
+ "uuid": "^9.0.1",
+ "vite": "^5.1.0",
+ "vite-plugin-cjs-interop": "^2.1.1",
+ "vite-tsconfig-paths": "^4.2.1"
+ },
+ "peerDependencies": {
+ "body-parser": "*"
+ }
+}
diff --git a/servers/frontend-server/postcss.config.js b/servers/frontend-server/postcss.config.js
new file mode 100644
index 000000000..49c0612d5
--- /dev/null
+++ b/servers/frontend-server/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/servers/frontend-server/public/favicon.ico b/servers/frontend-server/public/favicon.ico
new file mode 100644
index 000000000..d91e2d351
Binary files /dev/null and b/servers/frontend-server/public/favicon.ico differ
diff --git a/servers/frontend-server/server.js b/servers/frontend-server/server.js
new file mode 100644
index 000000000..f6224d626
--- /dev/null
+++ b/servers/frontend-server/server.js
@@ -0,0 +1,78 @@
+import express from 'express';
+import compression from 'compression';
+import { createRequestHandler } from '@remix-run/express';
+import { installGlobals } from '@remix-run/node';
+import './env.js';
+import {
+ performCopyOperations,
+} from '@common-stack/rollup-vite-utils/lib/preStartup/configLoader/configLoader.js';
+import config from './app/cde-webconfig.json' assert { type: 'json' };
+
+installGlobals();
+
+Object.keys(config.buildConfig).forEach((key) => {
+ global[key] = config.buildConfig[key];
+});
+
+const startServer = async () => {
+ await performCopyOperations(config);
+
+ const { corsMiddleware } = await import(`./${config.commonPaths.appPath}/${config.commonPaths.frontendStackPath}/backend/middlewares/cors.js`);
+ const { containerMiddleware } = await import(`./${config.commonPaths.appPath}/${config.commonPaths.frontendStackPath}/backend/middlewares/container.js`);
+ const { loadContext } = await import(`./${config.commonPaths.appPath}/${config.commonPaths.frontendStackPath}/load-context.server.js`);
+
+ const viteDevServer =
+ process.env.NODE_ENV === 'production'
+ ? undefined
+ : await import('vite').then((vite) => {
+ return vite.createServer({
+ server: { middlewareMode: true },
+ });
+ });
+
+ const remixHandler = createRequestHandler({
+ getLoadContext: loadContext,
+ build: viteDevServer
+ ? () => viteDevServer.ssrLoadModule('virtual:remix/server-build')
+ : await import('./build/server/index.js'),
+ });
+
+ const app = express();
+
+ app.use(compression());
+ app.disable('x-powered-by');
+
+ if (viteDevServer) {
+ app.use(viteDevServer.middlewares);
+ } else {
+ app.use('/assets', express.static('build/client/assets', { immutable: true, maxAge: '1y' }));
+ }
+
+ app.use(express.static('build/client', { maxAge: '1h' }));
+
+ app.use(corsMiddleware);
+ app.options('*', corsMiddleware);
+
+ app.use(async (req, res, next) => {
+ let isAssetRequest = (url) =>
+ /\.[jt]sx?$/.test(url) ||
+ /@id\/__x00__virtual:/.test(url) ||
+ /@vite\/client/.test(url) ||
+ /node_modules\/vite\/dist\/client\/env/.test(url);
+
+ if (isAssetRequest(req.url)) {
+ next();
+ } else {
+ return await containerMiddleware(req, res, async () => {
+ return remixHandler(req, res, next);
+ });
+ }
+ });
+
+ const port = process.env.PORT || 3000;
+ app.listen(port, () => console.log(`Express server listening at http://localhost:${port}`));
+};
+
+startServer().catch((err) => {
+ console.error('Failed to start server:', err);
+});
diff --git a/servers/frontend-server/src/app/500.tsx b/servers/frontend-server/src/app/500.tsx
deleted file mode 100644
index c6d64b45e..000000000
--- a/servers/frontend-server/src/app/500.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as React from 'react';
-import { Result, Button } from 'antd';
-
-export const Error500 = ({ error }: any) => {
- React.useEffect(() => {
- console.trace(error);
- }, [error]);
-
- return (
- Back Home }
- />
- );
-}
diff --git a/servers/frontend-server/src/app/ErrorBoundary.tsx b/servers/frontend-server/src/app/ErrorBoundary.tsx
deleted file mode 100644
index 0439bd326..000000000
--- a/servers/frontend-server/src/app/ErrorBoundary.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import * as React from 'react';
-import { Error500 } from './500';
-import { ServerError } from './ServerError';
-
-type IErrorBoundryState = { error: any, type: string }
-
-
-export class ErrorBoundary extends React.Component {
- constructor(props) {
- super(props);
- const serverError: any = __CLIENT__ ? window.__SERVER_ERROR__ : null;
- if (serverError) {
- this.state = { error: new ServerError(serverError), type: 'serverError' };
- } else {
- this.state = { error: undefined, type: undefined };
- }
- }
-
- componentDidCatch(error) {
- let type = undefined;
-
- if (process.env.NODE_ENV === 'production') {
- type = '404'
- } else {
- type = '500'
- }
- // Update state so the next render will show the fallback UI.
- this.setState({ error, type });
- }
-
-
- render() {
- const { error, type } = this.state;
- if (error) {
- return
- }
- return this.props.children;
- }
-}
\ No newline at end of file
diff --git a/servers/frontend-server/src/app/Main.tsx b/servers/frontend-server/src/app/Main.tsx
deleted file mode 100755
index 28a9fdd9e..000000000
--- a/servers/frontend-server/src/app/Main.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-///
-import * as React from 'react';
-import { ApolloProvider } from '@apollo/client';
-import { Provider } from 'react-redux';
-import { ConnectedRouter } from 'connected-react-router';
-import { PersistGate } from 'redux-persist/integration/react';
-import { persistStore } from 'redux-persist';
-import { createBrowserHistory } from 'history';
-
-import { createReduxStore } from '../config/redux-config';
-import { createClientContainer } from '../config/client.service';
-import modules, { MainRoute } from '../modules';
-import { ErrorBoundary } from './ErrorBoundary';
-
-const { apolloClient: client } = createClientContainer();
-
-const history = createBrowserHistory();
-const { store } = createReduxStore(history);
-
-export class Main extends React.Component<{}, {}> {
- public render() {
- let persistor = persistStore(store);
- return (
-
-
-
-
- {modules.getWrappedRoot(
- (
-
-
-
- ),
- )}
-
-
-
-
- );
- }
-}
-
-export default Main;
diff --git a/servers/frontend-server/src/app/ServerError.tsx b/servers/frontend-server/src/app/ServerError.tsx
deleted file mode 100644
index 2cd2c8721..000000000
--- a/servers/frontend-server/src/app/ServerError.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-
-class ServerError extends Error {
- constructor(error: any) {
- super();
- for (const key of Object.getOwnPropertyNames(error)) {
- this[key] = error[key];
- }
- this.name = 'ServerError';
- }
-}
-
-export { ServerError };
\ No newline at end of file
diff --git a/servers/frontend-server/src/backend/app.ts b/servers/frontend-server/src/backend/app.ts
deleted file mode 100755
index 36ceb45f2..000000000
--- a/servers/frontend-server/src/backend/app.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/* eslint-disable import/first */
-/* eslint-disable no-unused-expressions */
-/* eslint-disable global-require */
-/* eslint-disable @typescript-eslint/no-var-requires */
-/* eslint-disable jest/require-hook */
-// tslint:disable-next-line:no-unused-expression
-process.env.ENV_FILE !== null && require('dotenv').config({ path: process.env.ENV_FILE });
-
-import { logger } from '@cdm-logger/server';
-
-import './server';
-
-process.on('uncaughtException', (ex: Error) => {
- logger.error(ex, 'uncaughtException');
- process.exit(1);
-});
-
-process.on('unhandledRejection', (reason: Error) => {
- logger.error(reason, 'unhandledRejection');
-});
-
-if ((module as any).hot) {
- (module as any).hot.status((event) => {
- if (event === 'abort' || event === 'fail') {
- logger.error(`HMR error status: ${event}`);
- // Signal webpack.run.js to do full-reload of the back-end
- process.exit(250);
- }
- });
-
- (module as any).hot.accept();
-}
diff --git a/servers/frontend-server/src/backend/middlewares/cors.ts b/servers/frontend-server/src/backend/middlewares/cors.ts
deleted file mode 100755
index 823cbf953..000000000
--- a/servers/frontend-server/src/backend/middlewares/cors.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/* eslint-disable jest/require-hook */
-import cors from 'cors';
-import { logger } from '@common-stack/client-core';
-import { config } from '../../config';
-
-const { CLIENT_URL, BACKEND_URL } = config;
-
-const corsWhitelist = [CLIENT_URL, BACKEND_URL];
-logger.info('corsWhitelist (%j)', corsWhitelist);
-
-const corsOptions: cors.CorsOptions = {
- origin: (origin, callback) => {
- if (corsWhitelist.indexOf(origin) !== -1) {
- callback(null, true);
- } else {
- // TODO: only throw when in debug mode
- logger.error('url (%s) is not in the whitelist', origin);
- // callback(new Error('Not allowed by CORS'))
- logger.warn('allowing all origins temporarily, you need to disable it.');
- callback(null, true);
- }
- },
- credentials: false,
-};
-
-export const corsMiddleware = cors(corsOptions);
diff --git a/servers/frontend-server/src/backend/middlewares/error.ts b/servers/frontend-server/src/backend/middlewares/error.ts
deleted file mode 100755
index 1e4beafa1..000000000
--- a/servers/frontend-server/src/backend/middlewares/error.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-///
-
-import * as path from 'path';
-import * as fs from 'fs';
-import * as url from 'url';
-import { logger } from '@cdm-logger/server';
-
-
-let assetMap;
-
-const stripCircular = (from, seen?: any) => {
- const to = Array.isArray(from) ? [] : {};
- seen = seen || [];
- seen.push(from);
- Object.getOwnPropertyNames(from).forEach(key => {
- if (!from[key] || (typeof from[key] !== 'object' && !Array.isArray(from[key]))) {
- to[key] = from[key];
- } else if (seen.indexOf(from[key]) < 0) {
- to[key] = stripCircular(from[key], seen.slice(0));
- } else { to[key] = '[Circular]'; }
- });
- return to;
-};
-
-const { pathname } = url.parse(__BACKEND_URL__);
-
-export const errorMiddleware =
- (e, req, res, next) => {
- if (req.path === pathname) {
- const stack = e.stack.toString().replace(/[\n]/g, '\\n');
- res.status(200).send(`[{"data": {}, "errors":[{"message": "${stack}"}]}]`);
- } else {
- logger.error(e);
-
- if (__DEV__ || !assetMap) {
- assetMap = JSON.parse(fs.readFileSync(path.join(__FRONTEND_BUILD_DIR__, 'assets.json')).toString());
- }
-
- const serverErrorScript = ``;
- const vendorScript = assetMap['vendor.js']
- ? ``
- : '';
-
- res.status(200).send(
- `${serverErrorScript}
- ${vendorScript}
-
- `,
- );
- }
- };
-
-
diff --git a/servers/frontend-server/src/backend/modules/index.ts b/servers/frontend-server/src/backend/modules/index.ts
deleted file mode 100755
index c5c3222be..000000000
--- a/servers/frontend-server/src/backend/modules/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import modules from './modules';
-export default modules;
diff --git a/servers/frontend-server/src/backend/modules/modules.ts b/servers/frontend-server/src/backend/modules/modules.ts
deleted file mode 100755
index d38cf419d..000000000
--- a/servers/frontend-server/src/backend/modules/modules.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { Feature } from '@common-stack/server-core';
-
-export default new Feature({});
-
diff --git a/servers/frontend-server/src/backend/server.ts b/servers/frontend-server/src/backend/server.ts
deleted file mode 100755
index 6319b35b3..000000000
--- a/servers/frontend-server/src/backend/server.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-/* eslint-disable jest/require-hook */
-import 'reflect-metadata';
-import express from 'express';
-import compression from 'compression';
-import * as bodyParser from 'body-parser';
-import * as http from 'http';
-import * as path from 'path';
-import * as url from 'url';
-import 'isomorphic-fetch';
-import { logger } from '@cdm-logger/server';
-import { websiteMiddleware } from './website';
-import { corsMiddleware } from './middlewares/cors';
-import { errorMiddleware } from './middlewares/error';
-import { config } from '../config';
-import modules from './modules';
-
-const cookiesMiddleware = require('universal-cookie-express');
-
-let server;
-
-const app = express();
-
-app.use(corsMiddleware);
-app.options('*', corsMiddleware);
-
-for (const applyBeforeware of modules.beforewares) {
- applyBeforeware(app);
-}
-
-app.use(cookiesMiddleware());
-
-// By default it uses backend_url port, which may conflict with graphql server.
-const { port: serverPort } = url.parse(config.LOCAL_BACKEND_URL);
-
-// Don't rate limit heroku
-app.enable('trust proxy');
-if (!__DEV__) {
- app.use(compression());
-}
-
-app.use(bodyParser.urlencoded({ extended: true }));
-app.use(bodyParser.json());
-
-app.use(
- '/',
- express.static(path.join(__FRONTEND_BUILD_DIR__), {
- maxAge: '180 days',
- }),
-);
-
-if (__DEV__) {
- app.use('/', express.static(__DLL_BUILD_DIR__, { maxAge: '180 days' }));
-}
-
-app.use(websiteMiddleware);
-
-if (__DEV__) {
- app.use(errorMiddleware);
-}
-
-server = http.createServer(app);
-
-server.listen(serverPort, () => {
- logger.info(`Client Server is now running on port ${serverPort}`);
-});
-
-server.on('close', () => {
- server = undefined;
-});
-
-if ((module as any).hot) {
- (module as any).hot.dispose(() => {
- try {
- if (server) {
- server.close();
- }
- } catch (error) {
- logger.error(error.stack);
- }
- });
- (module as any).hot.accept(['./website'], () => {
- logger.debug('...reloading middleware');
- });
-
- (module as any).hot.accept();
-}
-
-export default server;
diff --git a/servers/frontend-server/src/backend/ssr/html.tsx b/servers/frontend-server/src/backend/ssr/html.tsx
deleted file mode 100755
index 5c68a0159..000000000
--- a/servers/frontend-server/src/backend/ssr/html.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-///
-
-import * as React from 'react';
-import serialize from 'serialize-javascript';
-import { HelmetData } from 'react-helmet';
-
-/**
- * A simple herlper function to prepare the HTML markup. This loads:
- * - Page title
- * - SEO meta tags
- * - Preloaded state (for Redux, Apollo, additional Environment variables) depending on the current route
- * - Code-split script tags depending on the current route
- * @param param0
- */
-const Html = ({
- content,
- state,
- reduxState,
- headElements,
- env,
- assetMap,
- styleSheet,
- helmet,
- stylesInserts = [],
- scriptsInserts = [],
-}: {
- content?: any;
- state: any;
- reduxState: any;
- headElements: React.ReactElement[];
- assetMap?: string[];
- env: any;
- styleSheet?: any;
- helmet?: HelmetData;
- stylesInserts?: any[];
- scriptsInserts?: string[];
-}) => {
- const htmlAttrs = helmet.htmlAttributes.toComponent(); // react-helmet html document tags
- const bodyAttrs = helmet.bodyAttributes.toComponent(); // react-helmet body document tags
- return (
-
-
- {helmet.title.toComponent()}
- {helmet.meta.toComponent()}
- {helmet.link.toComponent()}
- {helmet.style.toComponent()}
- {helmet.script.toComponent()}
- {helmet.noscript.toComponent()}
- {assetMap['vendor.js'] && }
- {headElements}
-
-
-
-
-
-
-
-
-
- {!!__DEV__ && (
-