Compare commits

...

15 Commits

Author SHA1 Message Date
iamBadgers
b5f0e8afbb minor ui tweaks 2025-07-13 11:14:33 -07:00
iamBadgers
b21e763d65 Initial pass on character lists. 2025-07-06 00:11:25 -07:00
iamBadgers
8745fc3c7e Add in some ui work for listing available characters. 2025-07-05 00:10:59 -07:00
iamBadgers
0707250864 Only idiots throw null... 2025-07-04 00:02:06 -07:00
iamBadgers
25cb93fba0 Progress with some fancy webrpc stuff through traefik 2025-06-20 01:41:15 -07:00
iamBadgers
d480267c64 random-ass changes 2025-06-19 23:34:08 -07:00
iamBadgers
a62fe1aba9 work on the list call 2025-06-16 00:21:03 -07:00
iamBadgers
1f43ff468b move flags to its own module. 2025-06-15 22:09:18 -07:00
iamBadgers
aa4c44840b move flags to its own module. 2025-06-14 17:12:49 -07:00
iamBadgers
882e8cf72a add commander for cli flags 2025-06-14 16:16:40 -07:00
iamBadgers
28a991c7d4 move over to database service cause I forgot I made that 2025-06-14 00:48:33 -07:00
iamBadgers
7230d526e0 Get it to store data from grpc calls. 2025-06-13 21:17:35 -07:00
iamBadgers
1bcaedc293 get mongo running 2025-06-13 00:01:55 -07:00
iamBadgers
39a3783ebd add reflection service to valut 2025-06-12 19:28:42 -07:00
iamBadgers
a4be179faf Finally up and running again. 2025-06-12 00:10:12 -07:00
34 changed files with 2361 additions and 694 deletions

View File

@@ -1,5 +1,5 @@
dist dist
rush-character-archive/node_modules frontend/node_modules
vault/node_modules vault/node_modules
vault/src/proto vault/src/proto
rush-character-archive/src/proto frontend/src/proto

128
build.log Normal file
View File

@@ -0,0 +1,128 @@
#0 building with "desktop-linux" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 322B done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/node:22.16
#2 DONE 0.3s
#3 [internal] load .dockerignore
#3 transferring context: 120B done
#3 DONE 0.0s
#4 [ 1/10] FROM docker.io/library/node:22.16@sha256:71bcbb3b215b3fa84b5b167585675072f4c270855e37a599803f1a58141a0716
#4 resolve docker.io/library/node:22.16@sha256:71bcbb3b215b3fa84b5b167585675072f4c270855e37a599803f1a58141a0716 0.0s done
#4 DONE 0.0s
#5 [ 2/10] WORKDIR /srv/proto
#5 CACHED
#6 [internal] load build context
#6 transferring context: 285.61kB 0.1s done
#6 DONE 0.1s
#7 [ 3/10] COPY proto/ .
#7 DONE 0.8s
#8 [ 4/10] WORKDIR /srv/frontend
#8 DONE 0.1s
#9 [ 5/10] COPY frontend/package.json .
#9 DONE 0.1s
#10 [ 6/10] RUN npm install
#10 10.52
#10 10.52 added 328 packages, and audited 329 packages in 10s
#10 10.52
#10 10.52 90 packages are looking for funding
#10 10.52 run `npm fund` for details
#10 10.52
#10 10.52 found 0 vulnerabilities
#10 10.52 npm notice
#10 10.52 npm notice New major version of npm available! 10.9.2 -> 11.4.1
#10 10.52 npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.4.1
#10 10.52 npm notice To update run: npm install -g npm@11.4.1
#10 10.52 npm notice
#10 DONE 11.1s
#11 [ 7/10] COPY frontend/. .
#11 DONE 0.2s
#12 [ 8/10] RUN npm i -g serve
#12 2.048
#12 2.048 added 88 packages in 2s
#12 2.048
#12 2.048 24 packages are looking for funding
#12 2.048 run `npm fund` for details
#12 DONE 2.1s
#13 [ 9/10] RUN npm run build_protos
#13 0.279
#13 0.279 > frontend@0.0.0 build_protos
#13 0.279 > mkdir -p src/proto & npx protoc -I=../proto/ --ts_out=server_grpc1:./src/proto --proto_path ../proto ../proto/*.proto
#13 0.279
#13 1.394 @protobuf-ts/protoc installed protoc v31.1.
#13 DONE 1.8s
#14 [10/10] RUN npm run build
#14 0.235
#14 0.235 > frontend@0.0.0 build
#14 0.235 > run-p type-check "build-only {@}" --
#14 0.235
#14 0.323
#14 0.323 > frontend@0.0.0 build-only
#14 0.323 > vite build
#14 0.323
#14 0.325
#14 0.325 > frontend@0.0.0 type-check
#14 0.325 > vue-tsc --build
#14 0.325
#14 0.752 vite v6.3.5 building for production...
#14 0.805 transforming...
#14 1.191 ✓ 69 modules transformed.
#14 1.297 rendering chunks...
#14 1.301 computing gzip size...
#14 1.307 dist/index.html 0.43 kB │ gzip: 0.28 kB
#14 1.307 dist/assets/index-TXLObeWa.css 3.71 kB │ gzip: 1.19 kB
#14 1.307 dist/assets/index-0ixp9Wqt.js 105.33 kB │ gzip: 37.78 kB
#14 1.307 ✓ built in 530ms
#14 1.467 src/proto/character.grpc-server.ts(7,28): error TS2307: Cannot find module '@grpc/grpc-js' or its corresponding type declarations.
#14 1.467 src/proto/character.grpc-server.ts(38,30): error TS7006: Parameter 'bytes' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(39,29): error TS7006: Parameter 'bytes' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(40,28): error TS7006: Parameter 'value' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(40,37): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
#14 1.467 src/proto/character.grpc-server.ts(41,27): error TS7006: Parameter 'value' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(41,36): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
#14 1.467 src/proto/character.grpc-server.ts(48,30): error TS7006: Parameter 'bytes' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(49,29): error TS7006: Parameter 'bytes' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(50,28): error TS7006: Parameter 'value' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(50,37): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
#14 1.467 src/proto/character.grpc-server.ts(51,27): error TS7006: Parameter 'value' implicitly has an 'any' type.
#14 1.467 src/proto/character.grpc-server.ts(51,36): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
#14 1.485 ERROR: "type-check" exited with 2.
#14 ERROR: process "/bin/sh -c npm run build" did not complete successfully: exit code: 1
------
> [10/10] RUN npm run build:
1.467 src/proto/character.grpc-server.ts(40,37): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
1.467 src/proto/character.grpc-server.ts(41,27): error TS7006: Parameter 'value' implicitly has an 'any' type.
1.467 src/proto/character.grpc-server.ts(41,36): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
1.467 src/proto/character.grpc-server.ts(48,30): error TS7006: Parameter 'bytes' implicitly has an 'any' type.
1.467 src/proto/character.grpc-server.ts(49,29): error TS7006: Parameter 'bytes' implicitly has an 'any' type.
1.467 src/proto/character.grpc-server.ts(50,28): error TS7006: Parameter 'value' implicitly has an 'any' type.
1.467 src/proto/character.grpc-server.ts(50,37): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
1.467 src/proto/character.grpc-server.ts(51,27): error TS7006: Parameter 'value' implicitly has an 'any' type.
1.467 src/proto/character.grpc-server.ts(51,36): error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
1.485 ERROR: "type-check" exited with 2.
------
Dockerfile:20
--------------------
18 |
19 | RUN npm run build_protos
20 | >>> RUN npm run build
21 |
22 | EXPOSE 8080
--------------------
ERROR: failed to solve: process "/bin/sh -c npm run build" did not complete successfully: exit code: 1
View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/k2rob0qo9fs8fmawdf7vwutz8

View File

