This commit is contained in:
@@ -89,11 +89,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
yarn build
|
yarn build
|
||||||
|
|
||||||
#- name: build ssr
|
- name: build ssr
|
||||||
# env:
|
env:
|
||||||
# FORCE_COLOR: "true"
|
FORCE_COLOR: "true"
|
||||||
# run: |
|
run: |
|
||||||
# yarn build:server
|
yarn build:server
|
||||||
|
|
||||||
- name: build legacy
|
- name: build legacy
|
||||||
env:
|
env:
|
||||||
@@ -101,58 +101,58 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
yarn build:legacy
|
yarn build:legacy
|
||||||
|
|
||||||
- name: Wait for Live Server
|
#- name: Wait for Live Server
|
||||||
run: |
|
# run: |
|
||||||
attempts=0
|
# attempts=0
|
||||||
max_attempts=2
|
# max_attempts=2
|
||||||
while ! curl --output /dev/null --silent --head --fail http://live-server:8081; do
|
# while ! curl --output /dev/null --silent --head --fail http://live-server:8081; do
|
||||||
if [ $attempts -eq $max_attempts ]; then
|
# if [ $attempts -eq $max_attempts ]; then
|
||||||
echo "Live server not ready after $max_attempts attempts"
|
# echo "Live server not ready after $max_attempts attempts"
|
||||||
echo "${{ toJson(job) }}"
|
# echo "${{ toJson(job) }}"
|
||||||
curl -v http://live-server:8081
|
# curl -v http://live-server:8081
|
||||||
exit 1
|
# exit 1
|
||||||
fi
|
# fi
|
||||||
attempts=$((attempts+1))
|
# attempts=$((attempts+1))
|
||||||
echo "Waiting for live-server to be ready... attempt $attempts"
|
# echo "Waiting for live-server to be ready... attempt $attempts"
|
||||||
sleep 5
|
# sleep 5
|
||||||
done
|
# done
|
||||||
|
|
||||||
- name: Test HTTP Request
|
#- name: Test HTTP Request
|
||||||
run: |
|
# run: |
|
||||||
echo "Live server not ready after $max_attempts attempts"
|
# echo "Live server not ready after $max_attempts attempts"
|
||||||
echo "${{ toJson(job) }}"
|
# echo "${{ toJson(job) }}"
|
||||||
echo "${{ job.services.live-server.id }}"
|
# echo "${{ job.services.live-server.id }}"
|
||||||
echo "${{ job.services.tibi-server.id }}"
|
# echo "${{ job.services.tibi-server.id }}"
|
||||||
echo "${{ job.services.mongo.id }}"
|
## echo "${{ job.services.mongo.id }}"
|
||||||
|
|
||||||
docker logs "${{ job.services.tibi-server.id }}"
|
# docker logs "${{ job.services.tibi-server.id }}"
|
||||||
docker logs "${{ job.services.live-server.id }}"
|
# docker logs "${{ job.services.live-server.id }}"
|
||||||
curl -v http://live-server:8081
|
# curl -v http://live-server:8081
|
||||||
|
|
||||||
- name: Install Chrome
|
#- name: Install Chrome
|
||||||
run: |
|
# run: |
|
||||||
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
|
# wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
|
||||||
sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
|
# sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
|
||||||
|
#
|
||||||
sudo apt-get update
|
# sudo apt-get update
|
||||||
sudo apt-get install -y google-chrome-stable
|
# sudo apt-get install -y google-chrome-stable
|
||||||
|
|
||||||
# Lighthouse Analysis Step
|
# Lighthouse Analysis Step
|
||||||
- name: Lighthouse Analysis
|
#- name: Lighthouse Analysis
|
||||||
run: |
|
# run: |
|
||||||
yarn add lighthouse
|
# yarn add lighthouse
|
||||||
npx lighthouse http://127.0.0.1:8081 --output json --output-path /tmp/lighthouse-report.json --chrome-flags="--headless --no-sandbox --disable-dev-shm-usage"
|
# npx lighthouse http://127.0.0.1:8081 --output json --output-path /tmp/lighthouse-report.json --chrome-flags="--headless --no-sandbox --disable-dev-shm-usage"
|
||||||
|
|
||||||
# Notify-Lighthouse Step
|
# Notify-Lighthouse Step
|
||||||
- name: Notify Lighthouse
|
#- name: Notify Lighthouse
|
||||||
run: |
|
# run: |
|
||||||
docker run --rm \
|
# docker run --rm \
|
||||||
-e PLUGIN_FROM=noreply@gitbase.de \
|
# -e PLUGIN_FROM=noreply@gitbase.de \
|
||||||
-e PLUGIN_HOST=smtp.basehosts.de \
|
# -e PLUGIN_HOST=smtp.basehosts.de \
|
||||||
-e PLUGIN_RECIPIENT=recipient@example.com \
|
# -e PLUGIN_RECIPIENT=recipient@example.com \
|
||||||
-e PLUGIN_SUBJECT="Lighthouse Report" \
|
# -e PLUGIN_SUBJECT="Lighthouse Report" \
|
||||||
-v ${{ github.workspace }}/tmp:/lighthouse-reports \
|
# -v ${{ github.workspace }}/tmp:/lighthouse-reports \
|
||||||
drillster/drone-email /tmp/lighthouse-report.json
|
# drillster/drone-email /tmp/lighthouse-report.json
|
||||||
|
|
||||||
- name: deploy
|
- name: deploy
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ meta:
|
|||||||
label: { de: "SSR Dummy", en: "ssr dummy" }
|
label: { de: "SSR Dummy", en: "ssr dummy" }
|
||||||
muiIcon: server
|
muiIcon: server
|
||||||
rowIdentTpl: { twig: "{{ id }}" }
|
rowIdentTpl: { twig: "{{ id }}" }
|
||||||
|
|
||||||
views:
|
views:
|
||||||
- type: simpleList
|
- type: simpleList
|
||||||
mediaQuery: "(max-width: 600px)"
|
mediaQuery: "(max-width: 600px)"
|
||||||
@@ -55,6 +56,7 @@ fields:
|
|||||||
- name: path
|
- name: path
|
||||||
type: string
|
type: string
|
||||||
index: [single, unique]
|
index: [single, unique]
|
||||||
|
|
||||||
- name: content
|
- name: content
|
||||||
type: string
|
type: string
|
||||||
meta:
|
meta:
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ collections:
|
|||||||
- !include collections/banner.yml
|
- !include collections/banner.yml
|
||||||
- !include collections/forms.yml
|
- !include collections/forms.yml
|
||||||
- !include collections/backups.yml
|
- !include collections/backups.yml
|
||||||
|
- !include collections/ssr.yml
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- cron: "0 * * * *"
|
- cron: "0 * * * *"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const release = "tibi-docs.dirty"
|
const release = "tibi-docs.dirty"
|
||||||
|
const apiClientBaseURL = "/api/"
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (release && typeof context !== "undefined") {
|
if (release && typeof context !== "undefined") {
|
||||||
context.response.header("X-Release", release)
|
context.response.header("X-Release", release)
|
||||||
@@ -7,4 +7,5 @@ if (release && typeof context !== "undefined") {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
release,
|
release,
|
||||||
|
apiClientBaseURL,
|
||||||
}
|
}
|
||||||
|
|||||||
180
api/hooks/lib/ssr.js
Normal file
180
api/hooks/lib/ssr.js
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
const { apiClientBaseURL } = require("../config-client")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert object to string
|
||||||
|
* @param {any} obj object
|
||||||
|
*/
|
||||||
|
function obj2str(obj) {
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
return JSON.stringify(
|
||||||
|
obj.map(function (idx) {
|
||||||
|
return obj2str(idx)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
} else if (typeof obj === "object" && obj !== null) {
|
||||||
|
var elements = Object.keys(obj)
|
||||||
|
.sort()
|
||||||
|
.map(function (key) {
|
||||||
|
var val = obj2str(obj[key])
|
||||||
|
if (val) {
|
||||||
|
return key + ":" + val
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var elementsCleaned = []
|
||||||
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
if (elements[i]) elementsCleaned.push(elements[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{" + elementsCleaned.join("|") + "}"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj) return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch polyfill
|
||||||
|
// [MIT License](LICENSE.md) © [Jason Miller](https://jasonformat.com/)
|
||||||
|
const _f = function (
|
||||||
|
/** @type {string | URL} */ url,
|
||||||
|
/** @type {{ method?: any; credentials?: any; headers?: any; body?: any; }} */ options
|
||||||
|
) {
|
||||||
|
if (typeof XMLHttpRequest === "undefined") {
|
||||||
|
return Promise.resolve(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = new XMLHttpRequest()
|
||||||
|
const keys = []
|
||||||
|
const all = []
|
||||||
|
const headers = {}
|
||||||
|
|
||||||
|
const response = () => ({
|
||||||
|
ok: ((request.status / 100) | 0) == 2, // 200-299
|
||||||
|
statusText: request.statusText,
|
||||||
|
status: request.status,
|
||||||
|
url: request.responseURL,
|
||||||
|
text: () => Promise.resolve(request.responseText),
|
||||||
|
json: () => Promise.resolve(request.responseText).then(JSON.parse),
|
||||||
|
blob: () => Promise.resolve(new Blob([request.response])),
|
||||||
|
clone: response,
|
||||||
|
headers: {
|
||||||
|
// @ts-ignore
|
||||||
|
keys: () => keys,
|
||||||
|
// @ts-ignore
|
||||||
|
entries: () => all,
|
||||||
|
get: (n) => headers[n.toLowerCase()],
|
||||||
|
has: (n) => n.toLowerCase() in headers,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
request.open(options.method || "get", url, true)
|
||||||
|
|
||||||
|
request.onload = () => {
|
||||||
|
request
|
||||||
|
.getAllResponseHeaders()
|
||||||
|
// @ts-ignore
|
||||||
|
.replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, (m, key, value) => {
|
||||||
|
keys.push((key = key.toLowerCase()))
|
||||||
|
all.push([key, value])
|
||||||
|
headers[key] = headers[key] ? `${headers[key]},${value}` : value
|
||||||
|
})
|
||||||
|
resolve(response())
|
||||||
|
}
|
||||||
|
|
||||||
|
request.onerror = reject
|
||||||
|
|
||||||
|
request.withCredentials = options.credentials == "include"
|
||||||
|
|
||||||
|
for (const i in options.headers) {
|
||||||
|
request.setRequestHeader(i, options.headers[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
request.send(options.body || null)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const _fetch = typeof fetch === "undefined" ? (typeof window === "undefined" ? _f : window.fetch || _f) : fetch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api request via client or server
|
||||||
|
* server function ssrRequest is called via context.ssrRequest, binded in ssr hook
|
||||||
|
*
|
||||||
|
* @param {string} endpoint
|
||||||
|
* @param {ApiOptions} options
|
||||||
|
* @param {any} body
|
||||||
|
* @returns {Promise<ApiResult<any>>}
|
||||||
|
*/
|
||||||
|
function apiRequest(endpoint, options, body) {
|
||||||
|
// TODO cache only for GET
|
||||||
|
|
||||||
|
// first check cache if on client
|
||||||
|
const cacheKey = obj2str({ endpoint: endpoint, options: options })
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
if (typeof window !== "undefined" && window.__SSR_CACHE__ && options?.method === "GET") {
|
||||||
|
// @ts-ignore
|
||||||
|
const cache = window.__SSR_CACHE__[cacheKey]
|
||||||
|
console.log("SSR:", cacheKey, cache)
|
||||||
|
if (cache) {
|
||||||
|
return Promise.resolve(cache)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let method = options?.method || "GET"
|
||||||
|
|
||||||
|
let query = "&count=1"
|
||||||
|
if (options?.filter) query += "&filter=" + encodeURIComponent(JSON.stringify(options.filter))
|
||||||
|
if (options?.sort) query += "&sort=" + options.sort + "&sort=_id"
|
||||||
|
if (options?.limit) query += "&limit=" + options.limit
|
||||||
|
if (options?.offset) query += "&offset=" + options.offset
|
||||||
|
if (options?.projection) query += "&projection=" + options.projection
|
||||||
|
if (options?.lookup) query += "&lookup=" + options.lookup
|
||||||
|
|
||||||
|
if (options?.params) {
|
||||||
|
Object.keys(options.params).forEach((p) => {
|
||||||
|
query += "&" + p + "=" + encodeURIComponent(options.params[p])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options?.headers) headers = { ...headers, ...options.headers }
|
||||||
|
|
||||||
|
if (typeof window === "undefined" && method === "GET") {
|
||||||
|
// server
|
||||||
|
|
||||||
|
// reference via context from get hook to tree shake in client
|
||||||
|
// @ts-ignore
|
||||||
|
const d = context.ssrRequest(cacheKey, endpoint, query, Object.assign({}, options, { method, headers }))
|
||||||
|
return d
|
||||||
|
} else {
|
||||||
|
// client
|
||||||
|
let url = endpoint + (query ? "?" + query : "")
|
||||||
|
const requestOptions = {
|
||||||
|
method,
|
||||||
|
mode: "cors",
|
||||||
|
headers,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method === "POST" || method === "PUT") {
|
||||||
|
requestOptions.body = JSON.stringify(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
return _fetch(apiClientBaseURL + url, requestOptions).then((response) => {
|
||||||
|
return response?.json().then((json) => {
|
||||||
|
if (response?.status < 200 || response?.status >= 400) {
|
||||||
|
return Promise.reject({ response, data: json })
|
||||||
|
}
|
||||||
|
return Promise.resolve({ data: json || null, count: response.headers?.get("x-results-count") || 0 })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
obj2str,
|
||||||
|
apiRequest,
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ const { obj2str, log } = require("../lib/utils")
|
|||||||
;(function () {
|
;(function () {
|
||||||
/** @type {HookResponse} */
|
/** @type {HookResponse} */
|
||||||
var response = null
|
var response = null
|
||||||
|
console.log("SSR GET READ")
|
||||||
var request = context.request()
|
var request = context.request()
|
||||||
var url = request.query("url")
|
var url = request.query("url")
|
||||||
var noCache = request.query("noCache")
|
var noCache = request.query("noCache")
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
const fs = require("fs")
|
||||||
|
|
||||||
const resolvePlugin = {
|
const resolvePlugin = {
|
||||||
name: "resolvePlugin",
|
name: "resolvePlugin",
|
||||||
setup(build) {
|
setup(build) {
|
||||||
@@ -68,7 +70,9 @@ const bsMiddleware = []
|
|||||||
|
|
||||||
if (process.argv[2] == "start") {
|
if (process.argv[2] == "start") {
|
||||||
const { createProxyMiddleware } = require("http-proxy-middleware")
|
const { createProxyMiddleware } = require("http-proxy-middleware")
|
||||||
const apiBase = process.env.API_BASE || "http://localhost:8080/api/v1/_/" + process.env.NAMESPACE
|
const dotEnv = fs.readFileSync(__dirname + "/.env", "utf8")
|
||||||
|
const TIBI_NAMESPACE = dotEnv.match(/TIBI_NAMESPACE=(.*)/)[1]
|
||||||
|
const apiBase = process.env.API_BASE || "http://localhost:8080/api/v1/_/" + TIBI_NAMESPACE
|
||||||
bsMiddleware.push(
|
bsMiddleware.push(
|
||||||
createProxyMiddleware("/api", {
|
createProxyMiddleware("/api", {
|
||||||
target: apiBase,
|
target: apiBase,
|
||||||
@@ -77,12 +81,39 @@ if (process.argv[2] == "start") {
|
|||||||
logLevel: "debug",
|
logLevel: "debug",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// if SSR env variable is set
|
||||||
|
console.log(process.env)
|
||||||
|
if (process.env.SSR) {
|
||||||
|
// read api/config.yml.env and read SSR_TOKEN variable from it
|
||||||
|
const configEnv = fs.readFileSync(__dirname + "/api/config.yml.env", "utf8")
|
||||||
|
const SSR_TOKEN = configEnv.match(/SSR_TOKEN=(.*)/)[1]
|
||||||
|
|
||||||
|
// redirect all other requests to /api/ssr?token=owshwerNwoa&url=...
|
||||||
|
bsMiddleware.push(
|
||||||
|
createProxyMiddleware(
|
||||||
|
function (path, req) {
|
||||||
|
return !path.match(/\./)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
target: apiBase,
|
||||||
|
changeOrigin: true,
|
||||||
|
logLevel: "debug",
|
||||||
|
pathRewrite: function (path, req) {
|
||||||
|
console.log(path)
|
||||||
|
return "/ssr?token=" + SSR_TOKEN + "&url=" + encodeURIComponent(path)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sveltePlugin: sveltePlugin,
|
sveltePlugin: sveltePlugin,
|
||||||
resolvePlugin: resolvePlugin,
|
resolvePlugin: resolvePlugin,
|
||||||
options: options,
|
options: options,
|
||||||
|
distDir,
|
||||||
watch: {
|
watch: {
|
||||||
path: [__dirname + "/" + frontendDir + "/src/**/*"],
|
path: [__dirname + "/" + frontendDir + "/src/**/*"],
|
||||||
},
|
},
|
||||||
@@ -103,7 +134,6 @@ module.exports = {
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
ghostMode: false,
|
|
||||||
open: false,
|
open: false,
|
||||||
// logLevel: "debug",
|
// logLevel: "debug",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
AddType application/javascript .mjs
|
AddType application/javascript .mjs
|
||||||
|
|
||||||
DirectoryIndex spa.html
|
#DirectoryIndex spa.html
|
||||||
#DirectoryIndex noindex
|
DirectoryIndex noindex
|
||||||
|
|
||||||
<ifModule mod_rewrite.c>
|
<ifModule mod_rewrite.c>
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
@@ -11,5 +11,6 @@ DirectoryIndex spa.html
|
|||||||
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
RewriteRule (.*) /spa.html [QSA,L]
|
RewriteRule ^/?(.*)$ http://tibi-server:8080/api/v1/_/allkids_erfurt/ssr?token=owshwerNwoa&url=/$1 [P,QSA,L]
|
||||||
|
#RewriteRule (.*) /spa.html [QSA,L]
|
||||||
</ifModule>
|
</ifModule>
|
||||||
|
|||||||
@@ -1,121 +1,12 @@
|
|||||||
import { apiBaseURL } from "./config"
|
import { apiRequest } from "../../api/hooks/lib/ssr"
|
||||||
|
|
||||||
const _f = function (url, options): Promise<Response> {
|
|
||||||
if (typeof XMLHttpRequest === "undefined") {
|
|
||||||
return Promise.resolve(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
options = options || {}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const request = new XMLHttpRequest()
|
|
||||||
const keys = []
|
|
||||||
const all = []
|
|
||||||
const headers = {}
|
|
||||||
|
|
||||||
const response = (): Response => ({
|
|
||||||
ok: ((request.status / 100) | 0) == 2, // 200-299
|
|
||||||
statusText: request.statusText,
|
|
||||||
status: request.status,
|
|
||||||
url: request.responseURL,
|
|
||||||
text: () => Promise.resolve(request.responseText),
|
|
||||||
json: () => Promise.resolve(request.responseText).then(JSON.parse),
|
|
||||||
blob: () => Promise.resolve(new Blob([request.response])),
|
|
||||||
clone: response,
|
|
||||||
headers: {
|
|
||||||
// @ts-ignore
|
|
||||||
keys: () => keys,
|
|
||||||
// @ts-ignore
|
|
||||||
entries: () => all,
|
|
||||||
get: (n) => headers[n.toLowerCase()],
|
|
||||||
has: (n) => n.toLowerCase() in headers,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
request.open(options.method || "get", url, true)
|
|
||||||
|
|
||||||
request.onload = () => {
|
|
||||||
request
|
|
||||||
.getAllResponseHeaders()
|
|
||||||
// @ts-ignore
|
|
||||||
.replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, (m, key, value) => {
|
|
||||||
keys.push((key = key.toLowerCase()))
|
|
||||||
all.push([key, value])
|
|
||||||
headers[key] = headers[key] ? `${headers[key]},${value}` : value
|
|
||||||
})
|
|
||||||
resolve(response())
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onerror = reject
|
|
||||||
request.withCredentials = options.credentials == "include"
|
|
||||||
for (const i in options.headers) {
|
|
||||||
request.setRequestHeader(i, options.headers[i])
|
|
||||||
}
|
|
||||||
request.send(options.body || null)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const _fetch = typeof fetch === "undefined" ? (typeof window === "undefined" ? _f : window.fetch || _f) : fetch
|
|
||||||
|
|
||||||
export const api = async <T>(
|
export const api = async <T>(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
options?: {
|
options?: ApiOptions,
|
||||||
method?: string
|
|
||||||
filter?: any
|
|
||||||
sort?: string
|
|
||||||
limit?: number
|
|
||||||
offset?: number
|
|
||||||
projection?: string
|
|
||||||
headers?: {
|
|
||||||
[key: string]: string
|
|
||||||
}
|
|
||||||
params?: {
|
|
||||||
[key: string]: string
|
|
||||||
}
|
|
||||||
},
|
|
||||||
body?: any
|
body?: any
|
||||||
): Promise<{ data: T; count: number } | any> => {
|
): Promise<{ data: T; count: number } | any> => {
|
||||||
if (typeof window === "undefined") {
|
let data = await apiRequest(endpoint, options, body)
|
||||||
// ssr
|
|
||||||
// @ts-ignore
|
|
||||||
return context.ssrFetch(endpoint, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
let method = options?.method || "GET"
|
|
||||||
|
|
||||||
let query = "&count=1"
|
|
||||||
if (options?.filter) query += "&filter=" + encodeURIComponent(JSON.stringify(options.filter))
|
|
||||||
if (options?.sort) query += "&sort=" + options.sort + "&sort=_id"
|
|
||||||
if (options?.limit) query += "&limit=" + options.limit
|
|
||||||
if (options?.offset) query += "&offset=" + options.offset
|
|
||||||
if (options?.projection) query += "&projection=" + options.projection
|
|
||||||
|
|
||||||
if (options?.params) {
|
|
||||||
Object.keys(options.params).forEach((p) => {
|
|
||||||
query += "&" + p + "=" + encodeURIComponent(options.params[p])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let headers: any = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.headers) headers = { ...headers, ...options.headers }
|
|
||||||
|
|
||||||
let url = apiBaseURL + endpoint + (query ? "?" + query : "")
|
|
||||||
|
|
||||||
const requestOptions: any = {
|
|
||||||
method,
|
|
||||||
mode: "cors",
|
|
||||||
headers,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method === "POST" || method === "PUT") {
|
|
||||||
requestOptions.body = JSON.stringify(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
let response = await _fetch(url, requestOptions)
|
|
||||||
if (response.status == 409 || response.status == 401) return response
|
|
||||||
let data = (await response?.json()) || null
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return { data }
|
console.log(data, "data")
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import App from "./components/App.svelte"
|
import App from "./App.svelte"
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
|
|||||||
21
types/global.d.ts
vendored
21
types/global.d.ts
vendored
@@ -2,6 +2,27 @@ interface Sites {
|
|||||||
[key: string]: Site
|
[key: string]: Site
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ApiResult<T> {
|
||||||
|
data: T
|
||||||
|
count: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ApiOptions {
|
||||||
|
method?: string
|
||||||
|
filter?: any
|
||||||
|
sort?: string
|
||||||
|
lookup?: string
|
||||||
|
limit?: number
|
||||||
|
offset?: number
|
||||||
|
projection?: string
|
||||||
|
headers?: {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
params?: {
|
||||||
|
[key: string]: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface Site {
|
interface Site {
|
||||||
path: string
|
path: string
|
||||||
showTeaser: boolean
|
showTeaser: boolean
|
||||||
|
|||||||
Reference in New Issue
Block a user