fix: modernize react router interface
This commit is contained in:
parent
d2fabd902d
commit
2f522e5152
311
package-lock.json
generated
311
package-lock.json
generated
|
@ -3088,6 +3088,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@remix-run/router": {
|
||||||
|
"version": "1.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz",
|
||||||
|
"integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sigstore/bundle": {
|
"node_modules/@sigstore/bundle": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.1.1.tgz",
|
||||||
|
@ -4672,53 +4680,6 @@
|
||||||
"ieee754": "^1.1.13"
|
"ieee754": "^1.1.13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/body-parser": {
|
|
||||||
"version": "1.20.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
|
|
||||||
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
|
|
||||||
"dependencies": {
|
|
||||||
"bytes": "3.1.2",
|
|
||||||
"content-type": "~1.0.5",
|
|
||||||
"debug": "2.6.9",
|
|
||||||
"depd": "2.0.0",
|
|
||||||
"destroy": "1.2.0",
|
|
||||||
"http-errors": "2.0.0",
|
|
||||||
"iconv-lite": "0.4.24",
|
|
||||||
"on-finished": "2.4.1",
|
|
||||||
"qs": "6.11.0",
|
|
||||||
"raw-body": "2.5.2",
|
|
||||||
"type-is": "~1.6.18",
|
|
||||||
"unpipe": "1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8",
|
|
||||||
"npm": "1.2.8000 || >= 1.4.16"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/body-parser/node_modules/debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"dependencies": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/body-parser/node_modules/iconv-lite": {
|
|
||||||
"version": "0.4.24",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
|
||||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
|
||||||
"dependencies": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/body-parser/node_modules/ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
|
||||||
},
|
|
||||||
"node_modules/bonjour-service": {
|
"node_modules/bonjour-service": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz",
|
||||||
|
@ -12714,31 +12675,6 @@
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/raw-body": {
|
|
||||||
"version": "2.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
|
||||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
|
||||||
"dependencies": {
|
|
||||||
"bytes": "3.1.2",
|
|
||||||
"http-errors": "2.0.0",
|
|
||||||
"iconv-lite": "0.4.24",
|
|
||||||
"unpipe": "1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/raw-body/node_modules/iconv-lite": {
|
|
||||||
"version": "0.4.24",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
|
||||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
|
||||||
"dependencies": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/rc": {
|
"node_modules/rc": {
|
||||||
"version": "1.2.8",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||||
|
@ -12901,23 +12837,29 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router": {
|
"node_modules/react-router": {
|
||||||
"version": "6.2.1",
|
"version": "6.22.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz",
|
||||||
"integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
|
"integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"history": "^5.2.0"
|
"@remix-run/router": "1.15.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=16.8"
|
"react": ">=16.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router-dom": {
|
"node_modules/react-router-dom": {
|
||||||
"version": "6.2.1",
|
"version": "6.22.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz",
|
||||||
"integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
|
"integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"history": "^5.2.0",
|
"@remix-run/router": "1.15.1",
|
||||||
"react-router": "6.2.1"
|
"react-router": "6.22.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=16.8",
|
"react": ">=16.8",
|
||||||
|
@ -16669,7 +16611,7 @@
|
||||||
},
|
},
|
||||||
"packages/build": {
|
"packages/build": {
|
||||||
"name": "@flecks/build",
|
"name": "@flecks/build",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.12.10",
|
"@babel/core": "^7.12.10",
|
||||||
|
@ -16680,7 +16622,7 @@
|
||||||
"@babel/preset-env": "^7.12.11",
|
"@babel/preset-env": "^7.12.11",
|
||||||
"@babel/traverse": "^7.17.0",
|
"@babel/traverse": "^7.17.0",
|
||||||
"@babel/types": "^7.17.0",
|
"@babel/types": "^7.17.0",
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.1.3",
|
||||||
"babel-merge": "^3.0.0",
|
"babel-merge": "^3.0.0",
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
|
@ -16738,7 +16680,7 @@
|
||||||
},
|
},
|
||||||
"packages/core": {
|
"packages/core": {
|
||||||
"name": "@flecks/core",
|
"name": "@flecks/core",
|
||||||
"version": "4.2.0",
|
"version": "4.2.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"callsites": "^3.1.0",
|
"callsites": "^3.1.0",
|
||||||
|
@ -16794,10 +16736,10 @@
|
||||||
},
|
},
|
||||||
"packages/create-app": {
|
"packages/create-app": {
|
||||||
"name": "@flecks/create-app",
|
"name": "@flecks/create-app",
|
||||||
"version": "4.0.9",
|
"version": "4.0.10",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"commander": "11.1.0",
|
"commander": "11.1.0",
|
||||||
"validate-npm-package-name": "^3.0.0"
|
"validate-npm-package-name": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
@ -16805,8 +16747,8 @@
|
||||||
"create-app": "build/cli.js"
|
"create-app": "build/cli.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/create-app/node_modules/builtins": {
|
"packages/create-app/node_modules/builtins": {
|
||||||
|
@ -16824,45 +16766,45 @@
|
||||||
},
|
},
|
||||||
"packages/create-fleck": {
|
"packages/create-fleck": {
|
||||||
"name": "@flecks/create-fleck",
|
"name": "@flecks/create-fleck",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"commander": "11.1.0"
|
"commander": "11.1.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"create-fleck": "build/cli.js"
|
"create-fleck": "build/cli.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/db": {
|
"packages/db": {
|
||||||
"name": "@flecks/db",
|
"name": "@flecks/db",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"sequelize": "^6.3.5",
|
"sequelize": "^6.3.5",
|
||||||
"sqlite3": "^5.0.2"
|
"sqlite3": "^5.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/docker": {
|
"packages/docker": {
|
||||||
"name": "@flecks/docker",
|
"name": "@flecks/docker",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"debug": "^4.3.3"
|
"debug": "^4.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/docker/node_modules/debug": {
|
"packages/docker/node_modules/debug": {
|
||||||
|
@ -16883,47 +16825,47 @@
|
||||||
},
|
},
|
||||||
"packages/dox": {
|
"packages/dox": {
|
||||||
"name": "@flecks/dox",
|
"name": "@flecks/dox",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.17.2",
|
"@babel/core": "^7.17.2",
|
||||||
"@babel/traverse": "^7.17.0",
|
"@babel/traverse": "^7.17.0",
|
||||||
"@babel/types": "^7.17.0",
|
"@babel/types": "^7.17.0",
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"comment-parser": "^1.3.0",
|
"comment-parser": "^1.3.0",
|
||||||
"rimraf": "^5.0.5"
|
"rimraf": "^5.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/electron": {
|
"packages/electron": {
|
||||||
"name": "@flecks/electron",
|
"name": "@flecks/electron",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"electron": "^28.1.4",
|
"electron": "^28.1.4",
|
||||||
"electron-devtools-installer": "^3.2.0"
|
"electron-devtools-installer": "^3.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/fleck": {
|
"packages/fleck": {
|
||||||
"name": "@flecks/fleck",
|
"name": "@flecks/fleck",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"babel-merge": "^3.0.0",
|
"babel-merge": "^3.0.0",
|
||||||
"debug": "^4.3.3",
|
"debug": "^4.3.3",
|
||||||
"mocha": "^10.2.0"
|
"mocha": "^10.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"chai": "4.2.0"
|
"chai": "4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -16944,86 +16886,88 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/headless": {
|
"packages/headless": {
|
||||||
|
"name": "@flecks/headless",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.0.0"
|
"@flecks/core": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.0.0",
|
"@flecks/build": "^4.0.0",
|
||||||
"@flecks/fleck": "^4.0.0"
|
"@flecks/fleck": "^4.0.0",
|
||||||
|
"puppeteer": "^22.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/passport": {
|
"packages/passport": {
|
||||||
"name": "@flecks/passport",
|
"name": "@flecks/passport",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/db": "^4.1.0",
|
"@flecks/db": "^4.1.1",
|
||||||
"@flecks/redux": "^4.0.8",
|
"@flecks/redux": "^4.0.9",
|
||||||
"@flecks/session": "^4.0.8",
|
"@flecks/session": "^4.0.9",
|
||||||
"passport": "^0.7.0"
|
"passport": "^0.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/passport-local": {
|
"packages/passport-local": {
|
||||||
"name": "@flecks/passport-local",
|
"name": "@flecks/passport-local",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/passport": "^4.0.8",
|
"@flecks/passport": "^4.0.9",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"passport-local": "^1.0.0"
|
"passport-local": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/passport-local-react": {
|
"packages/passport-local-react": {
|
||||||
"name": "@flecks/passport-local-react",
|
"name": "@flecks/passport-local-react",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/passport-local": "^4.0.8",
|
"@flecks/passport-local": "^4.0.9",
|
||||||
"@flecks/passport-react": "^4.0.8",
|
"@flecks/passport-react": "^4.0.9",
|
||||||
"@flecks/react": "^4.0.8"
|
"@flecks/react": "^4.0.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/passport-react": {
|
"packages/passport-react": {
|
||||||
"name": "@flecks/passport-react",
|
"name": "@flecks/passport-react",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/passport": "^4.0.8",
|
"@flecks/passport": "^4.0.9",
|
||||||
"@flecks/react": "^4.0.8",
|
"@flecks/react": "^4.0.9",
|
||||||
"@flecks/react-redux": "^4.0.8",
|
"@flecks/react-redux": "^4.0.9",
|
||||||
"@flecks/web": "^4.1.0"
|
"@flecks/web": "^4.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/react": {
|
"packages/react": {
|
||||||
"name": "@flecks/react",
|
"name": "@flecks/react",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/preset-react": "^7.23.3",
|
"@babel/preset-react": "^7.23.3",
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/web": "^4.1.0",
|
"@flecks/web": "^4.1.1",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
|
||||||
"babel-merge": "^3.0.0",
|
"babel-merge": "^3.0.0",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
@ -17033,61 +16977,61 @@
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-refresh": "^0.14.0",
|
"react-refresh": "^0.14.0",
|
||||||
"react-router": "6.2.1",
|
"react-router": "6.22.1",
|
||||||
"react-router-dom": "6.2.1",
|
"react-router-dom": "6.22.1",
|
||||||
"react-tabs": "^6.0.2",
|
"react-tabs": "^6.0.2",
|
||||||
"redux-first-history": "5.1.1"
|
"redux-first-history": "5.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/react-redux": {
|
"packages/react-redux": {
|
||||||
"name": "@flecks/react-redux",
|
"name": "@flecks/react-redux",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/react": "^4.0.8",
|
"@flecks/react": "^4.0.9",
|
||||||
"@flecks/redux": "^4.0.8",
|
"@flecks/redux": "^4.0.9",
|
||||||
"react-redux": "^7.2.2"
|
"react-redux": "^7.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/redis": {
|
"packages/redis": {
|
||||||
"name": "@flecks/redis",
|
"name": "@flecks/redis",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@socket.io/redis-adapter": "7.1.0",
|
"@socket.io/redis-adapter": "7.1.0",
|
||||||
"connect-redis": "^5.0.0",
|
"connect-redis": "^5.0.0",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
"redis": "4.0.3"
|
"redis": "4.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/redux": {
|
"packages/redux": {
|
||||||
"name": "@flecks/redux",
|
"name": "@flecks/redux",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@reduxjs/toolkit": "^1.5.0",
|
"@reduxjs/toolkit": "^1.5.0",
|
||||||
"debug": "^4.3.3",
|
"debug": "^4.3.3",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"reduce-reducers": "^1.0.4"
|
"reduce-reducers": "^1.0.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/redux/node_modules/debug": {
|
"packages/redux/node_modules/debug": {
|
||||||
|
@ -17108,51 +17052,51 @@
|
||||||
},
|
},
|
||||||
"packages/repl": {
|
"packages/repl": {
|
||||||
"name": "@flecks/repl",
|
"name": "@flecks/repl",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"command-exists": "^1.2.9",
|
"command-exists": "^1.2.9",
|
||||||
"debug": "4.3.1"
|
"debug": "4.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/server": {
|
"packages/server": {
|
||||||
"name": "@flecks/server",
|
"name": "@flecks/server",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0"
|
"@flecks/core": "^4.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/session": {
|
"packages/session": {
|
||||||
"name": "@flecks/session",
|
"name": "@flecks/session",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-session": "^1.17.3"
|
"express-session": "^1.17.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/socket": {
|
"packages/socket": {
|
||||||
"name": "@flecks/socket",
|
"name": "@flecks/socket",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/react": "^4.0.8",
|
"@flecks/react": "^4.0.9",
|
||||||
"msgpack-lite": "^0.1.26",
|
"msgpack-lite": "^0.1.26",
|
||||||
"proxy-addr": "^2.0.6",
|
"proxy-addr": "^2.0.6",
|
||||||
"schemapack": "^1.4.2",
|
"schemapack": "^1.4.2",
|
||||||
|
@ -17160,25 +17104,24 @@
|
||||||
"socket.io-client": "^4.1.2"
|
"socket.io-client": "^4.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0"
|
"@flecks/fleck": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/web": {
|
"packages/web": {
|
||||||
"name": "@flecks/web",
|
"name": "@flecks/web",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.17.0",
|
"@babel/parser": "^7.17.0",
|
||||||
"@babel/types": "^7.17.0",
|
"@babel/types": "^7.17.0",
|
||||||
"@flecks/core": "^4.2.0",
|
"@flecks/core": "^4.2.1",
|
||||||
"@flecks/server": "^4.1.0",
|
"@flecks/server": "^4.1.1",
|
||||||
"@webpack-cli/serve": "^2.0.5",
|
"@webpack-cli/serve": "^2.0.5",
|
||||||
"add-asset-html-webpack-plugin": "^6.0.0",
|
"add-asset-html-webpack-plugin": "^6.0.0",
|
||||||
"assert": "^2.1.0",
|
"assert": "^2.1.0",
|
||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"before-build-webpack": "^0.2.13",
|
"before-build-webpack": "^0.2.13",
|
||||||
"body-parser": "^1.20.2",
|
|
||||||
"browserify-zlib": "^0.2.0",
|
"browserify-zlib": "^0.2.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"clean-webpack-plugin": "4.0.0",
|
"clean-webpack-plugin": "4.0.0",
|
||||||
|
@ -17205,9 +17148,9 @@
|
||||||
"webpack-dev-server": "^4.15.1"
|
"webpack-dev-server": "^4.15.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@flecks/build": "^4.1.0",
|
"@flecks/build": "^4.1.1",
|
||||||
"@flecks/fleck": "^4.1.0",
|
"@flecks/fleck": "^4.1.1",
|
||||||
"puppeteer": "^22.0.0"
|
"@flecks/headless": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,5 +33,59 @@ export const hooks = {
|
||||||
// You can also just:
|
// You can also just:
|
||||||
return Component;
|
return Component;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Provide routes for React Router.
|
||||||
|
*
|
||||||
|
* You can also build routes from a file structure using e.g.:
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* import {createRoutesFromContext} from '@flecks/react/router';
|
||||||
|
*
|
||||||
|
* export const hooks = {
|
||||||
|
* '@flecks/react/router.routes': () => (
|
||||||
|
* createRoutesFromContext(require.context('./routes'))
|
||||||
|
* ),
|
||||||
|
* };
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* See [the documentation page on routing](../react#routing) for more details.
|
||||||
|
*
|
||||||
|
* @returns {RouteObject[]} An array of React Router route objects.
|
||||||
|
*/
|
||||||
|
'@flecks/react/router.routes': () => {
|
||||||
|
// You can also just return routes how React Router expects:
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
Component: function Component() {
|
||||||
|
return <p>This is the root route</p>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/team',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: ':teamId',
|
||||||
|
Component: function Component() {
|
||||||
|
const {teamId} = useParams();
|
||||||
|
return <p>This is team {teamId}.</p>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
Component: function Component() {
|
||||||
|
return <p>This is the team overview.</p>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/about',
|
||||||
|
Component: function Component() {
|
||||||
|
return <p>This is the about page</p>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
import {
|
||||||
import {createReduxHistory, history} from '@flecks/react/router/context';
|
createBrowserRouter,
|
||||||
import {unstable_HistoryRouter as HistoryRouter} from 'react-router-dom';
|
matchRoutes,
|
||||||
import {HistoryRouter as ReduxHistoryRouter} from './history-router';
|
RouterProvider,
|
||||||
|
} from 'react-router-dom';
|
||||||
|
|
||||||
export const hooks = {
|
export const hooks = {
|
||||||
'@flecks/react.providers': (req, flecks) => (
|
'@flecks/react.roots': async (req, res, flecks) => {
|
||||||
flecks.fleck('@flecks/redux')
|
const {routes} = flecks.reactRouter;
|
||||||
? [ReduxHistoryRouter, {history: createReduxHistory(flecks.redux)}]
|
// Determine if any of the initial routes are lazy
|
||||||
: [HistoryRouter, {history}]
|
const lazyMatches = matchRoutes(routes, window.location)?.filter(({route}) => route.lazy);
|
||||||
),
|
// Load the lazy matches and update the routes before creating the router
|
||||||
|
// so we can hydrate the SSR-rendered content synchronously.
|
||||||
|
if (lazyMatches && lazyMatches?.length > 0) {
|
||||||
|
await Promise.all(
|
||||||
|
lazyMatches.map(async (m) => {
|
||||||
|
Object.entries(await m.route.lazy())
|
||||||
|
.forEach(([name, value]) => {
|
||||||
|
m.route[name] = value;
|
||||||
|
});
|
||||||
|
delete m.route.lazy;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const router = createBrowserRouter(routes);
|
||||||
|
return [RouterProvider, {router}];
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
import {createReduxHistoryContext} from 'redux-first-history';
|
|
||||||
import {createBrowserHistory, createMemoryHistory} from 'history';
|
|
||||||
|
|
||||||
export const history = 'undefined' === typeof window
|
|
||||||
? createMemoryHistory()
|
|
||||||
: createBrowserHistory();
|
|
||||||
|
|
||||||
export const {
|
|
||||||
createReduxHistory,
|
|
||||||
routerMiddleware,
|
|
||||||
routerReducer,
|
|
||||||
} = createReduxHistoryContext({
|
|
||||||
history,
|
|
||||||
reduxTravelling: true,
|
|
||||||
});
|
|
138
packages/react/src/router/filetree-router.js
Normal file
138
packages/react/src/router/filetree-router.js
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
import {resolve} from 'path';
|
||||||
|
|
||||||
|
function filePathToSegmentPath(path) {
|
||||||
|
let localPath = path;
|
||||||
|
let suffix = '';
|
||||||
|
// `-path` -> `path?`
|
||||||
|
if (path.startsWith('-')) {
|
||||||
|
localPath = path.slice(1);
|
||||||
|
suffix = '?';
|
||||||
|
}
|
||||||
|
// `[...path]` -> `*`
|
||||||
|
if (localPath.match(/^\[\.\.\..*\]$/)) {
|
||||||
|
return '*';
|
||||||
|
}
|
||||||
|
// `[path]` -> `:path`
|
||||||
|
if (localPath.match(/^\[.*\]$/)) {
|
||||||
|
return `:${localPath.slice(1, -1)}${suffix}`;
|
||||||
|
}
|
||||||
|
return `${localPath}${suffix}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createRoutesFromFiletree({importer, paths, resolver}) {
|
||||||
|
const children = [{path: '/'}];
|
||||||
|
const elements = [];
|
||||||
|
const fix = [];
|
||||||
|
const moduleMap = {};
|
||||||
|
paths.forEach((path) => {
|
||||||
|
const resolved = resolver(path);
|
||||||
|
if (!moduleMap[resolved]) {
|
||||||
|
moduleMap[resolved] = [];
|
||||||
|
}
|
||||||
|
moduleMap[resolved].push(path);
|
||||||
|
});
|
||||||
|
// Build initial router object.
|
||||||
|
Object.entries(moduleMap)
|
||||||
|
.map(([, paths]) => (
|
||||||
|
// Second-longest: path without extension.
|
||||||
|
paths
|
||||||
|
.sort((l, r) => (l.length < r.length ? -1 : 1))
|
||||||
|
.slice(0, -1)
|
||||||
|
.pop()
|
||||||
|
))
|
||||||
|
.forEach((path) => {
|
||||||
|
let walk = children;
|
||||||
|
const parts = ['/', ...resolve('/', path).split('/').slice(1)];
|
||||||
|
const segments = parts.map(filePathToSegmentPath);
|
||||||
|
for (let i = 0; i < segments.length; ++i) {
|
||||||
|
const segment = segments[i];
|
||||||
|
const end = parts.length - 1;
|
||||||
|
// Colocation: bail.
|
||||||
|
if (segment.startsWith('_')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Create a new node if necessary.
|
||||||
|
let route = walk.find(({path}) => segment === path);
|
||||||
|
if (!route) {
|
||||||
|
route = {path: segment};
|
||||||
|
walk.push(route);
|
||||||
|
}
|
||||||
|
// Walking...
|
||||||
|
if (i < end - 1) {
|
||||||
|
if (!route.children) {
|
||||||
|
route.children = [];
|
||||||
|
fix.push(route.children);
|
||||||
|
}
|
||||||
|
route.children.route = route;
|
||||||
|
route.children.parent = walk;
|
||||||
|
walk = route.children;
|
||||||
|
}
|
||||||
|
// About to end, check last.
|
||||||
|
if (i === end - 1) {
|
||||||
|
const last = parts[i + 1];
|
||||||
|
// Non-index is a sibling, create if necessary.
|
||||||
|
if ('index' !== last) {
|
||||||
|
const offset = '/' === parts[i] ? 1 : 0;
|
||||||
|
const nestedPath = segments.slice(i + offset).join('/');
|
||||||
|
route = walk.find(({path}) => nestedPath === path);
|
||||||
|
if (!route) {
|
||||||
|
route = {path: nestedPath};
|
||||||
|
walk.push(route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elements.push([walk, route, path]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Mix imported modules into router object.
|
||||||
|
await Promise.all(
|
||||||
|
elements.map(async ([children, node, path]) => {
|
||||||
|
const route = await importer(path);
|
||||||
|
let {hoist} = route;
|
||||||
|
if (hoist > 0) {
|
||||||
|
const parts = node.path.split('/');
|
||||||
|
children.splice(children.indexOf(node), 1);
|
||||||
|
let walk = children;
|
||||||
|
while (hoist--) {
|
||||||
|
parts.unshift('/' !== walk.route.path ? walk.route.path : '');
|
||||||
|
walk = walk.parent;
|
||||||
|
}
|
||||||
|
node.path = parts.join('/');
|
||||||
|
walk.push(node);
|
||||||
|
}
|
||||||
|
Object.entries(route)
|
||||||
|
.forEach(([key, value]) => {
|
||||||
|
switch (key) {
|
||||||
|
case 'children':
|
||||||
|
// ???
|
||||||
|
return;
|
||||||
|
case 'hoist':
|
||||||
|
return;
|
||||||
|
case 'index':
|
||||||
|
delete node.path;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
node[key] = value;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
// Clean up the build junk.
|
||||||
|
fix.forEach((children) => {
|
||||||
|
if (0 === children.length) {
|
||||||
|
delete children.route.children;
|
||||||
|
}
|
||||||
|
delete children.route;
|
||||||
|
delete children.parent;
|
||||||
|
});
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createRoutesFromContext(context) {
|
||||||
|
return createRoutesFromFiletree({
|
||||||
|
paths: context.keys(),
|
||||||
|
importer: context,
|
||||||
|
resolver: context.resolve,
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
/* eslint-disable react/prop-types */
|
|
||||||
|
|
||||||
// redux-first-router/rr6 doesn't honor hoisting.
|
|
||||||
|
|
||||||
const {createElement, useLayoutEffect, useState} = require('react');
|
|
||||||
const {Router} = require('react-router');
|
|
||||||
|
|
||||||
exports.HistoryRouter = function HistoryRouter({basename, children, history}) {
|
|
||||||
const [state, setState] = useState({
|
|
||||||
action: history.action,
|
|
||||||
location: history.location,
|
|
||||||
});
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
history.listen(setState);
|
|
||||||
}, [history]);
|
|
||||||
// eslint-disable-next-line react/no-children-prop
|
|
||||||
return createElement(Router, {
|
|
||||||
basename,
|
|
||||||
children,
|
|
||||||
location: state.location,
|
|
||||||
navigationType: state.action,
|
|
||||||
navigator: history,
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,14 +1,32 @@
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
import {createRoutesFromFiletree, createRoutesFromContext} from './filetree-router';
|
||||||
import {routerMiddleware, routerReducer} from '@flecks/react/router/context';
|
|
||||||
|
|
||||||
export * from 'react-router-dom';
|
export * from 'react-router-dom';
|
||||||
export * from 'redux-first-history';
|
|
||||||
|
export {createRoutesFromFiletree, createRoutesFromContext};
|
||||||
|
|
||||||
export const hooks = {
|
export const hooks = {
|
||||||
'@flecks/redux.slices': () => ({
|
'@flecks/react/router.routes': () => createRoutesFromContext(require.context('./routes')),
|
||||||
router: routerReducer,
|
'@flecks/core.config': () => ({
|
||||||
|
/**
|
||||||
|
* Select the root routes. Implement `@flecks/react/router.routes` in e.g. `@your/fleck` and
|
||||||
|
* set `root` to `@your/fleck` to render your routes.
|
||||||
|
*/
|
||||||
|
root: '@flecks/react/router',
|
||||||
}),
|
}),
|
||||||
'@flecks/redux.store': (options) => {
|
'@flecks/core.starting': async (flecks) => {
|
||||||
options.middleware.push(routerMiddleware);
|
const {root} = flecks.get('@flecks/react/router');
|
||||||
|
flecks.reactRouter.routes = await flecks.invokeFleck('@flecks/react/router.routes', root);
|
||||||
},
|
},
|
||||||
|
'@flecks/web.config': (req, flecks) => ({
|
||||||
|
root: flecks.get('@flecks/react/router').root,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mixin = (Flecks) => class FlecksWithReactRouterServer extends Flecks {
|
||||||
|
|
||||||
|
constructor(runtime) {
|
||||||
|
super(runtime);
|
||||||
|
this.reactRouter = {handler: undefined, routes: undefined};
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
26
packages/react/src/router/request.js
Normal file
26
packages/react/src/router/request.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Adapted from https://reactrouter.com/en/main/guides/ssr
|
||||||
|
export function createFetchRequest(req, res) {
|
||||||
|
// Build and propagate request parameters.
|
||||||
|
const headers = new Headers();
|
||||||
|
Object.entries(req.headers).forEach(([key, values = []]) => {
|
||||||
|
(Array.isArray(values) ? values : [values]).forEach((value) => {
|
||||||
|
headers.append(key, value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const init = {headers, method: req.method};
|
||||||
|
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
||||||
|
const urlSearchParams = new URLSearchParams();
|
||||||
|
Object.entries(req.body)
|
||||||
|
.forEach(([name, value]) => {
|
||||||
|
urlSearchParams.append(name, value);
|
||||||
|
});
|
||||||
|
init.body = urlSearchParams;
|
||||||
|
}
|
||||||
|
// Build the request URL.
|
||||||
|
const origin = `${req.protocol}://${req.get('host')}`;
|
||||||
|
const {href} = new URL(req.originalUrl || req.url, origin);
|
||||||
|
// Allow aborting the request.
|
||||||
|
const controller = new AbortController();
|
||||||
|
res.on('close', () => controller.abort());
|
||||||
|
return new Request(href, {...init, signal: controller.signal});
|
||||||
|
}
|
5
packages/react/src/router/routes/index.jsx
Normal file
5
packages/react/src/router/routes/index.jsx
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export function Component() {
|
||||||
|
return <p className="flecks-router-root">No routes.</p>;
|
||||||
|
}
|
|
@ -1,7 +1,37 @@
|
||||||
import {StaticRouter} from 'react-router-dom/server';
|
import {Flecks} from '@flecks/core';
|
||||||
|
import {
|
||||||
|
createStaticHandler,
|
||||||
|
createStaticRouter,
|
||||||
|
StaticRouterProvider,
|
||||||
|
} from 'react-router-dom/server';
|
||||||
|
|
||||||
|
import {createFetchRequest} from './request';
|
||||||
|
|
||||||
export const hooks = {
|
export const hooks = {
|
||||||
'@flecks/react.providers': (req, flecks) => (
|
'@flecks/web/server.request.socket': (flecks) => async (req, res, next) => {
|
||||||
flecks.get('@flecks/react.ssr') ? [StaticRouter, {location: req.url}] : []
|
const {handler} = flecks.reactRouter;
|
||||||
|
const context = await handler.query(createFetchRequest(req, res));
|
||||||
|
if (context instanceof Response && [301, 302, 303, 307, 308].includes(context.status)) {
|
||||||
|
res.redirect(context.status, context.headers.get('Location'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ([404].includes(context.statusCode)) {
|
||||||
|
res.status(context.statusCode);
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
'@flecks/react.roots': async (req, res, flecks) => {
|
||||||
|
const {handler} = flecks.reactRouter;
|
||||||
|
const context = await handler.query(createFetchRequest(req, res));
|
||||||
|
const router = createStaticRouter(handler.dataRoutes, context);
|
||||||
|
return [StaticRouterProvider, {context, router}];
|
||||||
|
},
|
||||||
|
'@flecks/server.up': Flecks.priority(
|
||||||
|
async (flecks) => {
|
||||||
|
flecks.reactRouter.handler = createStaticHandler(flecks.reactRouter.routes);
|
||||||
|
},
|
||||||
|
{before: '@flecks/web/server'},
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
96
packages/react/test/filetree-router.js
Normal file
96
packages/react/test/filetree-router.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import {expect} from 'chai';
|
||||||
|
|
||||||
|
import {createRoutesFromContext} from '@flecks/react/router';
|
||||||
|
|
||||||
|
it('does not nest siblings', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/siblings'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([{path: '/', name: 'index'}, {path: 'test', name: 'sibling'}]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does nest siblings under parent', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/siblings-parent'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'index',
|
||||||
|
children: [
|
||||||
|
{path: ':test', name: 'test'},
|
||||||
|
{path: ':test/nest', name: 'nest'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does nest children', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/children'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'parent',
|
||||||
|
children: [
|
||||||
|
{path: 'test', name: 'child'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('finds dynamic segments', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/dynamic-segments'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'index',
|
||||||
|
children: [
|
||||||
|
{path: ':otherTest?', name: 'otherTest'},
|
||||||
|
{path: ':test', name: 'test'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('finds splats', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/splats'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'index',
|
||||||
|
children: [
|
||||||
|
{path: '*', name: 'splat'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows colocated sources', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/colocated'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([{path: '/', name: 'index'}]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('promotes module with index export', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/index'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'index',
|
||||||
|
children: [
|
||||||
|
{index: true, name: 'test'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('hoists', async () => {
|
||||||
|
const routes = await createRoutesFromContext(require.context('./filetree/hoist'));
|
||||||
|
expect(routes)
|
||||||
|
.to.deep.equal([
|
||||||
|
{path: '/', name: 'index'},
|
||||||
|
{path: '/test', name: 'test'},
|
||||||
|
]);
|
||||||
|
});
|
1
packages/react/test/filetree/children/index.jsx
Normal file
1
packages/react/test/filetree/children/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'parent';
|
1
packages/react/test/filetree/children/test/index.jsx
Normal file
1
packages/react/test/filetree/children/test/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'child';
|
1
packages/react/test/filetree/colocated/index.jsx
Normal file
1
packages/react/test/filetree/colocated/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'index';
|
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'otherTest';
|
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'test';
|
1
packages/react/test/filetree/dynamic-segments/index.jsx
Normal file
1
packages/react/test/filetree/dynamic-segments/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'index';
|
1
packages/react/test/filetree/hoist/index.jsx
Normal file
1
packages/react/test/filetree/hoist/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'index';
|
3
packages/react/test/filetree/hoist/test/index.jsx
Normal file
3
packages/react/test/filetree/hoist/test/index.jsx
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export const hoist = 1;
|
||||||
|
|
||||||
|
export const name = 'test';
|
1
packages/react/test/filetree/index/index.jsx
Normal file
1
packages/react/test/filetree/index/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'index';
|
2
packages/react/test/filetree/index/test/index.jsx
Normal file
2
packages/react/test/filetree/index/test/index.jsx
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export const index = true;
|
||||||
|
export const name = 'test';
|
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'test';
|
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'nest';
|
1
packages/react/test/filetree/siblings-parent/index.jsx
Normal file
1
packages/react/test/filetree/siblings-parent/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'index';
|
1
packages/react/test/filetree/siblings/index.jsx
Normal file
1
packages/react/test/filetree/siblings/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'index';
|
1
packages/react/test/filetree/siblings/test.jsx
Normal file
1
packages/react/test/filetree/siblings/test.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'sibling';
|
1
packages/react/test/filetree/splats/[...splat]/index.jsx
Normal file
1
packages/react/test/filetree/splats/[...splat]/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'splat';
|
1
packages/react/test/filetree/splats/index.jsx
Normal file
1
packages/react/test/filetree/splats/index.jsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export const name = 'index';
|
18
packages/react/test/router-custom.js
Normal file
18
packages/react/test/router-custom.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import {expect} from 'chai';
|
||||||
|
|
||||||
|
import {withWeb} from '@flecks/headless/test/helpers/with-web';
|
||||||
|
|
||||||
|
it('allows custom routes', withWeb(
|
||||||
|
async ({page, response}) => {
|
||||||
|
expect(response)
|
||||||
|
.to.not.be.null;
|
||||||
|
expect(response.ok())
|
||||||
|
.to.be.true;
|
||||||
|
const output = await page.waitForSelector('.custom-route');
|
||||||
|
expect(output)
|
||||||
|
.to.not.be.undefined;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: 'templates/router-custom',
|
||||||
|
},
|
||||||
|
));
|
52
packages/react/test/router-data.js
Normal file
52
packages/react/test/router-data.js
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import {expect} from 'chai';
|
||||||
|
|
||||||
|
import {withWeb} from '@flecks/headless/test/helpers/with-web';
|
||||||
|
|
||||||
|
it('implements data router', withWeb(
|
||||||
|
async ({page, response}) => {
|
||||||
|
expect(response)
|
||||||
|
.to.not.be.null;
|
||||||
|
expect(response.ok())
|
||||||
|
.to.be.true;
|
||||||
|
const output = await page.waitForSelector('.test-contact');
|
||||||
|
expect(await output?.evaluate((el) => el.textContent))
|
||||||
|
.to.equal('2');
|
||||||
|
await page.goto(new URL('/contact/2/edit', await page.url()));
|
||||||
|
expect(await page.waitForSelector('#test-contact-form'))
|
||||||
|
.to.not.be.undefined;
|
||||||
|
await page.type('[name="id"]', '5');
|
||||||
|
await page.click('[type="submit"]');
|
||||||
|
const {pathname} = new URL(await page.url());
|
||||||
|
expect(pathname)
|
||||||
|
.to.equal('/contact/52');
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: '/contact/2',
|
||||||
|
template: 'templates/router-custom',
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
it('implements data router with ssr', withWeb(
|
||||||
|
async ({page, response}) => {
|
||||||
|
expect(response)
|
||||||
|
.to.not.be.null;
|
||||||
|
expect(response.ok())
|
||||||
|
.to.be.true;
|
||||||
|
expect(await page.waitForSelector('#test-contact-form'))
|
||||||
|
.to.not.be.undefined;
|
||||||
|
await page.type('[name="id"]', '5');
|
||||||
|
const navigation = page.waitForNavigation();
|
||||||
|
await page.click('[type="submit"]');
|
||||||
|
await navigation;
|
||||||
|
const {pathname} = new URL(await page.url());
|
||||||
|
expect(pathname)
|
||||||
|
.to.equal('/contact/52');
|
||||||
|
},
|
||||||
|
{
|
||||||
|
beforePage: async ({page}) => {
|
||||||
|
await page.setJavaScriptEnabled(false);
|
||||||
|
},
|
||||||
|
pagePath: '/contact/2/edit',
|
||||||
|
template: 'templates/router-custom',
|
||||||
|
},
|
||||||
|
));
|
36
packages/react/test/router-default.js
Normal file
36
packages/react/test/router-default.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import {expect} from 'chai';
|
||||||
|
|
||||||
|
import {withWeb} from '@flecks/headless/test/helpers/with-web';
|
||||||
|
|
||||||
|
it('provides default routes', withWeb(
|
||||||
|
async ({page, response}) => {
|
||||||
|
expect(response)
|
||||||
|
.to.not.be.null;
|
||||||
|
expect(response.ok())
|
||||||
|
.to.be.true;
|
||||||
|
const output = await page.waitForSelector('.flecks-router-root');
|
||||||
|
expect(output)
|
||||||
|
.to.not.be.undefined;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
template: 'templates/router-default',
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
it('provides default routes with ssr', withWeb(
|
||||||
|
async ({page, response}) => {
|
||||||
|
expect(response)
|
||||||
|
.to.not.be.null;
|
||||||
|
expect(response.ok())
|
||||||
|
.to.be.true;
|
||||||
|
const output = await page.waitForSelector('.flecks-router-root');
|
||||||
|
expect(output)
|
||||||
|
.to.not.be.undefined;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
beforePage: async ({page}) => {
|
||||||
|
await page.setJavaScriptEnabled(false);
|
||||||
|
},
|
||||||
|
template: 'templates/router-default',
|
||||||
|
},
|
||||||
|
));
|
19
packages/react/test/router-lazy.js
Normal file
19
packages/react/test/router-lazy.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import {expect} from 'chai';
|
||||||
|
|
||||||
|
import {withWeb} from '@flecks/headless/test/helpers/with-web';
|
||||||
|
|
||||||
|
it('allows lazy routes', withWeb(
|
||||||
|
async ({page, response}) => {
|
||||||
|
expect(response)
|
||||||
|
.to.not.be.null;
|
||||||
|
expect(response.ok())
|
||||||
|
.to.be.true;
|
||||||
|
const output = await page.waitForSelector('.lazy');
|
||||||
|
expect(output)
|
||||||
|
.to.not.be.undefined;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pagePath: '/lazy',
|
||||||
|
template: 'templates/router-custom',
|
||||||
|
},
|
||||||
|
));
|
|
@ -0,0 +1,7 @@
|
||||||
|
'@flecks/core': {}
|
||||||
|
'@flecks/server': {}
|
||||||
|
'@flecks/react': {}
|
||||||
|
'@flecks/react/router': {
|
||||||
|
root: 'test'
|
||||||
|
}
|
||||||
|
'test:./test': {}
|
1
packages/react/test/templates/router-custom/package.json
Normal file
1
packages/react/test/templates/router-custom/package.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"@flecks/react": "*"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import {createRoutesFromContext} from '@flecks/react/router';
|
||||||
|
|
||||||
|
export const hooks = {
|
||||||
|
'@flecks/react/router.routes': () => createRoutesFromContext(require.context('./routes')),
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
import {React} from '@flecks/react';
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
useLoaderData,
|
||||||
|
redirect,
|
||||||
|
} from '@flecks/react/router';
|
||||||
|
|
||||||
|
export function Component() {
|
||||||
|
const {contact} = useLoaderData();
|
||||||
|
return (
|
||||||
|
<Form method="post" id="test-contact-form">
|
||||||
|
<input
|
||||||
|
aria-label="Contact ID"
|
||||||
|
type="text"
|
||||||
|
name="id"
|
||||||
|
defaultValue={contact}
|
||||||
|
/>
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function action({request}) {
|
||||||
|
const formData = await request.formData();
|
||||||
|
return redirect(`/contact/${formData.get('id')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loader({params}) {
|
||||||
|
return {contact: params.contactId};
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import {React} from '@flecks/react';
|
||||||
|
import {useParams} from '@flecks/react/router';
|
||||||
|
|
||||||
|
export function Component() {
|
||||||
|
const params = useParams();
|
||||||
|
return (
|
||||||
|
<div className="test-contact">
|
||||||
|
{params.contactId}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
import {React} from '@flecks/react';
|
||||||
|
import {Outlet} from '@flecks/react/router';
|
||||||
|
|
||||||
|
export const hoist = 1;
|
||||||
|
|
||||||
|
export function Component() {
|
||||||
|
return <div className="test-contacts"><Outlet /></div>;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import {React} from '@flecks/react';
|
||||||
|
import {Outlet} from '@flecks/react/router';
|
||||||
|
|
||||||
|
export function Component() {
|
||||||
|
return <div className="custom-route"><Outlet /></div>;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import {React} from '@flecks/react';
|
||||||
|
|
||||||
|
export async function lazy() {
|
||||||
|
return {
|
||||||
|
Component() {
|
||||||
|
return <p className="lazy" />;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
'@flecks/core': {}
|
||||||
|
'@flecks/server': {}
|
||||||
|
'@flecks/react': {}
|
||||||
|
'@flecks/react/router': {}
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
Loading…
Reference in New Issue
Block a user