@@ -1,36 +1,39 @@
networks:
rush-character-net:
services: services:
rush-character-archive:
proxy:
image: traefik
command: --providers.docker
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
frontend:
build: build:
context: ./ context: ./
dockerfile: ./frontend/Dockerfile dockerfile: ./frontend/Dockerfile
command: npm run dev command: npm run dev
networks:
- rush-character-net
ports:
- 8080:3000
develop: develop:
watch: watch:
- action: sync - action: sync
path: ./frontend path: ./frontend
target: /srv/frontende target: /srv/frontend
ignore: ignore:
- node_modules - node_modules
- action: rebuild - action: rebuild
path: ./frontend/package.json path: ./frontend/package.json
- action: rebuild - action: rebuild
path: ./frontend/Dockerfile path: ./frontend/Dockerfile
labels:
traefik.http.routers.client.rule: "Host(`localhost`)"
ports:
- 8080:3000
vault: vault:
build: build:
context: ./ context: ./
dockerfile: ./vault/Dockerfile dockerfile: ./vault/Dockerfile
command: npm run dev command: npm run dev
networks:
- rush-character-net
ports:
- 8081:8080
environment: environment:
MONGO_URI: mongodb://rushvault:rushvault@mongo:27017/ MONGO_URI: mongodb://rushvault:rushvault@mongo:27017/
depends_on: depends_on:
@@ -46,6 +49,14 @@ services:
path: ./vault/package.json path: ./vault/package.json
- action: rebuild - action: rebuild
path: ./vault/Dockerfile path: ./vault/Dockerfile
ports:
- 8081:8080
labels:
traefik.http.routers.api.rule: "Host(`localhost`) && PathPrefix(`/api`)"
traefik.http.services.api.loadbalancer.server.scheme: "h2c"
traefik.http.routers.api.middlewares: "api-stripprefix,api-grpcweb"
traefik.http.middlewares.api-stripprefix.stripprefix.prefixes: "/api"
traefik.http.middlewares.api-grpcweb.grpcWeb.allowOrigins: "*"
mongo: mongo:
image: mongo image: mongo
@@ -54,17 +65,10 @@ services:
MONGO_INITDB_ROOT_USERNAME: rushvault MONGO_INITDB_ROOT_USERNAME: rushvault
MONGO_INITDB_ROOT_PASSWORD: rushvault MONGO_INITDB_ROOT_PASSWORD: rushvault
MONGO_INITDB_DATABASE: DB MONGO_INITDB_DATABASE: DB
networks:
- rush-character-net
ports:
- 27017:27017
mongo-express: mongo-express:
image: mongo-express image: mongo-express
restart: always restart: always
networks:
- rush-character-net
ports:
- 8083:8081
depends_on: depends_on:
- mongo - mongo
environment: environment:
@@ -72,3 +76,7 @@ services:
ME_CONFIG_MONGODB_ADMINPASSWORD: rushvault ME_CONFIG_MONGODB_ADMINPASSWORD: rushvault
ME_CONFIG_MONGODB_URL: mongodb://rushvault:rushvault@mongo:27017/ ME_CONFIG_MONGODB_URL: mongodb://rushvault:rushvault@mongo:27017/
ME_CONFIG_BASICAUTH: false ME_CONFIG_BASICAUTH: false
labels:
traefik.http.routers.mexp.rule: "Host(`mexp.localhost`)"
ports:
- 8082:8081

View File

@@ -2,5 +2,5 @@
"$schema": "https://json.schemastore.org/prettierrc", "$schema": "https://json.schemastore.org/prettierrc",
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,
"printWidth": 100 "printWidth": 80
} }

View File

@@ -2,22 +2,22 @@ FROM node:22.16
WORKDIR /srv/proto WORKDIR /srv/proto
COPY proto . COPY proto/ .
RUN npm install # RUN npm install
RUN npm run build # RUN npm run build
WORKDIR /srv/rush-character-archive WORKDIR /srv/frontend
COPY rush-character-archive/package.json . COPY frontend/package.json .
RUN npm install RUN npm install
RUN npm i -g serve
COPY frontend/. . COPY frontend/. .
RUN npm i -g serve
RUN npm run build RUN npm run build
EXPOSE 8080 EXPOSE 3000
CMD ["serve", "-s", "dist"] CMD ["serve", "-s", "dist"]

View File

