Spaces:
Build error
Build error
wip
Browse files- .github/workflows/.keep +0 -0
- .gitignore +2 -129
- .gitmodules +3 -0
- .vscode/exensions.json +10 -0
- .vscode/launch.json +60 -0
- .vscode/settings.json +105 -0
- .vscode/tasks.json +156 -0
- README.md +112 -1
- backend/.firebaserc +5 -0
- backend/.gitignore +75 -0
- backend/firebase.json +44 -0
- backend/firestore.indexes.json +19 -0
- backend/firestore.rules +32 -0
- backend/functions/.editorconfig +36 -0
- backend/functions/.env.example +0 -0
- backend/functions/.vscode/launch.json +27 -0
- backend/functions/.vscode/settings.json +10 -0
- backend/functions/firebase-export-1712748362961bSfwZx/firestore_export/firestore_export.overall_export_metadata +0 -0
- backend/functions/package.json +72 -0
- backend/functions/src/cloud-functions/crawler.ts +69 -0
- backend/functions/src/fetch.d.ts +13 -0
- backend/functions/src/index.ts +33 -0
- backend/functions/src/services/puppeteer.ts +152 -0
- backend/functions/src/shared +1 -0
- backend/functions/src/types.d.ts +9 -0
- backend/functions/tsconfig.json +21 -0
- backend/storage.rules +8 -0
- package.json +15 -0
- thinapps-shared +1 -0
.github/workflows/.keep
ADDED
|
File without changes
|
.gitignore
CHANGED
|
@@ -1,130 +1,3 @@
|
|
| 1 |
-
|
| 2 |
-
logs
|
| 3 |
-
*.log
|
| 4 |
-
npm-debug.log*
|
| 5 |
-
yarn-debug.log*
|
| 6 |
-
yarn-error.log*
|
| 7 |
-
lerna-debug.log*
|
| 8 |
-
.pnpm-debug.log*
|
| 9 |
-
|
| 10 |
-
# Diagnostic reports (https://nodejs.org/api/report.html)
|
| 11 |
-
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
| 12 |
-
|
| 13 |
-
# Runtime data
|
| 14 |
-
pids
|
| 15 |
-
*.pid
|
| 16 |
-
*.seed
|
| 17 |
-
*.pid.lock
|
| 18 |
-
|
| 19 |
-
# Directory for instrumented libs generated by jscoverage/JSCover
|
| 20 |
-
lib-cov
|
| 21 |
-
|
| 22 |
-
# Coverage directory used by tools like istanbul
|
| 23 |
-
coverage
|
| 24 |
-
*.lcov
|
| 25 |
-
|
| 26 |
-
# nyc test coverage
|
| 27 |
-
.nyc_output
|
| 28 |
-
|
| 29 |
-
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
| 30 |
-
.grunt
|
| 31 |
-
|
| 32 |
-
# Bower dependency directory (https://bower.io/)
|
| 33 |
-
bower_components
|
| 34 |
-
|
| 35 |
-
# node-waf configuration
|
| 36 |
-
.lock-wscript
|
| 37 |
-
|
| 38 |
-
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
| 39 |
-
build/Release
|
| 40 |
-
|
| 41 |
-
# Dependency directories
|
| 42 |
node_modules/
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
# Snowpack dependency directory (https://snowpack.dev/)
|
| 46 |
-
web_modules/
|
| 47 |
-
|
| 48 |
-
# TypeScript cache
|
| 49 |
-
*.tsbuildinfo
|
| 50 |
-
|
| 51 |
-
# Optional npm cache directory
|
| 52 |
-
.npm
|
| 53 |
-
|
| 54 |
-
# Optional eslint cache
|
| 55 |
-
.eslintcache
|
| 56 |
-
|
| 57 |
-
# Optional stylelint cache
|
| 58 |
-
.stylelintcache
|
| 59 |
-
|
| 60 |
-
# Microbundle cache
|
| 61 |
-
.rpt2_cache/
|
| 62 |
-
.rts2_cache_cjs/
|
| 63 |
-
.rts2_cache_es/
|
| 64 |
-
.rts2_cache_umd/
|
| 65 |
-
|
| 66 |
-
# Optional REPL history
|
| 67 |
-
.node_repl_history
|
| 68 |
-
|
| 69 |
-
# Output of 'npm pack'
|
| 70 |
-
*.tgz
|
| 71 |
-
|
| 72 |
-
# Yarn Integrity file
|
| 73 |
-
.yarn-integrity
|
| 74 |
-
|
| 75 |
-
# dotenv environment variable files
|
| 76 |
-
.env
|
| 77 |
-
.env.development.local
|
| 78 |
-
.env.test.local
|
| 79 |
-
.env.production.local
|
| 80 |
-
.env.local
|
| 81 |
-
|
| 82 |
-
# parcel-bundler cache (https://parceljs.org/)
|
| 83 |
-
.cache
|
| 84 |
-
.parcel-cache
|
| 85 |
-
|
| 86 |
-
# Next.js build output
|
| 87 |
-
.next
|
| 88 |
-
out
|
| 89 |
-
|
| 90 |
-
# Nuxt.js build / generate output
|
| 91 |
-
.nuxt
|
| 92 |
-
dist
|
| 93 |
-
|
| 94 |
-
# Gatsby files
|
| 95 |
-
.cache/
|
| 96 |
-
# Comment in the public line in if your project uses Gatsby and not Next.js
|
| 97 |
-
# https://nextjs.org/blog/next-9-1#public-directory-support
|
| 98 |
-
# public
|
| 99 |
-
|
| 100 |
-
# vuepress build output
|
| 101 |
-
.vuepress/dist
|
| 102 |
-
|
| 103 |
-
# vuepress v2.x temp and cache directory
|
| 104 |
-
.temp
|
| 105 |
-
.cache
|
| 106 |
-
|
| 107 |
-
# Docusaurus cache and generated files
|
| 108 |
-
.docusaurus
|
| 109 |
-
|
| 110 |
-
# Serverless directories
|
| 111 |
-
.serverless/
|
| 112 |
-
|
| 113 |
-
# FuseBox cache
|
| 114 |
-
.fusebox/
|
| 115 |
-
|
| 116 |
-
# DynamoDB Local files
|
| 117 |
-
.dynamodb/
|
| 118 |
-
|
| 119 |
-
# TernJS port file
|
| 120 |
-
.tern-port
|
| 121 |
-
|
| 122 |
-
# Stores VSCode versions used for testing VSCode extensions
|
| 123 |
-
.vscode-test
|
| 124 |
-
|
| 125 |
-
# yarn v2
|
| 126 |
-
.yarn/cache
|
| 127 |
-
.yarn/unplugged
|
| 128 |
-
.yarn/build-state.yml
|
| 129 |
-
.yarn/install-state.gz
|
| 130 |
-
.pnp.*
|
|
|
|
| 1 |
+
package-lock.json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
node_modules/
|
| 3 |
+
.DS_Store
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.gitmodules
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[submodule "thinapps-shared"]
|
| 2 |
+
path = thinapps-shared
|
| 3 |
+
url = git@github.com:jina-ai/thinapps-shared.git
|
.vscode/exensions.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"recommendations": [
|
| 3 |
+
"editorconfig.editorconfig",
|
| 4 |
+
"octref.vetur",
|
| 5 |
+
"redhat.vscode-yaml",
|
| 6 |
+
"dbaeumer.vscode-eslint",
|
| 7 |
+
"esbenp.prettier-vscode",
|
| 8 |
+
"streetsidesoftware.code-spell-checker"
|
| 9 |
+
]
|
| 10 |
+
}
|
.vscode/launch.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "0.2.0",
|
| 3 |
+
"configurations": [
|
| 4 |
+
{
|
| 5 |
+
"name": "Debug Fullstack: attach",
|
| 6 |
+
"request": "attach",
|
| 7 |
+
"cwd": "${workspaceFolder}/backend/functions",
|
| 8 |
+
"skipFiles": [
|
| 9 |
+
"<node_internals>/**"
|
| 10 |
+
],
|
| 11 |
+
"type": "node",
|
| 12 |
+
"preLaunchTask": "Fullstack:debug"
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"name": "Debug Fullstack: attach: with proxy",
|
| 16 |
+
"request": "attach",
|
| 17 |
+
"cwd": "${workspaceFolder}/backend/functions",
|
| 18 |
+
"skipFiles": [
|
| 19 |
+
"<node_internals>/**"
|
| 20 |
+
],
|
| 21 |
+
"type": "node",
|
| 22 |
+
"preLaunchTask": "Fullstack:debug:with-proxy"
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"name": "Attach",
|
| 26 |
+
"port": 9229,
|
| 27 |
+
"request": "attach",
|
| 28 |
+
"skipFiles": [
|
| 29 |
+
"<node_internals>/**"
|
| 30 |
+
],
|
| 31 |
+
"type": "node"
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"name": "Attach by Process ID",
|
| 35 |
+
"processId": "${command:PickProcess}",
|
| 36 |
+
"request": "attach",
|
| 37 |
+
"skipFiles": [
|
| 38 |
+
"<node_internals>/**"
|
| 39 |
+
],
|
| 40 |
+
"type": "node"
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"name": "Debug Fullstack",
|
| 44 |
+
"request": "launch",
|
| 45 |
+
"runtimeArgs": [
|
| 46 |
+
"emulators:start",
|
| 47 |
+
"--import=../.firebase-emu",
|
| 48 |
+
"--export-on-exit=../.firebase-emu",
|
| 49 |
+
],
|
| 50 |
+
"cwd": "${workspaceFolder}/backend/functions",
|
| 51 |
+
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/firebase",
|
| 52 |
+
"skipFiles": [
|
| 53 |
+
"<node_internals>/**"
|
| 54 |
+
],
|
| 55 |
+
"type": "node",
|
| 56 |
+
"preLaunchTask": "Fullstack:prepare",
|
| 57 |
+
"killBehavior": "polite"
|
| 58 |
+
},
|
| 59 |
+
]
|
| 60 |
+
}
|
.vscode/settings.json
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"editor.wordWrap": "on",
|
| 3 |
+
"editor.wordWrapColumn": 120,
|
| 4 |
+
"files.trimTrailingWhitespace": true,
|
| 5 |
+
"files.trimFinalNewlines": true,
|
| 6 |
+
"[javascript]": {
|
| 7 |
+
"editor.defaultFormatter": "vscode.typescript-language-features"
|
| 8 |
+
},
|
| 9 |
+
"[vue]": {
|
| 10 |
+
"editor.defaultFormatter": "Vue.volar"
|
| 11 |
+
},
|
| 12 |
+
"[jsonc]": {
|
| 13 |
+
"editor.defaultFormatter": "vscode.json-language-features"
|
| 14 |
+
},
|
| 15 |
+
"[typescript]": {
|
| 16 |
+
"editor.defaultFormatter": "vscode.typescript-language-features"
|
| 17 |
+
},
|
| 18 |
+
"[json]": {
|
| 19 |
+
"editor.defaultFormatter": "vscode.json-language-features"
|
| 20 |
+
},
|
| 21 |
+
"[yaml]": {
|
| 22 |
+
"editor.defaultFormatter": "redhat.vscode-yaml"
|
| 23 |
+
},
|
| 24 |
+
"[markdown]": {
|
| 25 |
+
"files.trimTrailingWhitespace": false
|
| 26 |
+
},
|
| 27 |
+
"typescript.tsdk": "node_modules/typescript/lib",
|
| 28 |
+
"vetur.format.defaultFormatter.ts": "vscode-typescript",
|
| 29 |
+
"vetur.format.defaultFormatter.js": "vscode-typescript",
|
| 30 |
+
"typescript.preferences.quoteStyle": "single",
|
| 31 |
+
"typescript.format.semicolons": "insert",
|
| 32 |
+
"typescript.preferences.importModuleSpecifier": "project-relative",
|
| 33 |
+
"typescript.locale": "en",
|
| 34 |
+
"cSpell.enabled": true,
|
| 35 |
+
"cSpell.words": [
|
| 36 |
+
"Apiextensions",
|
| 37 |
+
"apihubble",
|
| 38 |
+
"auths",
|
| 39 |
+
"AUTOCASTABLE",
|
| 40 |
+
"Autocasting",
|
| 41 |
+
"backchannel",
|
| 42 |
+
"bodyparser",
|
| 43 |
+
"bson",
|
| 44 |
+
"BUILDKIT",
|
| 45 |
+
"buildx",
|
| 46 |
+
"castable",
|
| 47 |
+
"cmdl",
|
| 48 |
+
"Commandline",
|
| 49 |
+
"conpty",
|
| 50 |
+
"cpid",
|
| 51 |
+
"deferreds",
|
| 52 |
+
"DEVBOT",
|
| 53 |
+
"dockerhub",
|
| 54 |
+
"entrypoint",
|
| 55 |
+
"ENVIROMENT",
|
| 56 |
+
"finetuner",
|
| 57 |
+
"fpath",
|
| 58 |
+
"fswalk",
|
| 59 |
+
"Grafana",
|
| 60 |
+
"Hasher",
|
| 61 |
+
"istio",
|
| 62 |
+
"jina",
|
| 63 |
+
"jinahub",
|
| 64 |
+
"jinameta",
|
| 65 |
+
"Knative",
|
| 66 |
+
"kourier",
|
| 67 |
+
"kube",
|
| 68 |
+
"kubectl",
|
| 69 |
+
"Kubernetes",
|
| 70 |
+
"kwargs",
|
| 71 |
+
"letsencrypt",
|
| 72 |
+
"liveconfigs",
|
| 73 |
+
"LOGNAME",
|
| 74 |
+
"metas",
|
| 75 |
+
"Mgmt",
|
| 76 |
+
"middlewares",
|
| 77 |
+
"minikube",
|
| 78 |
+
"minio",
|
| 79 |
+
"ndjson",
|
| 80 |
+
"nodelib",
|
| 81 |
+
"oidc",
|
| 82 |
+
"openapi",
|
| 83 |
+
"paramtypes",
|
| 84 |
+
"penv",
|
| 85 |
+
"pino",
|
| 86 |
+
"prebuild",
|
| 87 |
+
"quickstart",
|
| 88 |
+
"reinit",
|
| 89 |
+
"sslip",
|
| 90 |
+
"subval",
|
| 91 |
+
"Succ",
|
| 92 |
+
"timedout",
|
| 93 |
+
"TOTP",
|
| 94 |
+
"tsbuildinfo",
|
| 95 |
+
"tsyringe",
|
| 96 |
+
"typeclass",
|
| 97 |
+
"upsert",
|
| 98 |
+
"upserted",
|
| 99 |
+
"userinfo",
|
| 100 |
+
"Vecs",
|
| 101 |
+
"vectorize",
|
| 102 |
+
"WECHAT",
|
| 103 |
+
"WXPAY"
|
| 104 |
+
],
|
| 105 |
+
}
|
.vscode/tasks.json
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "2.0.0",
|
| 3 |
+
"tasks": [
|
| 4 |
+
{
|
| 5 |
+
"type": "npm",
|
| 6 |
+
"script": "build",
|
| 7 |
+
"group": "build",
|
| 8 |
+
"options": {
|
| 9 |
+
"cwd": "${workspaceFolder}/backend/functions"
|
| 10 |
+
},
|
| 11 |
+
"problemMatcher": [],
|
| 12 |
+
"label": "Backend:rebuild",
|
| 13 |
+
"detail": "Backend:rebuild"
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"type": "npm",
|
| 17 |
+
"script": "emu:reset",
|
| 18 |
+
"group": "build",
|
| 19 |
+
"options": {
|
| 20 |
+
"cwd": "${workspaceFolder}/backend/functions"
|
| 21 |
+
},
|
| 22 |
+
"problemMatcher": [],
|
| 23 |
+
"label": "Backend:reset-emulator",
|
| 24 |
+
"detail": "Backend:reset-emulator"
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"type": "typescript",
|
| 28 |
+
"options": {
|
| 29 |
+
"cwd": "${workspaceFolder}/backend/functions"
|
| 30 |
+
},
|
| 31 |
+
"tsconfig": "backend/functions/tsconfig.json",
|
| 32 |
+
"option": "watch",
|
| 33 |
+
"isBackground": true,
|
| 34 |
+
"problemMatcher": [
|
| 35 |
+
"$tsc-watch"
|
| 36 |
+
],
|
| 37 |
+
"group": "build",
|
| 38 |
+
"label": "Backend:build:watch"
|
| 39 |
+
},
|
| 40 |
+
{
|
| 41 |
+
"type": "npm",
|
| 42 |
+
"script": "emu:debug",
|
| 43 |
+
"group": "none",
|
| 44 |
+
"options": {
|
| 45 |
+
"cwd": "${workspaceFolder}/backend/functions"
|
| 46 |
+
},
|
| 47 |
+
"problemMatcher": [
|
| 48 |
+
{
|
| 49 |
+
"base": "$tsc",
|
| 50 |
+
"background": {
|
| 51 |
+
"activeOnStart": false,
|
| 52 |
+
"beginsPattern": "shutdown requested|Starting emulators",
|
| 53 |
+
"endsPattern": "Debugger listening"
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
],
|
| 57 |
+
"label": "Backend:start-emulator-debug",
|
| 58 |
+
"detail": "Backend:start-emulator-debug",
|
| 59 |
+
"dependsOn": [
|
| 60 |
+
"Backend:build:watch"
|
| 61 |
+
],
|
| 62 |
+
"isBackground": true,
|
| 63 |
+
},
|
| 64 |
+
{
|
| 65 |
+
"type": "npm",
|
| 66 |
+
"script": "dev",
|
| 67 |
+
"options": {
|
| 68 |
+
"cwd": "${workspaceFolder}/webapp",
|
| 69 |
+
},
|
| 70 |
+
"group": "build",
|
| 71 |
+
"label": "Frontend:start:dev",
|
| 72 |
+
"detail": "Frontend:start:dev",
|
| 73 |
+
"isBackground": true,
|
| 74 |
+
"problemMatcher": {
|
| 75 |
+
"base": "$vite",
|
| 76 |
+
"background": {
|
| 77 |
+
"activeOnStart": true,
|
| 78 |
+
"endsPattern": "OK",
|
| 79 |
+
"beginsPattern": "vite"
|
| 80 |
+
}
|
| 81 |
+
},
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"type": "npm",
|
| 85 |
+
"script": "dev",
|
| 86 |
+
"options": {
|
| 87 |
+
"cwd": "${workspaceFolder}/webapp",
|
| 88 |
+
"env": {
|
| 89 |
+
"FIREBASE_EMULATE": "true",
|
| 90 |
+
}
|
| 91 |
+
},
|
| 92 |
+
"group": "build",
|
| 93 |
+
"label": "Frontend:start:emu",
|
| 94 |
+
"detail": "Frontend:start:emu",
|
| 95 |
+
"isBackground": true,
|
| 96 |
+
"problemMatcher": {
|
| 97 |
+
"base": "$vite",
|
| 98 |
+
"background": {
|
| 99 |
+
"activeOnStart": true,
|
| 100 |
+
"endsPattern": "OK",
|
| 101 |
+
"beginsPattern": "vite"
|
| 102 |
+
}
|
| 103 |
+
},
|
| 104 |
+
},
|
| 105 |
+
{
|
| 106 |
+
"type": "npm",
|
| 107 |
+
"script": "emu:debug2",
|
| 108 |
+
"group": "none",
|
| 109 |
+
"options": {
|
| 110 |
+
"cwd": "${workspaceFolder}/backend/functions",
|
| 111 |
+
"env": {
|
| 112 |
+
"https_proxy": "http://127.0.0.1:7890",
|
| 113 |
+
"http_proxy": "http://127.0.0.1:7890",
|
| 114 |
+
"all_proxy": "socks5://127.0.0.1:7890"
|
| 115 |
+
}
|
| 116 |
+
},
|
| 117 |
+
"problemMatcher": [
|
| 118 |
+
{
|
| 119 |
+
"base": "$tsc",
|
| 120 |
+
"background": {
|
| 121 |
+
"activeOnStart": false,
|
| 122 |
+
"beginsPattern": "shutdown requested|Starting emulators",
|
| 123 |
+
"endsPattern": "Debugger listening"
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
],
|
| 127 |
+
"label": "Backend:start-emulator-debug:with-proxy",
|
| 128 |
+
"detail": "Backend:start-emulator-debug:with-proxy",
|
| 129 |
+
"dependsOn": [
|
| 130 |
+
"Backend:build:watch"
|
| 131 |
+
],
|
| 132 |
+
"isBackground": true,
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"label": "Fullstack:prepare",
|
| 136 |
+
"dependsOn": [
|
| 137 |
+
"Frontend:start:emu",
|
| 138 |
+
"Backend:build:watch",
|
| 139 |
+
],
|
| 140 |
+
},
|
| 141 |
+
{
|
| 142 |
+
"label": "Fullstack:debug",
|
| 143 |
+
"dependsOn": [
|
| 144 |
+
// "Frontend:start:emu",
|
| 145 |
+
"Backend:start-emulator-debug",
|
| 146 |
+
],
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"label": "Fullstack:debug:with-proxy",
|
| 150 |
+
"dependsOn": [
|
| 151 |
+
"Frontend:start:emu",
|
| 152 |
+
"Backend:start-emulator-debug:with-proxy",
|
| 153 |
+
],
|
| 154 |
+
}
|
| 155 |
+
]
|
| 156 |
+
}
|
README.md
CHANGED
|
@@ -1 +1,112 @@
|
|
| 1 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Url2Text
|
| 2 |
+
|
| 3 |
+
## Development Guide
|
| 4 |
+
|
| 5 |
+
### Prerequisite
|
| 6 |
+
- Node v18 (The build fails for Node version >18)
|
| 7 |
+
- Yarn
|
| 8 |
+
- Firebase CLI (`npm install -g firebase-tools`)
|
| 9 |
+
|
| 10 |
+
### Installation
|
| 11 |
+
|
| 12 |
+
Clone the scenex repo by running the command:
|
| 13 |
+
|
| 14 |
+
```bash
|
| 15 |
+
git clone git@github.com:jina-ai/url2text.git
|
| 16 |
+
git submodule init
|
| 17 |
+
git submodule update
|
| 18 |
+
```
|
| 19 |
+
|
| 20 |
+
After a successful clone, install the packages for backend and the webapp.
|
| 21 |
+
|
| 22 |
+
For backend, go to the `backend/functions` directory and install the npm dependencies.
|
| 23 |
+
|
| 24 |
+
```bash
|
| 25 |
+
cd backend/functions
|
| 26 |
+
npm install
|
| 27 |
+
```
|
| 28 |
+
|
| 29 |
+
For the frontend (webapp), go to the `webapp` directory and install the yarn dependencies.
|
| 30 |
+
|
| 31 |
+
```bash
|
| 32 |
+
cd webapp
|
| 33 |
+
yarn
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
### Configure
|
| 37 |
+
|
| 38 |
+
**Establish localhost connection:**
|
| 39 |
+
|
| 40 |
+
Once the packages are installed, go to the `App.vue` file inside the `webapp/src/` and uncomment the below code:
|
| 41 |
+
|
| 42 |
+
```js
|
| 43 |
+
connectFunctionsEmulator(functions, 'localhost', 5001);
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
### Run The Application Now
|
| 47 |
+
|
| 48 |
+
To run the backend server, inside the `backend/functions` dir run the below command:
|
| 49 |
+
|
| 50 |
+
```bash
|
| 51 |
+
npm run serve
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
To run the frontend app, inside the `webapp` dir run the below command:
|
| 55 |
+
|
| 56 |
+
```bash
|
| 57 |
+
yarn dev
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
### Known Errors
|
| 61 |
+
|
| 62 |
+
1. If you encounter 'npm ERR! /bin/sh: pkg-config: command not found' error in Mac, run the command `brew install pkg-config cairo libpng jpeg giflib pango librsvg`
|
| 63 |
+
|
| 64 |
+
## Best practices
|
| 65 |
+
|
| 66 |
+
### Directory structure
|
| 67 |
+
|
| 68 |
+
There are three folders:
|
| 69 |
+
1. `webapp` is the frontend project of `SceneX`, knowledge requirements:
|
| 70 |
+
- Vue 3
|
| 71 |
+
- Quasar
|
| 72 |
+
- ...
|
| 73 |
+
|
| 74 |
+
2. `backend` contains source code of backend logic, knowledge requirements:
|
| 75 |
+
- Nodejs
|
| 76 |
+
- Firebase
|
| 77 |
+
- ...
|
| 78 |
+
|
| 79 |
+
3. `scripts` folder includes custom scripts we might need during the development or for production, currently we have the following scripts:
|
| 80 |
+
- `translate` is responsible for translating and updating our i18n language files in frontend project.
|
| 81 |
+
|
| 82 |
+
### Best practices of frontend
|
| 83 |
+
1. **Quasar docs** is your `best friend`. Since the frontend project highly depends on framework `Quasar`. It is recommended to use the predefined classes and components and avoid defining your custom classes
|
| 84 |
+
2. **Double check** of the UI output in `Dark mode` and `Light mode`. Again, use predefined classes and props.
|
| 85 |
+
3. **Plugins in boot** folder: create corresponding file in `boot` folder and use them in `quasar.config.js`:
|
| 86 |
+
```js
|
| 87 |
+
module.exports = configure(function() {
|
| 88 |
+
return {
|
| 89 |
+
...
|
| 90 |
+
boot: [
|
| 91 |
+
'i18n',
|
| 92 |
+
'axios',
|
| 93 |
+
'firebase',
|
| 94 |
+
'addressbar-color',
|
| 95 |
+
'quasar-lang-pack'
|
| 96 |
+
],
|
| 97 |
+
...
|
| 98 |
+
}
|
| 99 |
+
})
|
| 100 |
+
|
| 101 |
+
```
|
| 102 |
+
|
| 103 |
+
### Best practices of backend
|
| 104 |
+
1. **Remember to deploy your functions** by running:
|
| 105 |
+
```bash
|
| 106 |
+
# deploy all functions
|
| 107 |
+
firebase deploy --only functions
|
| 108 |
+
|
| 109 |
+
# deploy a specific function
|
| 110 |
+
firebase deploy --only functions:{function name}
|
| 111 |
+
|
| 112 |
+
```
|
backend/.firebaserc
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"projects": {
|
| 3 |
+
"default": "reader-6b7dc"
|
| 4 |
+
}
|
| 5 |
+
}
|
backend/.gitignore
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Logs
|
| 2 |
+
logs
|
| 3 |
+
*.log
|
| 4 |
+
npm-debug.log*
|
| 5 |
+
yarn-debug.log*
|
| 6 |
+
yarn-error.log*
|
| 7 |
+
firebase-debug.log*
|
| 8 |
+
firebase-debug.*.log*
|
| 9 |
+
|
| 10 |
+
# Firebase cache
|
| 11 |
+
.firebase/
|
| 12 |
+
|
| 13 |
+
# Firebase config
|
| 14 |
+
|
| 15 |
+
# Uncomment this if you'd like others to create their own Firebase project.
|
| 16 |
+
# For a team working on the same Firebase project(s), it is recommended to leave
|
| 17 |
+
# it commented so all members can deploy to the same project(s) in .firebaserc.
|
| 18 |
+
# .firebaserc
|
| 19 |
+
|
| 20 |
+
# Runtime data
|
| 21 |
+
pids
|
| 22 |
+
*.pid
|
| 23 |
+
*.seed
|
| 24 |
+
*.pid.lock
|
| 25 |
+
|
| 26 |
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
| 27 |
+
lib-cov
|
| 28 |
+
|
| 29 |
+
# Coverage directory used by tools like istanbul
|
| 30 |
+
coverage
|
| 31 |
+
|
| 32 |
+
# nyc test coverage
|
| 33 |
+
.nyc_output
|
| 34 |
+
|
| 35 |
+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
| 36 |
+
.grunt
|
| 37 |
+
|
| 38 |
+
# Bower dependency directory (https://bower.io/)
|
| 39 |
+
bower_components
|
| 40 |
+
|
| 41 |
+
# node-waf configuration
|
| 42 |
+
.lock-wscript
|
| 43 |
+
|
| 44 |
+
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
| 45 |
+
build/Release
|
| 46 |
+
|
| 47 |
+
# Dependency directories
|
| 48 |
+
node_modules/
|
| 49 |
+
|
| 50 |
+
# Optional npm cache directory
|
| 51 |
+
.npm
|
| 52 |
+
|
| 53 |
+
# Optional eslint cache
|
| 54 |
+
.eslintcache
|
| 55 |
+
|
| 56 |
+
# Optional REPL history
|
| 57 |
+
.node_repl_history
|
| 58 |
+
|
| 59 |
+
# Output of 'npm pack'
|
| 60 |
+
*.tgz
|
| 61 |
+
|
| 62 |
+
# Yarn Integrity file
|
| 63 |
+
.yarn-integrity
|
| 64 |
+
|
| 65 |
+
# dotenv environment variables file
|
| 66 |
+
.env
|
| 67 |
+
.secret.local
|
| 68 |
+
|
| 69 |
+
toy*.ts
|
| 70 |
+
|
| 71 |
+
.DS_Store
|
| 72 |
+
build/
|
| 73 |
+
.firebase-emu/
|
| 74 |
+
*.log
|
| 75 |
+
.DS_Store
|
backend/firebase.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"firestore": {
|
| 3 |
+
"rules": "firestore.rules",
|
| 4 |
+
"indexes": "firestore.indexes.json"
|
| 5 |
+
},
|
| 6 |
+
"functions": [
|
| 7 |
+
{
|
| 8 |
+
"source": "functions",
|
| 9 |
+
"codebase": "default",
|
| 10 |
+
"ignore": [
|
| 11 |
+
"node_modules",
|
| 12 |
+
"src",
|
| 13 |
+
".git",
|
| 14 |
+
"firebase-debug.log",
|
| 15 |
+
"firebase-debug.*.log"
|
| 16 |
+
],
|
| 17 |
+
"predeploy": [
|
| 18 |
+
"npm --prefix \"$RESOURCE_DIR\" run build:clean",
|
| 19 |
+
"npm --prefix \"$RESOURCE_DIR\" run build"
|
| 20 |
+
]
|
| 21 |
+
}
|
| 22 |
+
],
|
| 23 |
+
"storage": {
|
| 24 |
+
"rules": "storage.rules"
|
| 25 |
+
},
|
| 26 |
+
"emulators": {
|
| 27 |
+
"ui": {
|
| 28 |
+
"enabled": true
|
| 29 |
+
},
|
| 30 |
+
"singleProjectMode": true,
|
| 31 |
+
"functions": {
|
| 32 |
+
"port": 5001
|
| 33 |
+
},
|
| 34 |
+
"auth": {
|
| 35 |
+
"port": 9099
|
| 36 |
+
},
|
| 37 |
+
"firestore": {
|
| 38 |
+
"port": 9098
|
| 39 |
+
},
|
| 40 |
+
"storage": {
|
| 41 |
+
"port": 9097
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
}
|
backend/firestore.indexes.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"indexes": [
|
| 3 |
+
{
|
| 4 |
+
"collectionGroup": "prompts",
|
| 5 |
+
"queryScope": "COLLECTION_GROUP",
|
| 6 |
+
"fields": [
|
| 7 |
+
{
|
| 8 |
+
"fieldPath": "id",
|
| 9 |
+
"order": "ASCENDING"
|
| 10 |
+
},
|
| 11 |
+
{
|
| 12 |
+
"fieldPath": "isPublic",
|
| 13 |
+
"order": "ASCENDING"
|
| 14 |
+
}
|
| 15 |
+
]
|
| 16 |
+
}
|
| 17 |
+
],
|
| 18 |
+
"fieldOverrides": []
|
| 19 |
+
}
|
backend/firestore.rules
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
rules_version = '2';
|
| 2 |
+
service cloud.firestore {
|
| 3 |
+
match /databases/{database}/documents {
|
| 4 |
+
// match /questions/{document=**} {
|
| 5 |
+
// allow read: if request.auth != null
|
| 6 |
+
// }
|
| 7 |
+
|
| 8 |
+
// match /answers/{userId}/profiles/default {
|
| 9 |
+
// allow read, write: if request.auth != null && request.auth.uid == userId
|
| 10 |
+
// }
|
| 11 |
+
|
| 12 |
+
match /credits/{userId}/{document=**} {
|
| 13 |
+
allow read: if request.auth != null && request.auth.uid == userId
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
match /users/{userId}/prompts/{document=**} {
|
| 17 |
+
allow read: if request.auth != null && request.auth.uid == userId
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
// match /users/{userId}/profiles/{document=**} {
|
| 21 |
+
// allow read: if request.auth != null && request.auth.uid == userId
|
| 22 |
+
// }
|
| 23 |
+
|
| 24 |
+
match /users/{userId}/creditHistory/{document=**} {
|
| 25 |
+
allow read: if request.auth != null && request.auth.uid == userId
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
match /{document=**} {
|
| 29 |
+
allow read, write: if false;
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
}
|
backend/functions/.editorconfig
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
root = true
|
| 2 |
+
|
| 3 |
+
[*]
|
| 4 |
+
end_of_line = lf
|
| 5 |
+
charset = utf-8
|
| 6 |
+
indent_style = space
|
| 7 |
+
insert_final_newline = true
|
| 8 |
+
trim_trailing_whitespace = true
|
| 9 |
+
indent_size = 4
|
| 10 |
+
quote_type = single
|
| 11 |
+
max_line_length = 120
|
| 12 |
+
|
| 13 |
+
[*.py]
|
| 14 |
+
indent_size = 4
|
| 15 |
+
|
| 16 |
+
[*.ts]
|
| 17 |
+
indent_size = 4
|
| 18 |
+
|
| 19 |
+
[*.js]
|
| 20 |
+
indent_size = 2
|
| 21 |
+
|
| 22 |
+
[*.vue]
|
| 23 |
+
indent_size = 2
|
| 24 |
+
|
| 25 |
+
[*.*sx]
|
| 26 |
+
indent_size = 2
|
| 27 |
+
|
| 28 |
+
[*.*ml]
|
| 29 |
+
indent_size = 2
|
| 30 |
+
|
| 31 |
+
[*.json]
|
| 32 |
+
indent_size = 2
|
| 33 |
+
|
| 34 |
+
[*.md]
|
| 35 |
+
indent_size = 2
|
| 36 |
+
trim_trailing_whitespace = false
|
backend/functions/.env.example
ADDED
|
File without changes
|
backend/functions/.vscode/launch.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
// 使用 IntelliSense 了解相关属性。
|
| 3 |
+
// 悬停以查看现有属性的描述。
|
| 4 |
+
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
| 5 |
+
"version": "0.2.0",
|
| 6 |
+
"configurations": [
|
| 7 |
+
{
|
| 8 |
+
"name": "Attach by Process ID",
|
| 9 |
+
"processId": "${command:PickProcess}",
|
| 10 |
+
"request": "attach",
|
| 11 |
+
"skipFiles": [
|
| 12 |
+
"<node_internals>/**"
|
| 13 |
+
],
|
| 14 |
+
"type": "node"
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"name": "Attach",
|
| 18 |
+
"port": 9229,
|
| 19 |
+
"request": "attach",
|
| 20 |
+
"skipFiles": [
|
| 21 |
+
"<node_internals>/**"
|
| 22 |
+
],
|
| 23 |
+
"type": "node"
|
| 24 |
+
}
|
| 25 |
+
]
|
| 26 |
+
}
|
| 27 |
+
|
backend/functions/.vscode/settings.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cSpell.words": [
|
| 3 |
+
"AIHTTP",
|
| 4 |
+
"Castable",
|
| 5 |
+
"civkit",
|
| 6 |
+
"Firestore",
|
| 7 |
+
"openai"
|
| 8 |
+
],
|
| 9 |
+
"typescript.tsdk": "node_modules/typescript/lib"
|
| 10 |
+
}
|
backend/functions/firebase-export-1712748362961bSfwZx/firestore_export/firestore_export.overall_export_metadata
ADDED
|
Binary file (15 Bytes). View file
|
|
|
backend/functions/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "url2text",
|
| 3 |
+
"scripts": {
|
| 4 |
+
"lint": "eslint --ext .js,.ts .",
|
| 5 |
+
"build": "tsc -p .",
|
| 6 |
+
"build:watch": "tsc --watch",
|
| 7 |
+
"build:clean": "rm -rf ./build",
|
| 8 |
+
"shell": "npm run build && firebase functions:shell",
|
| 9 |
+
"emu:stage": "cd .. && tar -czvf firebase-emu-preset.tgz .firebase-emu",
|
| 10 |
+
"emu:reset": "rm -rf ../.firebase-emu && tar -xzf ../firebase-emu-preset.tgz --directory ../",
|
| 11 |
+
"emu:start": "firebase emulators:start --import ../.firebase-emu --export-on-exit",
|
| 12 |
+
"emu:debug": "firebase emulators:start --import ../.firebase-emu --export-on-exit --inspect-functions",
|
| 13 |
+
"emu:debug2": "firebase emulators:start --import ../.firebase-emu --export-on-exit --inspect-functions",
|
| 14 |
+
"emu:kill": "killall java",
|
| 15 |
+
"serve": "npm run build && npm run emu:start",
|
| 16 |
+
"debug": "npm run build && npm run emu:start -- --inspect-functions",
|
| 17 |
+
"from-scratch": "npm run build && rm -rf ../.firebase-emu && firebase emulators:start --export-on-exit",
|
| 18 |
+
"from-preset": "npm run build && npm run emu:reset && npm run emu:start",
|
| 19 |
+
"start": "npm run shell",
|
| 20 |
+
"deploy": "firebase deploy --only functions",
|
| 21 |
+
"logs": "firebase functions:log"
|
| 22 |
+
},
|
| 23 |
+
"engines": {
|
| 24 |
+
"node": "20"
|
| 25 |
+
},
|
| 26 |
+
"main": "build/index.js",
|
| 27 |
+
"dependencies": {
|
| 28 |
+
"@google-cloud/translate": "^8.2.0",
|
| 29 |
+
"@mozilla/readability": "^0.5.0",
|
| 30 |
+
"@napi-rs/canvas": "^0.1.44",
|
| 31 |
+
"@types/turndown": "^5.0.4",
|
| 32 |
+
"archiver": "^6.0.1",
|
| 33 |
+
"axios": "^1.3.3",
|
| 34 |
+
"bcrypt": "^5.1.0",
|
| 35 |
+
"civkit": "^0.6.5-be430ac",
|
| 36 |
+
"cors": "^2.8.5",
|
| 37 |
+
"dayjs": "^1.11.9",
|
| 38 |
+
"express": "^4.19.2",
|
| 39 |
+
"firebase-admin": "^11.5.0",
|
| 40 |
+
"firebase-functions": "^4.8.0",
|
| 41 |
+
"generic-pool": "^3.9.0",
|
| 42 |
+
"htmlparser2": "^9.0.0",
|
| 43 |
+
"jose": "^5.1.0",
|
| 44 |
+
"langdetect": "^0.2.1",
|
| 45 |
+
"minio": "^7.1.3",
|
| 46 |
+
"openai": "^4.20.0",
|
| 47 |
+
"puppeteer": "^22.6.3",
|
| 48 |
+
"stripe": "^11.11.0",
|
| 49 |
+
"tiktoken": "^1.0.10",
|
| 50 |
+
"turndown": "^7.1.3",
|
| 51 |
+
"undici": "^5.24.0"
|
| 52 |
+
},
|
| 53 |
+
"devDependencies": {
|
| 54 |
+
"@types/archiver": "^5.3.4",
|
| 55 |
+
"@types/bcrypt": "^5.0.0",
|
| 56 |
+
"@types/cors": "^2.8.17",
|
| 57 |
+
"@types/generic-pool": "^3.8.1",
|
| 58 |
+
"@types/node": "^18",
|
| 59 |
+
"@typescript-eslint/eslint-plugin": "^5.12.0",
|
| 60 |
+
"@typescript-eslint/parser": "^5.12.0",
|
| 61 |
+
"eslint": "^8.9.0",
|
| 62 |
+
"eslint-config-google": "^0.14.0",
|
| 63 |
+
"eslint-plugin-import": "^2.25.4",
|
| 64 |
+
"firebase-functions-test": "^3.0.0",
|
| 65 |
+
"replicate": "^0.16.1",
|
| 66 |
+
"typescript": "^5.1.6"
|
| 67 |
+
},
|
| 68 |
+
"private": true,
|
| 69 |
+
"exports": {
|
| 70 |
+
".": "./build/index.js"
|
| 71 |
+
}
|
| 72 |
+
}
|
backend/functions/src/cloud-functions/crawler.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { marshalErrorLike, RPCHost, RPCReflection } from 'civkit';
|
| 2 |
+
import { singleton } from 'tsyringe';
|
| 3 |
+
import { CloudHTTPv2, Logger, OutputServerEventStream, Param, RPCReflect } from '../shared';
|
| 4 |
+
import _ from 'lodash';
|
| 5 |
+
import { PuppeteerControl } from '../services/puppeteer';
|
| 6 |
+
import TurnDownService from 'turndown';
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
@singleton()
|
| 10 |
+
export class CrawlerHost extends RPCHost {
|
| 11 |
+
logger = this.globalLogger.child({ service: this.constructor.name });
|
| 12 |
+
|
| 13 |
+
turnDownService = new TurnDownService();
|
| 14 |
+
|
| 15 |
+
constructor(
|
| 16 |
+
protected globalLogger: Logger,
|
| 17 |
+
protected puppeteerControl: PuppeteerControl,
|
| 18 |
+
) {
|
| 19 |
+
super(...arguments);
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
override async init() {
|
| 23 |
+
await this.dependencyReady();
|
| 24 |
+
|
| 25 |
+
this.emit('ready');
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
@CloudHTTPv2({
|
| 29 |
+
exportInGroup: ['crawler'],
|
| 30 |
+
httpMethod: ['get', 'post'],
|
| 31 |
+
returnType: OutputServerEventStream,
|
| 32 |
+
})
|
| 33 |
+
async crawl(
|
| 34 |
+
@RPCReflect() rpcReflect: RPCReflection,
|
| 35 |
+
@Param('url', { required: true }) url: string
|
| 36 |
+
) {
|
| 37 |
+
await this.serviceReady();
|
| 38 |
+
const sseStream = new OutputServerEventStream();
|
| 39 |
+
|
| 40 |
+
rpcReflect.return(sseStream);
|
| 41 |
+
|
| 42 |
+
try {
|
| 43 |
+
for await (const scrapped of this.puppeteerControl.scrap(url)) {
|
| 44 |
+
this.logger.info(`Scrapped: ${scrapped.snapshot}`);
|
| 45 |
+
const content = typeof scrapped.snapshot === 'string' ? scrapped.snapshot : (scrapped.snapshot as any)?.content;
|
| 46 |
+
if (!content) {
|
| 47 |
+
continue;
|
| 48 |
+
}
|
| 49 |
+
const text = this.turnDownService.turndown(typeof scrapped.snapshot === 'string' ? scrapped.snapshot : (scrapped.snapshot as any)?.content);
|
| 50 |
+
sseStream.write({
|
| 51 |
+
event: 'data',
|
| 52 |
+
data: text,
|
| 53 |
+
});
|
| 54 |
+
}
|
| 55 |
+
} catch (err: any) {
|
| 56 |
+
this.logger.error(`Failed to crawl ${url}`, { err: marshalErrorLike(err) });
|
| 57 |
+
sseStream.write({
|
| 58 |
+
event: 'error',
|
| 59 |
+
data: err,
|
| 60 |
+
});
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
sseStream.end();
|
| 64 |
+
|
| 65 |
+
return sseStream;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
}
|
backend/functions/src/fetch.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare global {
|
| 2 |
+
export const {
|
| 3 |
+
fetch,
|
| 4 |
+
FormData,
|
| 5 |
+
Headers,
|
| 6 |
+
Request,
|
| 7 |
+
Response,
|
| 8 |
+
File,
|
| 9 |
+
}: typeof import('undici');
|
| 10 |
+
export type { FormData, Headers, Request, RequestInit, Response, RequestInit, File } from 'undici';
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export { };
|
backend/functions/src/index.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import 'reflect-metadata';
|
| 2 |
+
import * as functions from 'firebase-functions';
|
| 3 |
+
import { initializeApp } from 'firebase-admin/app';
|
| 4 |
+
initializeApp();
|
| 5 |
+
|
| 6 |
+
import secretExposer from './shared/services/secrets';
|
| 7 |
+
|
| 8 |
+
export const onUserCreated = functions
|
| 9 |
+
.runWith({ secrets: [...secretExposer.bundle], memory: '512MB' })
|
| 10 |
+
.auth.user()
|
| 11 |
+
.onCreate(async (user) => {
|
| 12 |
+
|
| 13 |
+
return null;
|
| 14 |
+
});
|
| 15 |
+
|
| 16 |
+
export const onUserLogin = functions
|
| 17 |
+
.runWith({ secrets: [...secretExposer.bundle], memory: '512MB' })
|
| 18 |
+
.auth.user()
|
| 19 |
+
.beforeSignIn(async (user, _ctx) => {
|
| 20 |
+
|
| 21 |
+
return;
|
| 22 |
+
});
|
| 23 |
+
|
| 24 |
+
import { loadModulesDynamically, registry } from './shared';
|
| 25 |
+
import path from 'path';
|
| 26 |
+
loadModulesDynamically(path.resolve(__dirname, 'cloud-functions'));
|
| 27 |
+
|
| 28 |
+
Object.assign(exports, registry.exportGrouped({
|
| 29 |
+
memory: '1GiB',
|
| 30 |
+
timeoutSeconds: 540,
|
| 31 |
+
}));
|
| 32 |
+
registry.title = 'url2text';
|
| 33 |
+
registry.version = '0.1.0';
|
backend/functions/src/services/puppeteer.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { AsyncService, Defer } from 'civkit';
|
| 2 |
+
import { container, singleton } from 'tsyringe';
|
| 3 |
+
import puppeteer, { Browser } from 'puppeteer';
|
| 4 |
+
import { Logger } from '../shared/services/logger';
|
| 5 |
+
import genericPool from 'generic-pool';
|
| 6 |
+
import os from 'os';
|
| 7 |
+
import fs from 'fs';
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
const READABILITY_JS = fs.readFileSync(require.resolve('@mozilla/readability/Readability.js'), 'utf-8');
|
| 11 |
+
|
| 12 |
+
@singleton()
|
| 13 |
+
export class PuppeteerControl extends AsyncService {
|
| 14 |
+
|
| 15 |
+
browser!: Browser;
|
| 16 |
+
logger = this.globalLogger.child({ service: this.constructor.name });
|
| 17 |
+
|
| 18 |
+
pagePool = genericPool.createPool({
|
| 19 |
+
create: async () => {
|
| 20 |
+
const page = await this.newPage();
|
| 21 |
+
return page;
|
| 22 |
+
},
|
| 23 |
+
destroy: async (page) => {
|
| 24 |
+
await page.browserContext().close();
|
| 25 |
+
},
|
| 26 |
+
validate: async (page) => {
|
| 27 |
+
return this.browser.connected && !page.isClosed();
|
| 28 |
+
}
|
| 29 |
+
}, {
|
| 30 |
+
max: Math.ceil(os.freemem() / 1024 * 1024 * 1024),
|
| 31 |
+
min: 0,
|
| 32 |
+
});
|
| 33 |
+
|
| 34 |
+
constructor(protected globalLogger: Logger) {
|
| 35 |
+
super(...arguments);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
override async init() {
|
| 39 |
+
await this.dependencyReady();
|
| 40 |
+
|
| 41 |
+
if (this.browser) {
|
| 42 |
+
await this.browser.close();
|
| 43 |
+
}
|
| 44 |
+
this.browser = await puppeteer.launch({
|
| 45 |
+
headless: false,
|
| 46 |
+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
| 47 |
+
});
|
| 48 |
+
this.browser.once('disconnected', () => {
|
| 49 |
+
this.logger.warn(`Browser disconnected`);
|
| 50 |
+
this.emit('crippled');
|
| 51 |
+
});
|
| 52 |
+
|
| 53 |
+
this.emit('ready');
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
async newPage() {
|
| 57 |
+
await this.serviceReady();
|
| 58 |
+
const dedicatedContext = await this.browser.createBrowserContext();
|
| 59 |
+
|
| 60 |
+
const page = await dedicatedContext.newPage();
|
| 61 |
+
await page.setUserAgent(`Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)`);
|
| 62 |
+
await page.setViewport({ width: 1920, height: 1080 });
|
| 63 |
+
await page.exposeFunction('reportSnapshot', (snapshot: any) => {
|
| 64 |
+
page.emit('snapshot', snapshot);
|
| 65 |
+
});
|
| 66 |
+
|
| 67 |
+
await page.evaluateOnNewDocument(READABILITY_JS);
|
| 68 |
+
|
| 69 |
+
await page.evaluateOnNewDocument(() => {
|
| 70 |
+
// @ts-expect-error
|
| 71 |
+
window.giveSnapshot() = () => {
|
| 72 |
+
// @ts-expect-error
|
| 73 |
+
return new Readability(document.cloneNode(true)).parse();
|
| 74 |
+
};
|
| 75 |
+
let aftershot: any;
|
| 76 |
+
const handlePageLoad = () => {
|
| 77 |
+
// @ts-expect-error
|
| 78 |
+
if (document.readyState !== 'complete' && document.readyState !== 'interactive') {
|
| 79 |
+
return;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// @ts-expect-error
|
| 83 |
+
const parsed = window.giveSnapshot();
|
| 84 |
+
console.log(parsed);
|
| 85 |
+
if (parsed) {
|
| 86 |
+
// @ts-expect-error
|
| 87 |
+
window.reportSnapshot(parsed);
|
| 88 |
+
} else {
|
| 89 |
+
if (aftershot) {
|
| 90 |
+
clearTimeout(aftershot);
|
| 91 |
+
}
|
| 92 |
+
aftershot = setTimeout(() => {
|
| 93 |
+
// @ts-expect-error
|
| 94 |
+
window.reportSnapshot(window.giveSnapshot());
|
| 95 |
+
}, 500);
|
| 96 |
+
}
|
| 97 |
+
};
|
| 98 |
+
// setInterval(handlePageLoad, 1000);
|
| 99 |
+
// @ts-expect-error
|
| 100 |
+
document.addEventListener('readystatechange', handlePageLoad);
|
| 101 |
+
// @ts-expect-error
|
| 102 |
+
document.addEventListener('load', handlePageLoad);
|
| 103 |
+
});
|
| 104 |
+
|
| 105 |
+
// TODO: further setup the page;
|
| 106 |
+
|
| 107 |
+
return page;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
async *scrap(url: string) {
|
| 111 |
+
const page = await this.pagePool.acquire();
|
| 112 |
+
let snapshot: unknown;
|
| 113 |
+
let nextSnapshotDeferred = Defer();
|
| 114 |
+
let finalized = false;
|
| 115 |
+
const hdl = (s: any) => {
|
| 116 |
+
if (snapshot === s) {
|
| 117 |
+
return;
|
| 118 |
+
}
|
| 119 |
+
snapshot = s;
|
| 120 |
+
nextSnapshotDeferred.resolve(s);
|
| 121 |
+
nextSnapshotDeferred = Defer();
|
| 122 |
+
};
|
| 123 |
+
page.on('snapshot', hdl);
|
| 124 |
+
const gotoPromise = page.goto(url, { waitUntil: 'networkidle2', timeout: 30_000 });
|
| 125 |
+
gotoPromise.finally(() => finalized = true);
|
| 126 |
+
|
| 127 |
+
try {
|
| 128 |
+
while (true) {
|
| 129 |
+
await Promise.race([nextSnapshotDeferred.promise, gotoPromise]);
|
| 130 |
+
const screenshot = await page.screenshot();
|
| 131 |
+
if (finalized) {
|
| 132 |
+
await gotoPromise;
|
| 133 |
+
snapshot = await page.evaluate('window.giveSnapshot()');
|
| 134 |
+
yield { snapshot, screenshot };
|
| 135 |
+
break;
|
| 136 |
+
}
|
| 137 |
+
yield { snapshot, screenshot };
|
| 138 |
+
}
|
| 139 |
+
} catch (_err) {
|
| 140 |
+
void 0;
|
| 141 |
+
} finally {
|
| 142 |
+
page.off('snapshot', hdl);
|
| 143 |
+
await this.pagePool.destroy(page);
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
const puppeteerControl = container.resolve(PuppeteerControl);
|
| 151 |
+
|
| 152 |
+
export default puppeteerControl;
|
backend/functions/src/shared
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
../../../thinapps-shared/backend
|
backend/functions/src/types.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
declare module 'langdetect' {
|
| 2 |
+
interface DetectionResult {
|
| 3 |
+
lang: string;
|
| 4 |
+
prob: number;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
export function detect(text: string): DetectionResult[];
|
| 8 |
+
export function detectOne(text: string): string | null;
|
| 9 |
+
}
|
backend/functions/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"module": "commonjs",
|
| 4 |
+
"noImplicitReturns": true,
|
| 5 |
+
"noUnusedLocals": true,
|
| 6 |
+
"outDir": "build",
|
| 7 |
+
"sourceMap": true,
|
| 8 |
+
"strict": true,
|
| 9 |
+
"allowJs": true,
|
| 10 |
+
"target": "es2022",
|
| 11 |
+
"lib": ["es2022"],
|
| 12 |
+
"skipLibCheck": true,
|
| 13 |
+
"useDefineForClassFields": false,
|
| 14 |
+
"experimentalDecorators": true,
|
| 15 |
+
"emitDecoratorMetadata": true,
|
| 16 |
+
"esModuleInterop": true,
|
| 17 |
+
"noImplicitOverride": true,
|
| 18 |
+
},
|
| 19 |
+
"compileOnSave": true,
|
| 20 |
+
"include": ["src"]
|
| 21 |
+
}
|
backend/storage.rules
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
rules_version = '2';
|
| 2 |
+
service firebase.storage {
|
| 3 |
+
match /b/{bucket}/o {
|
| 4 |
+
match /{allPaths=**} {
|
| 5 |
+
allow read, write: if false;
|
| 6 |
+
}
|
| 7 |
+
}
|
| 8 |
+
}
|
package.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "url2text",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"description": "### Prerequisite - Node v18 (The build fails for Node version >18) - Yarn - Firebase CLI (`npm install -g firebase-tools`)",
|
| 5 |
+
"main": "index.js",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"test": "echo \"Error: no test specified\" && exit 1"
|
| 8 |
+
},
|
| 9 |
+
"author": "",
|
| 10 |
+
"license": "ISC",
|
| 11 |
+
"devDependencies": {
|
| 12 |
+
"firebase-tools": "^12.4.2",
|
| 13 |
+
"typescript": "^5.1.6"
|
| 14 |
+
}
|
| 15 |
+
}
|
thinapps-shared
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
Subproject commit 9f0fa1dd7f8cfcea4c8d79252319b151fae6ed19
|