@@ -9,14 +9,14 @@ import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup // More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
export default defineConfigWithVueTs( export default defineConfigWithVueTs(
{ // {
name: 'app/files-to-lint', // name: 'app/files-to-lint',
files: ['**/*.{ts,mts,tsx,vue}'], // files: ['**/*.{ts,mts,tsx,vue}'],
}, // },
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']), // globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
pluginVue.configs['flat/essential'], // pluginVue.configs['flat/essential'],
vueTsConfigs.recommended, // vueTsConfigs.recommended,
skipFormatting, // skipFormatting,
) )

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "run-p type-check \"build-only {@}\" --", "build_protos": "mkdir -p src/proto & npx protoc -I=../proto/ --ts_out ./src/proto --proto_path ../proto ../proto/*.proto",
"build": "run-p build_protos && run-p type-check \"build-only {@}\" --",
"preview": "vite preview", "preview": "vite preview",
"build-only": "vite build", "build-only": "vite build",
"type-check": "vue-tsc --build", "type-check": "vue-tsc --build",
@@ -13,13 +14,14 @@
"format": "prettier --write src/" "format": "prettier --write src/"
}, },
"dependencies": { "dependencies": {
"@protobuf-ts/grpcweb-transport": "^2.11.0", "@vueuse/core": "^13.5.0",
"@protobuf-ts/plugin": "^2.11.0", "json-editor-vue": "^0.18.1",
"google-protobuf": "^3.21.4", "vue": "^3.5.13",
"grpc-web": "^1.5.0", "vuetify": "^3.8.12"
"vue": "^3.5.13"
}, },
"devDependencies": { "devDependencies": {
"@protobuf-ts/grpcweb-transport": "^2.11.0",
"@protobuf-ts/plugin": "^2.11.0",
"@tsconfig/node22": "^22.0.1", "@tsconfig/node22": "^22.0.1",
"@types/google-protobuf": "^3.15.12", "@types/google-protobuf": "^3.15.12",
"@types/node": "^22.15.31", "@types/node": "^22.15.31",
@@ -29,6 +31,8 @@
"@vue/tsconfig": "^0.7.0", "@vue/tsconfig": "^0.7.0",
"eslint": "^9.22.0", "eslint": "^9.22.0",
"eslint-plugin-vue": "~10.0.0", "eslint-plugin-vue": "~10.0.0",
"google-protobuf": "^3.21.4",
"grpc-web": "^1.5.0",
"jiti": "^2.4.2", "jiti": "^2.4.2",
"npm-run-all2": "^7.0.2", "npm-run-all2": "^7.0.2",
"prettier": "3.5.3", "prettier": "3.5.3",

View File

@@ -1,19 +1,49 @@
<script setup lang="ts"> <script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue' import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue' import TheWelcome from './components/TheWelcome.vue'
import CharacterEditer from './components/CharacterEditer.vue'
import CharacterSelector from './components/CharacterSelector.vue'
import { Character, ListCharacterRequest } from './proto/character'
import { CharacterManagerClient } from './proto/character.client'
import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport'
const client = new CharacterManagerClient(
new GrpcWebFetchTransport({
baseUrl: 'http://localhost/api',
format: 'binary',
}),
)
const butts = () => {
console.log('click')
let request = ListCharacterRequest.fromJson({
playerName: 'potato',
characterName: 'spud',
})
return client.listCharacters(request).then((res) => {
console.log(res)
return res
})
}
</script> </script>
<template> <template>
<header> <header>
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" /> <img
alt="Vue logo"
<div class="wrapper"> class="logo"
<HelloWorld msg="You did it!" /> src="./assets/logo.svg"
</div> width="125"
height="125"
/>
</header> </header>
<main> <main>
<TheWelcome /> <CharacterSelector></CharacterSelector>
<!-- potato
<button class="button" @click="butts">butts</button>
<CharacterEditer></CharacterEditer> -->
</main> </main>
</template> </template>

View File

@@ -0,0 +1,24 @@
<template>
<div>{{ character }}</div>
<JsonEditorVue v-model="value" v-bind="{}" />
<v-btn>Save Character</v-btn>
</template>
<style></style>
<script setup lang="ts">
import { ref } from 'vue'
import JsonEditorVue from 'json-editor-vue'
import { Character } from '../proto/character'
const value = ref({})
const character: Character = {
playerName: '',
characterName: '',
characterAlias: [],
version: '',
sourceTable: '',
json: '{}',
}
</script>

View File

@@ -0,0 +1,79 @@
<template>
<v-text-field
v-model="characterSearch"
label="Character Name / Alias"
type="input"
clearable
></v-text-field>
<v-text-field
v-model="playerSearch"
label="Player Name"
type="input"
clearable
></v-text-field>
<div v-for="character in characterList">{{ character }}</div>
<v-expansion-panels>
<CharacterSelectorRow
v-for="character in characterList"
:character="character"
/>
</v-expansion-panels>
</template>
<style></style>
<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { Character, ListCharacterRequest } from '../proto/character'
import { CharacterManagerClient } from '../proto/character.client'
import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport'
import { watchDebounced } from '@vueuse/core'
import CharacterSelectorRow from './CharacterSelectorRow.vue'
const characterSearch = ref('')
const playerSearch = ref('')
const characterList = ref(new Array<Character>())
const client = new CharacterManagerClient(
new GrpcWebFetchTransport({
baseUrl: 'http://localhost/api',
format: 'binary',
}),
)
watchDebounced(
[characterSearch, playerSearch],
(
[newCharacterValue, oldCharacterValue],
[newPlayerValue, oldPlayerValue],
) => {
console.log(newCharacterValue)
console.log(newPlayerValue)
client
.listCharacters({
characterName: characterSearch.value,
playerName: playerSearch.value,
})
.then((res) => {
characterList.value = res.response.characters
})
},
{ debounce: 500 },
)
onMounted(() => {
let request = ListCharacterRequest.fromJson({
playerName: '',
characterName: '',
})
client.listCharacters(request).then((res) => {
characterList.value = res.response.characters
})
})
</script>

View File

@@ -0,0 +1,61 @@
<template>
<v-expansion-panel>
<v-expansion-panel-title>
<div class="d-flex flex-row">
<div class="charactername">{{ characterName }}</div>
<div class="playername">( {{ playerName }} )</div>
</div>
</v-expansion-panel-title>
<v-expansion-panel-text>
<div>Alias: {{ alias }}</div>
<JsonEditorVue v-model="json" v-bind="editorConfig" />
</v-expansion-panel-text>
</v-expansion-panel>
</template>
<style>
.charactername {
font-weight: bold;
margin-right: 10px;
}
</style>
<script setup lang="ts">
import JsonEditorVue from 'json-editor-vue'
import { computed } from 'vue'
import { Character, ListCharacterRequest } from '../proto/character'
const editorConfig = {
mainMenuBar: false,
navigationBar: false,
readOnly: true,
}
const {
character = {
playerName: 'Unkown Player',
characterName: 'Player Character',
characterAlias: ['No Alias'],
json: "",
},
} = defineProps<{ character?: Character }>()
const playerName = computed(() => {
return character.playerName || 'Unnamed Player'
})
const characterName = computed(() => {
return character.characterName || 'Unnamed Character'
})
const alias = computed(() => {
return (character.characterAlias || [])
.map((entry) => '"' + entry + '"')
.join(', ')
})
const json = computed(() => {
return character.json || '{}'
})
</script>

View File

@@ -1,3 +1,4 @@
d
<script setup lang="ts"> <script setup lang="ts">
defineProps<{ defineProps<{
msg: string msg: string

View File

@@ -17,7 +17,9 @@ const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
<template #heading>Documentation</template> <template #heading>Documentation</template>
Vues Vues
<a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a> <a href="https://vuejs.org/" target="_blank" rel="noopener"
>official documentation</a
>
provides you with all information you need to get started. provides you with all information you need to get started.
</WelcomeItem> </WelcomeItem>
@@ -28,22 +30,35 @@ const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
<template #heading>Tooling</template> <template #heading>Tooling</template>
This project is served and bundled with This project is served and bundled with
<a href="https://vite.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The <a
recommended IDE setup is href="https://vite.dev/guide/features.html"
<a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a> target="_blank"
rel="noopener"
>Vite</a
>. The recommended IDE setup is
<a href="https://code.visualstudio.com/" target="_blank" rel="noopener"
>VSCode</a
>
+ +
<a href="https://github.com/vuejs/language-tools" target="_blank" rel="noopener">Vue - Official</a>. If <a
you need to test your components and web pages, check out href="https://github.com/vuejs/language-tools"
target="_blank"
rel="noopener"
>Vue - Official</a
>. If you need to test your components and web pages, check out
<a href="https://vitest.dev/" target="_blank" rel="noopener">Vitest</a> <a href="https://vitest.dev/" target="_blank" rel="noopener">Vitest</a>
and and
<a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a> <a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a>
/ /
<a href="https://playwright.dev/" target="_blank" rel="noopener">Playwright</a>. <a href="https://playwright.dev/" target="_blank" rel="noopener"
>Playwright</a
>.
<br /> <br />
More instructions are available in More instructions are available in
<a href="javascript:void(0)" @click="openReadmeInEditor"><code>README.md</code></a <a href="javascript:void(0)" @click="openReadmeInEditor"
><code>README.md</code></a
>. >.
</WelcomeItem> </WelcomeItem>
@@ -55,11 +70,21 @@ const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
Get official tools and libraries for your project: Get official tools and libraries for your project:
<a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>, <a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
<a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>, <a href="https://router.vuejs.org/" target="_blank" rel="noopener"
<a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and >Vue Router</a
<a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If >,
you need more resources, we suggest paying <a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener"
<a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a> >Vue Test Utils</a
>, and
<a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener"
>Vue Dev Tools</a
>. If you need more resources, we suggest paying
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
rel="noopener"
>Awesome Vue</a
>
a visit. a visit.
</WelcomeItem> </WelcomeItem>
@@ -72,10 +97,15 @@ const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
Got stuck? Ask your question on Got stuck? Ask your question on
<a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a> <a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>
(our official Discord server), or (our official Discord server), or
<a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener" <a
href="https://stackoverflow.com/questions/tagged/vue.js"
target="_blank"
rel="noopener"
>StackOverflow</a >StackOverflow</a
>. You should also follow the official >. You should also follow the official
<a href="https://bsky.app/profile/vuejs.org" target="_blank" rel="noopener">@vuejs.org</a> <a href="https://bsky.app/profile/vuejs.org" target="_blank" rel="noopener"
>@vuejs.org</a
>
Bluesky account or the Bluesky account or the
<a href="https://x.com/vuejs" target="_blank" rel="noopener">@vuejs</a> <a href="https://x.com/vuejs" target="_blank" rel="noopener">@vuejs</a>
X account for latest news in the Vue world. X account for latest news in the Vue world.
@@ -87,8 +117,10 @@ const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
</template> </template>
<template #heading>Support Vue</template> <template #heading>Support Vue</template>
As an independent project, Vue relies on community backing for its sustainability. You can help As an independent project, Vue relies on community backing for its
us by sustainability. You can help us by
<a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>. <a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener"
>becoming a sponsor</a
>.
</WelcomeItem> </WelcomeItem>
</template> </template>

View File

@@ -1,5 +1,10 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"> <svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
>
<path <path
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z" d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
/> />

View File

@@ -1,5 +1,10 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor"> <svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="17"
fill="currentColor"
>
<path <path
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z" d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
/> />

View File

@@ -1,5 +1,10 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor"> <svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="20"
fill="currentColor"
>
<path <path
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z" d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
/> />

View File

@@ -1,5 +1,10 @@
<template> <template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"> <svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
>
<path <path
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z" d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
/> />

View File

@@ -1,9 +1,13 @@
import './assets/main.css' import './assets/main.css'
import 'vuetify/styles'
// import * as grpc from 'grpc'; import { createVuetify } from 'vuetify'
import { Character } from './proto/character' import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
createApp(App).mount('#app') const vuetify = createVuetify({ components, directives })
createApp(App).use(vuetify).mount('#app')

View File

@@ -10,6 +10,16 @@ export default defineConfig({
vue(), vue(),
vueDevTools(), vueDevTools(),
], ],
preview: {
port: 3000,
strictPort: true,
},
server: {
port: 3000,
strictPort: true,
host: true,
origin: "http://0.0.0.0:3000",
},
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)) '@': fileURLToPath(new URL('./src', import.meta.url))

958
package-lock.json generated Normal file
View File

@@ -0,0 +1,958 @@
{
"name": "rush-character-archive",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"json-editor-vue": "^0.18.1",
"vuetify": "^3.8.12"
}
},
"node_modules/@ampproject/remapping": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"license": "Apache-2.0",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
"integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.28.0"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/types": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz",
"integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@codemirror/autocomplete": {
"version": "6.18.6",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz",
"integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.17.0",
"@lezer/common": "^1.0.0"
}
},
"node_modules/@codemirror/commands": {
"version": "6.8.1",
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz",
"integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.4.0",
"@codemirror/view": "^6.27.0",
"@lezer/common": "^1.1.0"
}
},
"node_modules/@codemirror/lang-json": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz",
"integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
"@lezer/json": "^1.0.0"
}
},
"node_modules/@codemirror/language": {
"version": "6.11.2",
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.2.tgz",
"integrity": "sha512-p44TsNArL4IVXDTbapUmEkAlvWs2CFQbcfc0ymDsis1kH2wh0gcY96AS29c/vp2d0y2Tquk1EDSaawpzilUiAw==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.23.0",
"@lezer/common": "^1.1.0",
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0",
"style-mod": "^4.0.0"
}
},
"node_modules/@codemirror/lint": {
"version": "6.8.5",
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz",
"integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.35.0",
"crelt": "^1.0.5"
}
},
"node_modules/@codemirror/search": {
"version": "6.5.11",
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz",
"integrity": "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"crelt": "^1.0.5"
}
},
"node_modules/@codemirror/state": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
"license": "MIT",
"dependencies": {
"@marijn/find-cluster-break": "^1.0.0"
}
},
"node_modules/@codemirror/view": {
"version": "6.38.0",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.0.tgz",
"integrity": "sha512-yvSchUwHOdupXkd7xJ0ob36jdsSR/I+/C+VbY0ffBiL5NiSTEBDfB1ZGWbbIlDd5xgdUkody+lukAdOxYrOBeg==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.5.0",
"crelt": "^1.0.6",
"style-mod": "^4.1.0",
"w3c-keyname": "^2.2.4"
}
},
"node_modules/@fortawesome/fontawesome-common-types": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz",
"integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-regular-svg-icons": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.7.2.tgz",
"integrity": "sha512-7Z/ur0gvCMW8G93dXIQOkQqHo2M5HLhYrRVC0//fakJXxcF1VmMPsxnG6Ee8qEylA8b8Q3peQXWMNZ62lYF28g==",
"license": "(CC-BY-4.0 AND MIT)",
"dependencies": {
"@fortawesome/fontawesome-common-types": "6.7.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-solid-svg-icons": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz",
"integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==",
"license": "(CC-BY-4.0 AND MIT)",
"dependencies": {
"@fortawesome/fontawesome-common-types": "6.7.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.12",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
"integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
"integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.29",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
"integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@jsep-plugin/assignment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz",
"integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==",
"license": "MIT",
"engines": {
"node": ">= 10.16.0"
},
"peerDependencies": {
"jsep": "^0.4.0||^1.0.0"
}
},
"node_modules/@jsep-plugin/regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz",
"integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==",
"license": "MIT",
"engines": {
"node": ">= 10.16.0"
},
"peerDependencies": {
"jsep": "^0.4.0||^1.0.0"
}
},
"node_modules/@jsonquerylang/jsonquery": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/@jsonquerylang/jsonquery/-/jsonquery-5.0.4.tgz",
"integrity": "sha512-QdgVkapeGRxUqOOJuh2svDutejKaCizhupEmO4ZKSsaLolD7w5QhgrjmBNuS1wMCM5TyNKifK4i1wBDfNzO9xQ==",
"license": "ISC",
"bin": {
"jsonquery": "bin/cli.js"
}
},
"node_modules/@lezer/common": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==",
"license": "MIT"
},
"node_modules/@lezer/highlight": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
"integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
"license": "MIT",
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@lezer/json": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz",
"integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==",
"license": "MIT",
"dependencies": {
"@lezer/common": "^1.2.0",
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0"
}
},
"node_modules/@lezer/lr": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
"integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
"license": "MIT",
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@marijn/find-cluster-break": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
"license": "MIT"
},
"node_modules/@replit/codemirror-indentation-markers": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/@replit/codemirror-indentation-markers/-/codemirror-indentation-markers-6.5.3.tgz",
"integrity": "sha512-hL5Sfvw3C1vgg7GolLe/uxX5T3tmgOA3ZzqlMv47zjU1ON51pzNWiVbS22oh6crYhtVhv8b3gdXwoYp++2ilHw==",
"license": "MIT",
"peerDependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0"
}
},
"node_modules/@sphinxxxx/color-conversion": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz",
"integrity": "sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==",
"license": "ISC"
},
"node_modules/@sveltejs/acorn-typescript": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz",
"integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==",
"license": "MIT",
"peerDependencies": {
"acorn": "^8.9.0"
}
},
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"license": "MIT"
},
"node_modules/@vue/compiler-core": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.17.tgz",
"integrity": "sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.27.5",
"@vue/shared": "3.5.17",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.17.tgz",
"integrity": "sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.5.17",
"@vue/shared": "3.5.17"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.17.tgz",
"integrity": "sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.27.5",
"@vue/compiler-core": "3.5.17",
"@vue/compiler-dom": "3.5.17",
"@vue/compiler-ssr": "3.5.17",
"@vue/shared": "3.5.17",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.17",
"postcss": "^8.5.6",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.17.tgz",
"integrity": "sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.17",
"@vue/shared": "3.5.17"
}
},
"node_modules/@vue/reactivity": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.17.tgz",
"integrity": "sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/shared": "3.5.17"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.17.tgz",
"integrity": "sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.17",
"@vue/shared": "3.5.17"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.17.tgz",
"integrity": "sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.17",
"@vue/runtime-core": "3.5.17",
"@vue/shared": "3.5.17",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.17.tgz",
"integrity": "sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-ssr": "3.5.17",
"@vue/shared": "3.5.17"
},
"peerDependencies": {
"vue": "3.5.17"
}
},
"node_modules/@vue/shared": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.17.tgz",
"integrity": "sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==",
"license": "MIT",
"peer": true
},
"node_modules/acorn": {
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/aria-query": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
"integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
"license": "Apache-2.0",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/codemirror-wrapped-line-indent": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/codemirror-wrapped-line-indent/-/codemirror-wrapped-line-indent-1.0.9.tgz",
"integrity": "sha512-oc976hHLt35u6Ojbhub+IWOxEpapZSqYieLEdGhsgFZ4rtYQtdb5KjxzgjCCyVe3t0yk+a6hmaIOEsjU/tZRxQ==",
"license": "MIT",
"peerDependencies": {
"@codemirror/language": "^6.9.0",
"@codemirror/state": "^6.2.1",
"@codemirror/view": "^6.17.1"
}
},
"node_modules/crelt": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
"license": "MIT"
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT",
"peer": true
},
"node_modules/diff-sequences": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
"integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
"license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/esm-env": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
"license": "MIT"
},
"node_modules/esrap": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz",
"integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"license": "MIT",
"peer": true
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-uri": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
"integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
},
"node_modules/immutable-json-patch": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/immutable-json-patch/-/immutable-json-patch-6.0.1.tgz",
"integrity": "sha512-BHL/cXMjwFZlTOffiWNdY8ZTvNyYLrutCnWxrcKPHr5FqpAb6vsO6WWSPnVSys3+DruFN6lhHJJPHi8uELQL5g==",
"license": "ISC"
},
"node_modules/is-reference": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.6"
}
},
"node_modules/jmespath": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
"integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==",
"license": "Apache-2.0",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/jsep": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz",
"integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==",
"license": "MIT",
"engines": {
"node": ">= 10.16.0"
}
},
"node_modules/json-editor-vue": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/json-editor-vue/-/json-editor-vue-0.18.1.tgz",
"integrity": "sha512-SQCtNngo/ScFjXC7KUOqLOeeLgvl+xwWbxfNelqIOHC6uLilQl7AlWzNJyrDqo+RWnc53nT0OngXki5uTx9SJg==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"vanilla-jsoneditor": "^3.0.0",
"vue-demi": "^0.14.10"
},
"peerDependencies": {
"@vue/composition-api": ">=1",
"vue": "2||3"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
"node_modules/json-source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/json-source-map/-/json-source-map-0.6.1.tgz",
"integrity": "sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==",
"license": "MIT"
},
"node_modules/jsonpath-plus": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz",
"integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==",
"license": "MIT",
"dependencies": {
"@jsep-plugin/assignment": "^1.3.0",
"@jsep-plugin/regex": "^1.0.4",
"jsep": "^1.4.0"
},
"bin": {
"jsonpath": "bin/jsonpath-cli.js",
"jsonpath-plus": "bin/jsonpath-cli.js"
},
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/jsonrepair": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/jsonrepair/-/jsonrepair-3.12.0.tgz",
"integrity": "sha512-SWfjz8SuQ0wZjwsxtSJ3Zy8vvLg6aO/kxcp9TWNPGwJKgTZVfhNEQBMk/vPOpYCDFWRxD6QWuI6IHR1t615f0w==",
"license": "ISC",
"bin": {
"jsonrepair": "bin/cli.js"
}
},
"node_modules/locate-character": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/magic-string": {
"version": "0.30.17",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
"integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/natural-compare-lite": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
"integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC",
"peer": true
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/style-mod": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
"license": "MIT"
},
"node_modules/svelte": {
"version": "5.35.2",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.35.2.tgz",
"integrity": "sha512-uW/rRXYrhZ7Dh4UQNZ0t+oVGL1dEM+95GavCO8afAk1IY2cPq9BcZv9C3um5aLIya2y8lIeLPxLII9ASGg9Dzw==",
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.3.0",
"@jridgewell/sourcemap-codec": "^1.5.0",
"@sveltejs/acorn-typescript": "^1.0.5",
"@types/estree": "^1.0.5",
"acorn": "^8.12.1",
"aria-query": "^5.3.1",
"axobject-query": "^4.1.0",
"clsx": "^2.1.1",
"esm-env": "^1.2.1",
"esrap": "^2.1.0",
"is-reference": "^3.0.3",
"locate-character": "^3.0.0",
"magic-string": "^0.30.11",
"zimmerframe": "^1.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/vanilla-jsoneditor": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/vanilla-jsoneditor/-/vanilla-jsoneditor-3.6.1.tgz",
"integrity": "sha512-P/rDsaj8c4IKWCPmpxcy13TVANzjAR0qSil78HJEw+aVCghJK6cySzJm/XwJ8Q/vyvfUg1aAq8hJWF/Uui6T0w==",
"license": "ISC",
"dependencies": {
"@codemirror/autocomplete": "^6.18.1",
"@codemirror/commands": "^6.7.1",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/language": "^6.10.3",
"@codemirror/lint": "^6.8.2",
"@codemirror/search": "^6.5.6",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.34.1",
"@fortawesome/free-regular-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@jsonquerylang/jsonquery": "^3.1.1 || ^4.0.0 || ^5.0.0",
"@lezer/highlight": "^1.2.1",
"@replit/codemirror-indentation-markers": "^6.5.3",
"ajv": "^8.17.1",
"codemirror-wrapped-line-indent": "^1.0.8",
"diff-sequences": "^29.6.3",
"immutable-json-patch": "^6.0.1",
"jmespath": "^0.16.0",
"json-source-map": "^0.6.1",
"jsonpath-plus": "^10.3.0",
"jsonrepair": "^3.0.0",
"lodash-es": "^4.17.21",
"memoize-one": "^6.0.0",
"natural-compare-lite": "^1.4.0",
"svelte": "^5.0.0",
"vanilla-picker": "^2.12.3"
}
},
"node_modules/vanilla-picker": {
"version": "2.12.3",
"resolved": "https://registry.npmjs.org/vanilla-picker/-/vanilla-picker-2.12.3.tgz",
"integrity": "sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==",
"license": "ISC",
"dependencies": {
"@sphinxxxx/color-conversion": "^2.2.2"
}
},
"node_modules/vue": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.17.tgz",
"integrity": "sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.17",
"@vue/compiler-sfc": "3.5.17",
"@vue/runtime-dom": "3.5.17",
"@vue/server-renderer": "3.5.17",
"@vue/shared": "3.5.17"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/vuetify": {
"version": "3.8.12",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.8.12.tgz",
"integrity": "sha512-XRX/yRel/V5rlas12ovujVCo8RDb/NwICyef/DVYzybqbYz/UGHZd23sN5q1zw0h9jUN8httXI6ytWN7OFugmA==",
"license": "MIT",
"engines": {
"node": "^12.20 || >=14.13"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/johnleider"
},
"peerDependencies": {
"typescript": ">=4.7",
"vite-plugin-vuetify": ">=2.1.0",
"vue": "^3.5.0",
"webpack-plugin-vuetify": ">=3.1.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
},
"vite-plugin-vuetify": {
"optional": true
},
"webpack-plugin-vuetify": {
"optional": true
}
}
},
"node_modules/w3c-keyname": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
"license": "MIT"
},
"node_modules/zimmerframe": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz",
"integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==",
"license": "MIT"
}
}
}

6
package.json Normal file
View File

@@ -0,0 +1,6 @@
{
"dependencies": {
"json-editor-vue": "^0.18.1",
"vuetify": "^3.8.12"
}
}

View File

@@ -1,49 +0,0 @@
// @generated by protobuf-ts 2.11.0 with parameter server_grpc1
// @generated from protobuf file "character.proto" (syntax proto3)
// tslint:disable
import type { RpcTransport } from "@protobuf-ts/runtime-rpc";
import type { ServiceInfo } from "@protobuf-ts/runtime-rpc";
import { CharacterManager } from "./character";
import type { GetCharacterRequest } from "./character";
import { stackIntercept } from "@protobuf-ts/runtime-rpc";
import type { Character } from "./character";
import type { CreateCharacterRequest } from "./character";
import type { UnaryCall } from "@protobuf-ts/runtime-rpc";
import type { RpcOptions } from "@protobuf-ts/runtime-rpc";
/**
* @generated from protobuf service CharacterManager
*/
export interface ICharacterManagerClient {
/**
* @generated from protobuf rpc: createCharacter
*/
createCharacter(input: CreateCharacterRequest, options?: RpcOptions): UnaryCall<CreateCharacterRequest, Character>;
/**
* @generated from protobuf rpc: getCharacter
*/
getCharacter(input: GetCharacterRequest, options?: RpcOptions): UnaryCall<GetCharacterRequest, Character>;
}
/**
* @generated from protobuf service CharacterManager
*/
export class CharacterManagerClient implements ICharacterManagerClient, ServiceInfo {
typeName = CharacterManager.typeName;
methods = CharacterManager.methods;
options = CharacterManager.options;
constructor(private readonly _transport: RpcTransport) {
}
/**
* @generated from protobuf rpc: createCharacter
*/
createCharacter(input: CreateCharacterRequest, options?: RpcOptions): UnaryCall<CreateCharacterRequest, Character> {
const method = this.methods[0], opt = this._transport.mergeOptions(options);
return stackIntercept<CreateCharacterRequest, Character>("unary", this._transport, method, opt, input);
}
/**
* @generated from protobuf rpc: getCharacter
*/
getCharacter(input: GetCharacterRequest, options?: RpcOptions): UnaryCall<GetCharacterRequest, Character> {
const method = this.methods[1], opt = this._transport.mergeOptions(options);
return stackIntercept<GetCharacterRequest, Character>("unary", this._transport, method, opt, input);
}
}

View File

@@ -1,53 +0,0 @@
// @generated by protobuf-ts 2.11.0 with parameter server_grpc1
// @generated from protobuf file "character.proto" (syntax proto3)
// tslint:disable
import { GetCharacterRequest } from "./character";
import { Character } from "./character";
import { CreateCharacterRequest } from "./character";
import type * as grpc from "@grpc/grpc-js";
/**
* @generated from protobuf service CharacterManager
*/
export interface ICharacterManager extends grpc.UntypedServiceImplementation {
/**
* @generated from protobuf rpc: createCharacter
*/
createCharacter: grpc.handleUnaryCall<CreateCharacterRequest, Character>;
/**
* @generated from protobuf rpc: getCharacter
*/
getCharacter: grpc.handleUnaryCall<GetCharacterRequest, Character>;
}
/**
* @grpc/grpc-js definition for the protobuf service CharacterManager.
*
* Usage: Implement the interface ICharacterManager and add to a grpc server.
*
* ```typescript
* const server = new grpc.Server();
* const service: ICharacterManager = ...
* server.addService(characterManagerDefinition, service);
* ```
*/
export const characterManagerDefinition: grpc.ServiceDefinition<ICharacterManager> = {
createCharacter: {
path: "/CharacterManager/createCharacter",
originalName: "createCharacter",
requestStream: false,
responseStream: false,
responseDeserialize: bytes => Character.fromBinary(bytes),
requestDeserialize: bytes => CreateCharacterRequest.fromBinary(bytes),
responseSerialize: value => Buffer.from(Character.toBinary(value)),
requestSerialize: value => Buffer.from(CreateCharacterRequest.toBinary(value))
},
getCharacter: {
path: "/CharacterManager/getCharacter",
originalName: "getCharacter",
requestStream: false,
responseStream: false,
responseDeserialize: bytes => Character.fromBinary(bytes),
requestDeserialize: bytes => GetCharacterRequest.fromBinary(bytes),
responseSerialize: value => Buffer.from(Character.toBinary(value)),
requestSerialize: value => Buffer.from(GetCharacterRequest.toBinary(value))
}
};

View File

@@ -3,14 +3,31 @@ syntax = "proto3";
service CharacterManager { service CharacterManager {
rpc createCharacter(CreateCharacterRequest) returns (Character); rpc createCharacter(CreateCharacterRequest) returns (Character);
rpc getCharacter(GetCharacterRequest) returns (Character); rpc getCharacter(GetCharacterRequest) returns (Character);
rpc listCharacters(ListCharacterRequest) returns (ListCharacterResponse);
} }
message Empty {}
message Character { message Character {
string PlayerName = 1; string PlayerName = 1;
string CharacterName = 2; string CharacterName = 2;
repeated string CharacterAlias = 3; repeated string CharacterAlias = 3;
string Version = 4;
string SourceTable = 5;
string Json = 6;
} }
message CreateCharacterRequest {} message CreateCharacterRequest {
Character characterData = 1;
}
message GetCharacterRequest {} message GetCharacterRequest {}
message ListCharacterRequest {
string PlayerName = 1;
string CharacterName = 2;
}
message ListCharacterResponse {
repeated Character characters = 1;
}

View File

@@ -1,186 +0,0 @@
// @generated by protobuf-ts 2.11.0 with parameter server_grpc1
// @generated from protobuf file "character.proto" (syntax proto3)
// tslint:disable
import { ServiceType } from "@protobuf-ts/runtime-rpc";
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
import type { IBinaryWriter } from "@protobuf-ts/runtime";
import { WireType } from "@protobuf-ts/runtime";
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
import type { IBinaryReader } from "@protobuf-ts/runtime";
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
import type { PartialMessage } from "@protobuf-ts/runtime";
import { reflectionMergePartial } from "@protobuf-ts/runtime";
import { MessageType } from "@protobuf-ts/runtime";
/**
* @generated from protobuf message Character
*/
export interface Character {
/**
* @generated from protobuf field: string PlayerName = 1
*/
playerName: string;
/**
* @generated from protobuf field: string CharacterName = 2
*/
characterName: string;
/**
* @generated from protobuf field: repeated string CharacterAlias = 3
*/
characterAlias: string[];
}
/**
* @generated from protobuf message CreateCharacterRequest
*/
export interface CreateCharacterRequest {
}
/**
* @generated from protobuf message GetCharacterRequest
*/
export interface GetCharacterRequest {
}
// @generated message type with reflection information, may provide speed optimized methods
class Character$Type extends MessageType<Character> {
constructor() {
super("Character", [
{ no: 1, name: "PlayerName", kind: "scalar", jsonName: "PlayerName", T: 9 /*ScalarType.STRING*/ },
{ no: 2, name: "CharacterName", kind: "scalar", jsonName: "CharacterName", T: 9 /*ScalarType.STRING*/ },
{ no: 3, name: "CharacterAlias", kind: "scalar", jsonName: "CharacterAlias", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ }
]);
}
create(value?: PartialMessage<Character>): Character {
const message = globalThis.Object.create((this.messagePrototype!));
message.playerName = "";
message.characterName = "";
message.characterAlias = [];
if (value !== undefined)
reflectionMergePartial<Character>(this, message, value);
return message;
}
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Character): Character {
let message = target ?? this.create(), end = reader.pos + length;
while (reader.pos < end) {
let [fieldNo, wireType] = reader.tag();
switch (fieldNo) {
case /* string PlayerName */ 1:
message.playerName = reader.string();
break;
case /* string CharacterName */ 2:
message.characterName = reader.string();
break;
case /* repeated string CharacterAlias */ 3:
message.characterAlias.push(reader.string());
break;
default:
let u = options.readUnknownField;
if (u === "throw")
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
let d = reader.skip(wireType);
if (u !== false)
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
}
}
return message;
}
internalBinaryWrite(message: Character, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
/* string PlayerName = 1; */
if (message.playerName !== "")
writer.tag(1, WireType.LengthDelimited).string(message.playerName);
/* string CharacterName = 2; */
if (message.characterName !== "")
writer.tag(2, WireType.LengthDelimited).string(message.characterName);
/* repeated string CharacterAlias = 3; */
for (let i = 0; i < message.characterAlias.length; i++)
writer.tag(3, WireType.LengthDelimited).string(message.characterAlias[i]);
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
return writer;
}
}
/**
* @generated MessageType for protobuf message Character
*/
export const Character = new Character$Type();
// @generated message type with reflection information, may provide speed optimized methods
class CreateCharacterRequest$Type extends MessageType<CreateCharacterRequest> {
constructor() {
super("CreateCharacterRequest", []);
}
create(value?: PartialMessage<CreateCharacterRequest>): CreateCharacterRequest {
const message = globalThis.Object.create((this.messagePrototype!));
if (value !== undefined)
reflectionMergePartial<CreateCharacterRequest>(this, message, value);
return message;
}
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: CreateCharacterRequest): CreateCharacterRequest {
let message = target ?? this.create(), end = reader.pos + length;
while (reader.pos < end) {
let [fieldNo, wireType] = reader.tag();
switch (fieldNo) {
default:
let u = options.readUnknownField;
if (u === "throw")
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
let d = reader.skip(wireType);
if (u !== false)
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
}
}
return message;
}
internalBinaryWrite(message: CreateCharacterRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
return writer;
}
}
/**
* @generated MessageType for protobuf message CreateCharacterRequest
*/
export const CreateCharacterRequest = new CreateCharacterRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class GetCharacterRequest$Type extends MessageType<GetCharacterRequest> {
constructor() {
super("GetCharacterRequest", []);
}
create(value?: PartialMessage<GetCharacterRequest>): GetCharacterRequest {
const message = globalThis.Object.create((this.messagePrototype!));
if (value !== undefined)
reflectionMergePartial<GetCharacterRequest>(this, message, value);
return message;
}
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GetCharacterRequest): GetCharacterRequest {
let message = target ?? this.create(), end = reader.pos + length;
while (reader.pos < end) {
let [fieldNo, wireType] = reader.tag();
switch (fieldNo) {
default:
let u = options.readUnknownField;
if (u === "throw")
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
let d = reader.skip(wireType);
if (u !== false)
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
}
}
return message;
}
internalBinaryWrite(message: GetCharacterRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
return writer;
}
}
/**
* @generated MessageType for protobuf message GetCharacterRequest
*/
export const GetCharacterRequest = new GetCharacterRequest$Type();
/**
* @generated ServiceType for protobuf service CharacterManager
*/
export const CharacterManager = new ServiceType("CharacterManager", [
{ name: "createCharacter", options: {}, I: CreateCharacterRequest, O: Character },
{ name: "getCharacter", options: {}, I: GetCharacterRequest, O: Character }
]);

View File

@@ -2,7 +2,7 @@ FROM node:22.16
WORKDIR /srv/proto WORKDIR /srv/proto
COPY proto . COPY proto/ .
WORKDIR /srv/vault WORKDIR /srv/vault
@@ -10,10 +10,7 @@ COPY vault/package.json .
RUN npm install RUN npm install
COPY vault . COPY vault/ .
RUN npm install -g protoc
RUN npm install -g protoc-gen-ts
RUN npm run build_protos RUN npm run build_protos
RUN npm run build RUN npm run build

View File

@@ -1,260 +0,0 @@
/**
* Generated by the protoc-gen-ts. DO NOT EDIT!
* compiler version: 3.20.3
* source: character.proto
* git: https://github.com/thesayyn/protoc-gen-ts */
import * as pb_1 from "google-protobuf";
import * as grpc_1 from "@grpc/grpc-js";
export class Character extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
PlayerName?: string;
CharacterName?: string;
CharacterAlias?: string[];
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [3], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("PlayerName" in data && data.PlayerName != undefined) {
this.PlayerName = data.PlayerName;
}
if ("CharacterName" in data && data.CharacterName != undefined) {
this.CharacterName = data.CharacterName;
}
if ("CharacterAlias" in data && data.CharacterAlias != undefined) {
this.CharacterAlias = data.CharacterAlias;
}
}
}
get PlayerName() {
return pb_1.Message.getFieldWithDefault(this, 1, "") as string;
}
set PlayerName(value: string) {
pb_1.Message.setField(this, 1, value);
}
get CharacterName() {
return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
}
set CharacterName(value: string) {
pb_1.Message.setField(this, 2, value);
}
get CharacterAlias() {
return pb_1.Message.getFieldWithDefault(this, 3, []) as string[];
}
set CharacterAlias(value: string[]) {
pb_1.Message.setField(this, 3, value);
}
static fromObject(data: {
PlayerName?: string;
CharacterName?: string;
CharacterAlias?: string[];
}): Character {
const message = new Character({});
if (data.PlayerName != null) {
message.PlayerName = data.PlayerName;
}
if (data.CharacterName != null) {
message.CharacterName = data.CharacterName;
}
if (data.CharacterAlias != null) {
message.CharacterAlias = data.CharacterAlias;
}
return message;
}
toObject() {
const data: {
PlayerName?: string;
CharacterName?: string;
CharacterAlias?: string[];
} = {};
if (this.PlayerName != null) {
data.PlayerName = this.PlayerName;
}
if (this.CharacterName != null) {
data.CharacterName = this.CharacterName;
}
if (this.CharacterAlias != null) {
data.CharacterAlias = this.CharacterAlias;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.PlayerName.length)
writer.writeString(1, this.PlayerName);
if (this.CharacterName.length)
writer.writeString(2, this.CharacterName);
if (this.CharacterAlias.length)
writer.writeRepeatedString(3, this.CharacterAlias);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): Character {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new Character();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.PlayerName = reader.readString();
break;
case 2:
message.CharacterName = reader.readString();
break;
case 3:
pb_1.Message.addToRepeatedField(message, 3, reader.readString());
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): Character {
return Character.deserialize(bytes);
}
}
export class CreateCharacterRequest extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") { }
}
static fromObject(data: {}): CreateCharacterRequest {
const message = new CreateCharacterRequest({});
return message;
}
toObject() {
const data: {} = {};
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): CreateCharacterRequest {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new CreateCharacterRequest();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): CreateCharacterRequest {
return CreateCharacterRequest.deserialize(bytes);
}
}
export class GetCharacterRequest extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") { }
}
static fromObject(data: {}): GetCharacterRequest {
const message = new GetCharacterRequest({});
return message;
}
toObject() {
const data: {} = {};
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): GetCharacterRequest {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new GetCharacterRequest();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): GetCharacterRequest {
return GetCharacterRequest.deserialize(bytes);
}
}
interface GrpcUnaryServiceInterface<P, R> {
(message: P, metadata: grpc_1.Metadata, options: grpc_1.CallOptions, callback: grpc_1.requestCallback<R>): grpc_1.ClientUnaryCall;
(message: P, metadata: grpc_1.Metadata, callback: grpc_1.requestCallback<R>): grpc_1.ClientUnaryCall;
(message: P, options: grpc_1.CallOptions, callback: grpc_1.requestCallback<R>): grpc_1.ClientUnaryCall;
(message: P, callback: grpc_1.requestCallback<R>): grpc_1.ClientUnaryCall;
}
interface GrpcStreamServiceInterface<P, R> {
(message: P, metadata: grpc_1.Metadata, options?: grpc_1.CallOptions): grpc_1.ClientReadableStream<R>;
(message: P, options?: grpc_1.CallOptions): grpc_1.ClientReadableStream<R>;
}
interface GrpWritableServiceInterface<P, R> {
(metadata: grpc_1.Metadata, options: grpc_1.CallOptions, callback: grpc_1.requestCallback<R>): grpc_1.ClientWritableStream<P>;
(metadata: grpc_1.Metadata, callback: grpc_1.requestCallback<R>): grpc_1.ClientWritableStream<P>;
(options: grpc_1.CallOptions, callback: grpc_1.requestCallback<R>): grpc_1.ClientWritableStream<P>;
(callback: grpc_1.requestCallback<R>): grpc_1.ClientWritableStream<P>;
}
interface GrpcChunkServiceInterface<P, R> {
(metadata: grpc_1.Metadata, options?: grpc_1.CallOptions): grpc_1.ClientDuplexStream<P, R>;
(options?: grpc_1.CallOptions): grpc_1.ClientDuplexStream<P, R>;
}
interface GrpcPromiseServiceInterface<P, R> {
(message: P, metadata: grpc_1.Metadata, options?: grpc_1.CallOptions): Promise<R>;
(message: P, options?: grpc_1.CallOptions): Promise<R>;
}
export abstract class UnimplementedCharacterManagerService {
static definition = {
createCharacter: {
path: "/CharacterManager/createCharacter",
requestStream: false,
responseStream: false,
requestSerialize: (message: CreateCharacterRequest) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => CreateCharacterRequest.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: Character) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => Character.deserialize(new Uint8Array(bytes))
},
getCharacter: {
path: "/CharacterManager/getCharacter",
requestStream: false,
responseStream: false,
requestSerialize: (message: GetCharacterRequest) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => GetCharacterRequest.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: Character) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => Character.deserialize(new Uint8Array(bytes))
}
};
[method: string]: grpc_1.UntypedHandleCall;
abstract createCharacter(call: grpc_1.ServerUnaryCall<CreateCharacterRequest, Character>, callback: grpc_1.sendUnaryData<Character>): void;
abstract getCharacter(call: grpc_1.ServerUnaryCall<GetCharacterRequest, Character>, callback: grpc_1.sendUnaryData<Character>): void;
}
export class CharacterManagerClient extends grpc_1.makeGenericClientConstructor(UnimplementedCharacterManagerService.definition, "CharacterManager", {}) {
constructor(address: string, credentials: grpc_1.ChannelCredentials, options?: Partial<grpc_1.ChannelOptions>) {
super(address, credentials, options);
}
createCharacter: GrpcUnaryServiceInterface<CreateCharacterRequest, Character> = (message: CreateCharacterRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<Character>, options?: grpc_1.CallOptions | grpc_1.requestCallback<Character>, callback?: grpc_1.requestCallback<Character>): grpc_1.ClientUnaryCall => {
return super.createCharacter(message, metadata, options, callback);
};
getCharacter: GrpcUnaryServiceInterface<GetCharacterRequest, Character> = (message: GetCharacterRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<Character>, options?: grpc_1.CallOptions | grpc_1.requestCallback<Character>, callback?: grpc_1.requestCallback<Character>): grpc_1.ClientUnaryCall => {
return super.getCharacter(message, metadata, options, callback);
};
}

View File

@@ -10,7 +10,10 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@grpc/grpc-js": "^1.13.4", "@grpc/grpc-js": "^1.13.4",
"@grpc/proto-loader": "^0.7.15",
"@grpc/reflection": "^1.0.4",
"@protobuf-ts/protoc": "^2.11.0", "@protobuf-ts/protoc": "^2.11.0",
"commander": "^14.0.0",
"express": "^5.1.0", "express": "^5.1.0",
"google-protobuf": "^3.21.4", "google-protobuf": "^3.21.4",
"mongodb": "^6.17.0" "mongodb": "^6.17.0"
@@ -260,6 +263,19 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/@grpc/reflection": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@grpc/reflection/-/reflection-1.0.4.tgz",
"integrity": "sha512-znA8v4AviOD3OPOxy11pxrtP8k8DanpefeTymS8iGW1fVr1U2cHuzfhYqDPHnVNDf4qvF9E25KtSihPy2DBWfQ==",
"license": "Apache-2.0",
"dependencies": {
"@grpc/proto-loader": "^0.7.13",
"protobufjs": "^7.2.5"
},
"peerDependencies": {
"@grpc/grpc-js": "^1.8.21"
}
},
"node_modules/@humanfs/core": { "node_modules/@humanfs/core": {
"version": "0.19.1", "version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -1314,6 +1330,15 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/commander": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz",
"integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==",
"license": "MIT",
"engines": {
"node": ">=20"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",

View File

@@ -4,7 +4,7 @@
"description": "backend for rush cahracter archive", "description": "backend for rush cahracter archive",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build_protos": "mkdir -p src/proto & npx protoc -I=../proto/ --ts_out=server_grpc1:./src/proto --proto_path ../proto ../proto/*.proto", "build_protos": "mkdir -p src/proto && npx protoc -I=../proto/ --ts_out=server_grpc1:./src/proto --proto_path ../proto ../proto/*.proto && cp ../proto/*.proto ./src/proto",
"build": "tsc", "build": "tsc",
"start": "tsc && node dist/app.js", "start": "tsc && node dist/app.js",
"dev": "npx ts-node-dev src/app.ts", "dev": "npx ts-node-dev src/app.ts",
@@ -29,7 +29,10 @@
}, },
"dependencies": { "dependencies": {
"@grpc/grpc-js": "^1.13.4", "@grpc/grpc-js": "^1.13.4",
"@grpc/proto-loader": "^0.7.15",
"@grpc/reflection": "^1.0.4",
"@protobuf-ts/protoc": "^2.11.0", "@protobuf-ts/protoc": "^2.11.0",
"commander": "^14.0.0",
"express": "^5.1.0", "express": "^5.1.0",
"google-protobuf": "^3.21.4", "google-protobuf": "^3.21.4",
"mongodb": "^6.17.0" "mongodb": "^6.17.0"

View File

@@ -1,13 +1,26 @@
import { Server, ServerCredentials } from '@grpc/grpc-js' import { Server, ServerCredentials } from '@grpc/grpc-js'
import { MongoClient } from 'mongodb'
import { initCharacterService } from './character_service' import { CharacterService } from './character_service'
import { DatabaseService } from './database'
import { Flags } from './flags'
const port = 8000 const flags = new Flags()
const port = flags.getPort()
const address = `0.0.0.0:${port}`
const databaseService = new DatabaseService(
flags.getMongoDbAddress(),
flags.getMongoDbName(),
)
const characterService = new CharacterService(databaseService)
const app = new Server() const app = new Server()
initCharacterService(app) characterService.addToServer(app)
app.bindAsync('0.0.0.0:8080', ServerCredentials.createInsecure(), () => { app.bindAsync(address, ServerCredentials.createInsecure(), () => {
console.log('Starting server at 0.0.0.0:8080') console.log(`Starting server at ${address}`)
}) })

View File

@@ -1,40 +1,87 @@
import { Server, ServerUnaryCall, sendUnaryData } from '@grpc/grpc-js' import { Server, ServerUnaryCall, sendUnaryData, StatusBuilder } from '@grpc/grpc-js'
import { ReflectionService } from '@grpc/reflection'
import { loadSync } from '@grpc/proto-loader'
import { MongoClient, Collection, Db } from 'mongodb'
import { DatabaseService } from './database'
import { import {
Character, Character,
GetCharacterRequest, GetCharacterRequest,
CreateCharacterRequest, CreateCharacterRequest,
ListCharacterRequest,
ListCharacterResponse,
} from './proto/character' } from './proto/character'
import { characterManagerDefinition } from "./proto/character.grpc-server" import {
characterManagerDefinition,
ICharacterManager,
} from './proto/character.grpc-server'
export function initCharacterService(server: Server) { const testCharacter: Character = {
server.addService(characterManagerDefinition, { playerName: 'test player',
createCharacter: createCharacter_Call, characterName: 'test character',
getCharacter: getCharacter_Call, characterAlias: ['test alias'],
version: 'test version',
sourceTable: 'source table',
json: 'test json',
}
export class CharacterService {
reflectionService: ReflectionService
characterManager: ICharacterManager
databaseService: DatabaseService
constructor(databaseService: DatabaseService) {
this.reflectionService = new ReflectionService(
loadSync('./src/proto/character.proto'),
)
this.characterManager = {
createCharacter: this.createCharacterCall.bind(this),
getCharacter: this.getCharacterCall.bind(this),
listCharacters: this.listCharactersCall.bind(this),
}
this.databaseService = databaseService
}
addToServer(server: Server) {
server.addService(characterManagerDefinition, this.characterManager)
this.reflectionService.addToServer(server)
}
async createCharacterCall(
call: ServerUnaryCall<CreateCharacterRequest, Character>,
callback: sendUnaryData<Character>,
) {
let newCharacter = await this.databaseService.insertCharacter(
call.request.characterData,
)
console.log(newCharacter)
callback(null, newCharacter)
}
getCharacterCall(
call: ServerUnaryCall<GetCharacterRequest, Character>,
callback: sendUnaryData<Character>,
) {
callback(null, testCharacter)
}
async listCharactersCall(
call: ServerUnaryCall<ListCharacterRequest, ListCharacterResponse>,
callback: sendUnaryData<ListCharacterResponse>,
) {
let characters = await this.databaseService.listCharacters(
call.request.playerName,
call.request.characterName,
)
callback(null, {
characters,
}) })
}
function createCharacter_Call(call: ServerUnaryCall<CreateCharacterRequest, Character>, callback: sendUnaryData<Character>) {
callback(null, createCharacter(call.request))
}
function createCharacter(request: CreateCharacterRequest): Character {
return {
playerName: "test player",
characterName: "test character",
characterAlias: ["test alias"]
}
}
function getCharacter_Call(call: ServerUnaryCall<GetCharacterRequest, Character>, callback: sendUnaryData<Character>) {
callback(null, getCharacter(call.request))
}
function getCharacter(request: GetCharacterRequest): Character {
return {
playerName: "test player",
characterName: "test character",
characterAlias: ["test alias"]
} }
} }

71
vault/src/database.ts Normal file
View File

@@ -0,0 +1,71 @@
import { MongoClient, Db, Collection } from 'mongodb'
import { Character } from './proto/character'
export class DatabaseService {
private readonly client: MongoClient
private readonly db: Db
private readonly characterCollection: Collection
constructor(databaseAddress: string, databaseName: string) {
this.client = new MongoClient(databaseAddress)
this.db = this.client.db(databaseName)
this.characterCollection = this.db.collection('characters')
}
insertCharacter(character: Character): Promise<Character> {
return this.characterCollection
.insertOne(character)
.then((insertResult) => {
console.log("Adding new character record:", insertResult)
return this.characterCollection.findOne({
_id: insertResult.insertedId,
})
})
.then(record => {
const character = recordToCharacter(record)
console.log(`New character result: \n _id: ${record._id}`, character)
return character
})
}
fetchCharactersForPlayer(playerName: string): Promise<Array<Character>> {
return this.characterCollection
.find({ playerName: playerName })
.toArray()
.then((results) => results.map(recordToCharacter))
}
fetchCharactersForCharacterName(playerName: string): Array<Character> {
return []
}
listCharacters(
playerName: string,
characterName: string,
): Promise<Array<Character>> {
let query = {}
if (playerName != '') query['playerName'] = playerName
if (characterName != '')
query['$or'] = [
{ characterName: characterName },
{ characterAlias: characterName},
]
return this.characterCollection
.find(query)
.toArray()
.then((results) => results.map(recordToCharacter))
}
}
function recordToCharacter(record): Character {
return {
playerName: record.playerName,
characterName: record.characterName,
characterAlias: record.characterAlias,
version: record.version,
sourceTable: record.sourceTable,
json: record.json,
}
}

32
vault/src/flags.ts Normal file
View File

@@ -0,0 +1,32 @@
import { Command } from 'commander'
export class Flags {
private readonly program = new Command()
.option('-p, --port <number>', 'server port number', '8080')
.option(
'--mongoPath <string>',
'mongo db path',
'mongodb://rushvault:rushvault@mongo:27017/',
)
.option(
'--mongoDb <string>',
'name of the databse to store collections',
'rush-vault',
)
constructor() {
this.program.parse()
}
getPort(): number {
return this.program.opts().port
}
getMongoDbAddress(): string {
return this.program.opts().mongoPath
}
getMongoDbName(): string {
return this.program.opts().mongoDb
}
}