mirror of
https://github.com/Spythere/srjp-td2.git
synced 2026-05-03 13:38:12 +00:00
@@ -5,7 +5,7 @@ name: Deploy to Firebase Hosting on merge
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main-old
|
||||||
jobs:
|
jobs:
|
||||||
build_and_deploy:
|
build_and_deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
github-releases-to-discord:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Github Releases To Discord
|
||||||
|
uses: SethCohen/github-releases-to-discord@v1.13.1
|
||||||
|
with:
|
||||||
|
webhook_url: '${{ secrets.WEBHOOK_URL }}'
|
||||||
|
color: '10038562'
|
||||||
|
footer_title: 'Changelog - Rozkładownik SRJP'
|
||||||
|
footer_timestamp: true
|
||||||
@@ -19,7 +19,7 @@ async function main() {
|
|||||||
if (!existsSync('endpoints')) await mkdir('endpoints');
|
if (!existsSync('endpoints')) await mkdir('endpoints');
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
['getActiveData', 'getDonators', 'getSceneries', 'getVehicles'].map((endpointName) =>
|
['getActiveData', 'getDonators', 'getSceneries', 'getVehiclesData'].map((endpointName) =>
|
||||||
fetchJSONEndpointData(
|
fetchJSONEndpointData(
|
||||||
`https://stacjownik.spythere.eu/api/${endpointName}`,
|
`https://stacjownik.spythere.eu/api/${endpointName}`,
|
||||||
`${endpointName}.json`
|
`${endpointName}.json`
|
||||||
|
|||||||
+2
-2
@@ -15,8 +15,8 @@ app.get('/api/getSceneries', (_, res) => {
|
|||||||
res.sendFile(path.join(cwd(), 'endpoints', 'getSceneries.json'));
|
res.sendFile(path.join(cwd(), 'endpoints', 'getSceneries.json'));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/api/getVehicles', (_, res) => {
|
app.get('/api/getVehiclesData', (_, res) => {
|
||||||
res.sendFile(path.join(cwd(), 'endpoints', 'getVehicles.json'));
|
res.sendFile(path.join(cwd(), 'endpoints', 'getVehiclesData.json'));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/api/getDonators', (_, res) => {
|
app.get('/api/getDonators', (_, res) => {
|
||||||
|
|||||||
+1
-2
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "srjp-td2",
|
"name": "srjp-td2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --mode staging",
|
"dev": "vite --mode staging",
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.13.6",
|
|
||||||
"lucide-vue-next": "^0.577.0",
|
"lucide-vue-next": "^0.577.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"vue": "^3.5.30",
|
"vue": "^3.5.30",
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
<nav class="bg-zinc-900 w-full p-1 print:hidden flex justify-between items-center relative">
|
<nav class="bg-zinc-900 w-full p-1 print:hidden flex justify-between items-center relative">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img src="/favicon.svg" class="size-8 inline" alt="SRJP logo" />
|
<img src="/favicon.svg" class="size-8 inline" alt="SRJP logo" />
|
||||||
<b class="ml-2 text-lg"
|
<b class="ml-2 text-lg">
|
||||||
>Rozkładownik TD2 <sup class="font-semibold text-zinc-300">{{ version }}</sup></b
|
Rozkładownik TD2
|
||||||
>
|
<sup class="font-semibold text-zinc-300">
|
||||||
|
<a :href="releaseHref" target="_blank">v{{ version }}</a>
|
||||||
|
</sup>
|
||||||
|
</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -23,12 +26,15 @@
|
|||||||
import { GlobeIcon } from 'lucide-vue-next';
|
import { GlobeIcon } from 'lucide-vue-next';
|
||||||
import { version } from '../../../package.json';
|
import { version } from '../../../package.json';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
|
|
||||||
function changeLang(locale?: string) {
|
function changeLang(locale?: string) {
|
||||||
i18n.locale.value = locale ?? i18n.locale.value == 'pl' ? 'en' : 'pl';
|
i18n.locale.value = (locale ?? i18n.locale.value == 'pl') ? 'en' : 'pl';
|
||||||
window.localStorage.setItem('locale', i18n.locale.value);
|
window.localStorage.setItem('locale', i18n.locale.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const releaseHref = computed(() => `https://github.com/Spythere/srjp-td2/releases/tag/v${version}`);
|
||||||
// const apiMode = import.meta.env.VITE_API_MODE;
|
// const apiMode = import.meta.env.VITE_API_MODE;
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,13 +8,30 @@
|
|||||||
<Minimize2Icon :size="22" />
|
<Minimize2Icon :size="22" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Timetable render based on current view mode -->
|
|
||||||
<CurrentTimetableView v-if="globalStore.currentTimetableData != null" />
|
|
||||||
|
|
||||||
<!-- If there is no timetable chosen -->
|
<!-- If there is no timetable chosen -->
|
||||||
<div class="overflow-auto text-center font-bold text-zinc-400 p-1 min-h-full" v-else>
|
<div
|
||||||
|
class="overflow-auto text-center font-bold text-zinc-400 p-2 min-h-full"
|
||||||
|
v-if="globalStore.currentTimetableData == null"
|
||||||
|
>
|
||||||
<component :is="viewModes[globalStore.viewMode]" />
|
<component :is="viewModes[globalStore.viewMode]" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="overflow-auto text-center font-bold text-white p-2 min-h-full"
|
||||||
|
v-else-if="apiStore.apiDataStatus == DataStatus.LOADING"
|
||||||
|
>
|
||||||
|
Pobieranie danych...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="overflow-auto text-center font-bold text-red-500 p-2 min-h-full"
|
||||||
|
v-else-if="apiStore.apiDataStatus == DataStatus.ERROR"
|
||||||
|
>
|
||||||
|
Ups! Coś poszło nie tak przy pobieraniu danych! :/
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Timetable render based on current view mode -->
|
||||||
|
<CurrentTimetableView v-else />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -24,8 +41,11 @@ import JournalStorageView from '../TimetableViews/JournalStorageView.vue';
|
|||||||
import ActiveDataView from '../TimetableViews/ActiveDataView.vue';
|
import ActiveDataView from '../TimetableViews/ActiveDataView.vue';
|
||||||
import CurrentTimetableView from '../TimetableViews/CurrentTimetableView.vue';
|
import CurrentTimetableView from '../TimetableViews/CurrentTimetableView.vue';
|
||||||
import { Minimize2Icon } from 'lucide-vue-next';
|
import { Minimize2Icon } from 'lucide-vue-next';
|
||||||
|
import { useApiStore } from '../../stores/api.store';
|
||||||
|
import { DataStatus } from '../../types/api.types';
|
||||||
|
|
||||||
const globalStore = useGlobalStore();
|
const globalStore = useGlobalStore();
|
||||||
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
const viewModes: Record<typeof globalStore.viewMode, any> = {
|
const viewModes: Record<typeof globalStore.viewMode, any> = {
|
||||||
active: ActiveDataView,
|
active: ActiveDataView,
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
{{ globalStore.currentTimetableData!.route.replace('|', ' - ') }}
|
{{ globalStore.currentTimetableData!.route.replace('|', ' - ') }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<table class="table-fixed mt-2 w-full border-collapse" v-if="computedTimetableRows.length > 0">
|
<table
|
||||||
|
class="table-fixed mt-2 w-full border-collapse overflow-hidden"
|
||||||
|
v-if="computedTimetableRows.length > 0"
|
||||||
|
>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="40" class="border border-black dark:border-white">
|
<th width="40" class="border border-black dark:border-white">
|
||||||
@@ -15,7 +18,7 @@
|
|||||||
<th width="100" class="border border-black dark:border-white">
|
<th width="100" class="border border-black dark:border-white">
|
||||||
{{ $t('headers.line_km') }}
|
{{ $t('headers.line_km') }}
|
||||||
</th>
|
</th>
|
||||||
<th width="40" class="border border-black dark:border-white">V<sub>P</sub></th>
|
<th width="42" class="border border-black dark:border-white">V<sub>P</sub></th>
|
||||||
<th width="40" class="border border-black dark:border-white">V<sub>L</sub></th>
|
<th width="40" class="border border-black dark:border-white">V<sub>L</sub></th>
|
||||||
<th width="200" class="border border-black dark:border-white">
|
<th width="200" class="border border-black dark:border-white">
|
||||||
{{ $t('headers.station') }}
|
{{ $t('headers.station') }}
|
||||||
@@ -107,14 +110,14 @@
|
|||||||
class="align-top border-t text-inherit"
|
class="align-top border-t text-inherit"
|
||||||
:class="{
|
:class="{
|
||||||
'border-t-0 text-transparent':
|
'border-t-0 text-transparent':
|
||||||
row.lastRowRef == null ||
|
row.lastRowRef &&
|
||||||
(row.lastRowRef.departureSpeedL == row.arrivalSpeedL &&
|
row.lastRowRef.departureSpeedL == row.arrivalSpeedL &&
|
||||||
row.lastRowRef.departureSpeedP == row.arrivalSpeedP &&
|
row.lastRowRef.departureSpeedP == row.arrivalSpeedP &&
|
||||||
row.lastRowRef.departureTracks == row.arrivalTracks &&
|
row.lastRowRef.departureTracks == row.arrivalTracks &&
|
||||||
row.lastRowRef.arrivalLineNumber == row.arrivalLineNumber)
|
row.lastRowRef.arrivalLineNumber == row.arrivalLineNumber
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ row.arrivalKm }}
|
{{ row.arrivalKm }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -131,7 +134,7 @@
|
|||||||
row.departureSpeedP == row.arrivalSpeedP
|
row.departureSpeedP == row.arrivalSpeedP
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<td>{{ row.departureKm == '0.000' ? '' : row.departureKm }}</td>
|
<td> {{ row.departureKm }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -146,18 +149,24 @@
|
|||||||
}"
|
}"
|
||||||
colspan="2"
|
colspan="2"
|
||||||
>
|
>
|
||||||
|
<!-- Direction line arrow -->
|
||||||
|
<div
|
||||||
|
class="absolute h-0 w-0 border-x-transparent border-x-[6px] -left-[4px] border-t-[25px] -bottom-[12px] z-30 border-t-black dark:border-t-white print:border-t-black"
|
||||||
|
v-if="i == computedTimetableRows.length - 1"
|
||||||
|
></div>
|
||||||
|
|
||||||
<div class="absolute -top-[0.5px] left-0 w-full h-full">
|
<div class="absolute -top-[0.5px] left-0 w-full h-full">
|
||||||
<table class="h-full w-full border-collapse">
|
<table class="h-full w-full border-collapse">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="align-top">
|
<tr class="align-top">
|
||||||
<td
|
<td
|
||||||
:colspan="row.arrivalTracks == 2 ? '1' : '2'"
|
class="font-bold border-l-4 border-l-black dark:border-l-white"
|
||||||
:class="{
|
:class="{
|
||||||
'border-t border-t-black dark:border-t-white':
|
'border-t border-t-black dark:border-t-white':
|
||||||
row.lastRowRef != null &&
|
row.lastRowRef != null &&
|
||||||
row.lastRowRef.departureSpeedP != row.arrivalSpeedP
|
row.lastRowRef.departureSpeedP != row.arrivalSpeedP
|
||||||
}"
|
}"
|
||||||
class="font-bold"
|
:colspan="row.arrivalTracks == 2 ? '1' : '2'"
|
||||||
width="35"
|
width="35"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
@@ -190,6 +199,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr
|
<tr
|
||||||
|
class="border-l-4 border-l-black dark:border-l-white"
|
||||||
:class="{
|
:class="{
|
||||||
'border-t border-t-black dark:border-t-white align-top':
|
'border-t border-t-black dark:border-t-white align-top':
|
||||||
row.arrivalTracks != row.departureTracks ||
|
row.arrivalTracks != row.departureTracks ||
|
||||||
@@ -358,7 +368,12 @@
|
|||||||
<div>
|
<div>
|
||||||
- {{ parseTimetableRunDate(computedTimetableRows[0].scheduledDepartureDate!) }}
|
- {{ parseTimetableRunDate(computedTimetableRows[0].scheduledDepartureDate!) }}
|
||||||
<span
|
<span
|
||||||
v-if="computedTimetableRows[computedTimetableRows.length - 1].scheduledArrivalDate!.getDate() != computedTimetableRows[0].scheduledDepartureDate!.getDate()"
|
v-if="
|
||||||
|
computedTimetableRows[
|
||||||
|
computedTimetableRows.length - 1
|
||||||
|
].scheduledArrivalDate!.getDate() !=
|
||||||
|
computedTimetableRows[0].scheduledDepartureDate!.getDate()
|
||||||
|
"
|
||||||
>
|
>
|
||||||
-
|
-
|
||||||
{{
|
{{
|
||||||
@@ -658,10 +673,10 @@ function parseTimetablePath(path: string): TimetablePathData[] {
|
|||||||
|
|
||||||
const sceneryData = apiStore.sceneryData?.find((sc) => sc.name == sceneryName) ?? null;
|
const sceneryData = apiStore.sceneryData?.find((sc) => sc.name == sceneryName) ?? null;
|
||||||
const arrivalLineData = arrivalLine
|
const arrivalLineData = arrivalLine
|
||||||
? sceneryData?.routesInfo.find((rt) => rt.routeName == arrivalLine) ?? null
|
? (sceneryData?.routesInfo.find((rt) => rt.routeName == arrivalLine) ?? null)
|
||||||
: null;
|
: null;
|
||||||
const departureLineData = departureLine
|
const departureLineData = departureLine
|
||||||
? sceneryData?.routesInfo.find((rt) => rt.routeName == departureLine) ?? null
|
? (sceneryData?.routesInfo.find((rt) => rt.routeName == departureLine) ?? null)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
name="trains"
|
name="trains"
|
||||||
id="trains-select"
|
id="trains-select"
|
||||||
class="bg-zinc-800 p-1 rounded-md print:hidden w-full"
|
class="bg-zinc-800 p-1 rounded-md print:hidden w-full"
|
||||||
:disabled="apiStore.activeDataStatus != DataStatus.SUCCESS"
|
:disabled="apiStore.apiDataStatus != DataStatus.SUCCESS"
|
||||||
aria-label="Active train select"
|
aria-label="Active train select"
|
||||||
>
|
>
|
||||||
<option :value="null" disabled>
|
<option :value="null" disabled>
|
||||||
{{
|
{{
|
||||||
apiStore.activeDataStatus == DataStatus.LOADING
|
apiStore.apiDataStatus == DataStatus.LOADING
|
||||||
? $t('data-loading-text')
|
? $t('data-loading-text')
|
||||||
: $t('train-select-placeholder')
|
: $t('train-select-placeholder')
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -105,11 +105,10 @@ async function fetchJournalTimetables() {
|
|||||||
try {
|
try {
|
||||||
apiStore.journalDataStatus = DataStatus.LOADING;
|
apiStore.journalDataStatus = DataStatus.LOADING;
|
||||||
|
|
||||||
const response = (
|
const response = await apiStore.client.get<JournalTimetablesShortResponse>(
|
||||||
await apiStore.client!.get<JournalTimetablesShortResponse>('/api/getTimetables', {
|
'api/getTimetables',
|
||||||
params: fetchParams
|
fetchParams
|
||||||
})
|
);
|
||||||
).data;
|
|
||||||
|
|
||||||
apiStore.journalDataStatus = DataStatus.SUCCESS;
|
apiStore.journalDataStatus = DataStatus.SUCCESS;
|
||||||
apiStore.journalTimetablesData = response;
|
apiStore.journalTimetablesData = response;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="text-white">
|
<div class="text-white">
|
||||||
<h2 class="font-bold p-2 bg-zinc-700 mb-3 text-2xl flex items-center gap-2 justify-center flex-wrap">
|
<h2
|
||||||
|
class="font-bold p-2 bg-zinc-700 mb-3 text-2xl flex items-center gap-2 justify-center flex-wrap"
|
||||||
|
>
|
||||||
<HistoryIcon :size="25" />
|
<HistoryIcon :size="25" />
|
||||||
{{ $t('journal-preview-title') }}
|
{{ $t('journal-preview-title') }}
|
||||||
</h2>
|
</h2>
|
||||||
@@ -77,15 +79,10 @@ const globalStore = useGlobalStore();
|
|||||||
|
|
||||||
async function fetchTimetableDetails(id: number) {
|
async function fetchTimetableDetails(id: number) {
|
||||||
try {
|
try {
|
||||||
const response = (
|
const response = await apiStore.client.get<JournalTimetableDetailed[]>('api/getTimetables', {
|
||||||
await apiStore.client!.get<JournalTimetableDetailed[]>('/api/getTimetables', {
|
timetableId: id,
|
||||||
params: {
|
returnType: 'detailed'
|
||||||
timetableId: id,
|
});
|
||||||
hasStopsDetails: 1,
|
|
||||||
returnType: 'detailed'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
).data;
|
|
||||||
|
|
||||||
if (response.length > 0) globalStore.selectedJournalTimetable = response[0];
|
if (response.length > 0) globalStore.selectedJournalTimetable = response[0];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
export class HttpClient {
|
||||||
|
constructor(private readonly baseURL: string) {}
|
||||||
|
|
||||||
|
async get<T>(url: string, params?: Record<string, any>): Promise<T> {
|
||||||
|
const absoluteURL = new URL(this.baseURL + '/' + url);
|
||||||
|
|
||||||
|
if (params) {
|
||||||
|
Object.keys(params).forEach((key) => {
|
||||||
|
if (params[key] === undefined) return;
|
||||||
|
|
||||||
|
absoluteURL.searchParams.append(key, params[key]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await fetch(absoluteURL);
|
||||||
|
|
||||||
|
if (!data.ok) {
|
||||||
|
throw new Error(`Cannot fetch ${absoluteURL}: ${data.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.json();
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
-36
@@ -1,5 +1,3 @@
|
|||||||
import type { AxiosInstance } from 'axios';
|
|
||||||
import axios from 'axios';
|
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import {
|
import {
|
||||||
DataStatus,
|
DataStatus,
|
||||||
@@ -13,13 +11,28 @@ import type {
|
|||||||
SceneryData,
|
SceneryData,
|
||||||
VehicleData
|
VehicleData
|
||||||
} from '../types/common.types';
|
} from '../types/common.types';
|
||||||
|
import { HttpClient } from '../http';
|
||||||
|
|
||||||
let activeDataInterval = -1;
|
let activeDataInterval = -1;
|
||||||
|
|
||||||
|
// Base API URL
|
||||||
|
let baseURL = 'https://stacjownik.spythere.eu';
|
||||||
|
|
||||||
|
switch (import.meta.env.VITE_API_MODE) {
|
||||||
|
case 'development':
|
||||||
|
baseURL = 'http://localhost:3001';
|
||||||
|
break;
|
||||||
|
case 'mocking':
|
||||||
|
baseURL = 'http://localhost:3123';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
export const useApiStore = defineStore('api', {
|
export const useApiStore = defineStore('api', {
|
||||||
state() {
|
state() {
|
||||||
return {
|
return {
|
||||||
client: null as AxiosInstance | null,
|
client: new HttpClient(baseURL),
|
||||||
|
|
||||||
activeData: null as ActiveData | null,
|
activeData: null as ActiveData | null,
|
||||||
sceneryData: null as SceneryData[] | null,
|
sceneryData: null as SceneryData[] | null,
|
||||||
@@ -29,7 +42,7 @@ export const useApiStore = defineStore('api', {
|
|||||||
outdatedTimerId: -1,
|
outdatedTimerId: -1,
|
||||||
isActiveDataOutdated: false,
|
isActiveDataOutdated: false,
|
||||||
|
|
||||||
activeDataStatus: DataStatus.LOADING,
|
apiDataStatus: DataStatus.LOADING,
|
||||||
journalDataStatus: DataStatus.SUCCESS,
|
journalDataStatus: DataStatus.SUCCESS,
|
||||||
|
|
||||||
connectionMode: 'online' as 'online' | 'offline'
|
connectionMode: 'online' as 'online' | 'offline'
|
||||||
@@ -38,43 +51,33 @@ export const useApiStore = defineStore('api', {
|
|||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
async setupAPIData() {
|
async setupAPIData() {
|
||||||
if (this.client == null) {
|
|
||||||
let baseURL = 'https://stacjownik.spythere.eu';
|
|
||||||
|
|
||||||
switch (import.meta.env.VITE_API_MODE) {
|
|
||||||
case 'development':
|
|
||||||
baseURL = 'http://localhost:3001';
|
|
||||||
break;
|
|
||||||
case 'mocking':
|
|
||||||
baseURL = 'http://localhost:3123';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.client = axios.create({
|
|
||||||
baseURL
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clearInterval(activeDataInterval);
|
clearInterval(activeDataInterval);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.apiDataStatus = DataStatus.LOADING;
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
this.fetchSceneriesData(),
|
||||||
|
this.fetchVehiclesData(),
|
||||||
|
this.fetchActiveData()
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.apiDataStatus = DataStatus.SUCCESS;
|
||||||
|
} catch (error) {
|
||||||
|
this.apiDataStatus = DataStatus.ERROR;
|
||||||
|
console.log('Data fetching error: ', error);
|
||||||
|
}
|
||||||
|
|
||||||
activeDataInterval = setInterval(() => {
|
activeDataInterval = setInterval(() => {
|
||||||
this.fetchActiveData();
|
this.fetchActiveData();
|
||||||
}, 25000);
|
}, 25000);
|
||||||
|
|
||||||
this.fetchSceneriesData();
|
|
||||||
this.fetchVehiclesData();
|
|
||||||
|
|
||||||
await this.fetchActiveData();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchActiveData() {
|
async fetchActiveData() {
|
||||||
try {
|
try {
|
||||||
const response = (await this.client!.get<ActiveDataResponse>('/api/getActiveData')).data;
|
const response = await this.client.get<ActiveDataResponse>('api/getActiveData');
|
||||||
|
|
||||||
this.activeData = response;
|
this.activeData = response;
|
||||||
this.activeDataStatus = DataStatus.SUCCESS;
|
|
||||||
this.isActiveDataOutdated = false;
|
this.isActiveDataOutdated = false;
|
||||||
|
|
||||||
if (this.outdatedTimerId != -1) clearTimeout(this.outdatedTimerId);
|
if (this.outdatedTimerId != -1) clearTimeout(this.outdatedTimerId);
|
||||||
@@ -83,27 +86,30 @@ export const useApiStore = defineStore('api', {
|
|||||||
this.isActiveDataOutdated = true;
|
this.isActiveDataOutdated = true;
|
||||||
}, 60000);
|
}, 60000);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchSceneriesData() {
|
async fetchSceneriesData() {
|
||||||
try {
|
try {
|
||||||
const response = (await this.client!.get<SceneriesDataResponse>('/api/getSceneries')).data;
|
const response = await this.client.get<SceneriesDataResponse>('api/getSceneries');
|
||||||
|
|
||||||
this.sceneryData = response;
|
this.sceneryData = response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchVehiclesData() {
|
async fetchVehiclesData() {
|
||||||
try {
|
try {
|
||||||
const response = (await this.client!.get<VehiclesDataResponse>('/api/getVehicles')).data;
|
const response = await this.client.get<VehiclesDataResponse>('api/getVehiclesData');
|
||||||
|
|
||||||
this.vehiclesData = response;
|
this.vehiclesData = response.vehicles.map((v) => ({
|
||||||
|
...v,
|
||||||
|
group: response.vehicleGroups.find((g) => g.id == v.vehicleGroupsId)!
|
||||||
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+48
-7
@@ -1,12 +1,15 @@
|
|||||||
import type { ActiveData, JournalTimetableShort, SceneryData, VehicleData } from './common.types';
|
import type {
|
||||||
|
ActiveData,
|
||||||
|
JournalTimetableShort,
|
||||||
|
SceneryData,
|
||||||
|
VehicleGroup,
|
||||||
|
VehicleRestrictions
|
||||||
|
} from './common.types';
|
||||||
|
|
||||||
export type ActiveDataResponse = ActiveData;
|
/***
|
||||||
|
* API Data Status
|
||||||
|
* */
|
||||||
|
|
||||||
export type SceneriesDataResponse = SceneryData[];
|
|
||||||
|
|
||||||
export type JournalTimetablesShortResponse = JournalTimetableShort[];
|
|
||||||
|
|
||||||
export type VehiclesDataResponse = VehicleData[];
|
|
||||||
|
|
||||||
export enum DataStatus {
|
export enum DataStatus {
|
||||||
'INIT' = -1,
|
'INIT' = -1,
|
||||||
@@ -14,3 +17,41 @@ export enum DataStatus {
|
|||||||
'SUCCESS' = 1,
|
'SUCCESS' = 1,
|
||||||
'ERROR' = 2
|
'ERROR' = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Active Data API
|
||||||
|
* */
|
||||||
|
|
||||||
|
export type ActiveDataResponse = ActiveData;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Sceneries API
|
||||||
|
* */
|
||||||
|
|
||||||
|
export type SceneriesDataResponse = SceneryData[];
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Journal API
|
||||||
|
* */
|
||||||
|
|
||||||
|
export type JournalTimetablesShortResponse = JournalTimetableShort[];
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Vehicles API
|
||||||
|
* */
|
||||||
|
|
||||||
|
export interface VehiclesDataResponse {
|
||||||
|
vehicles: VehicleDataAPI[];
|
||||||
|
vehicleGroups: VehicleGroupAPI[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleDataAPI {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
cabinName?: string;
|
||||||
|
restrictions?: VehicleRestrictions;
|
||||||
|
vehicleGroupsId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VehicleGroupAPI extends VehicleGroup {}
|
||||||
|
|||||||
@@ -298,7 +298,6 @@ export interface VehicleData {
|
|||||||
group: VehicleGroup;
|
group: VehicleGroup;
|
||||||
cabinName?: string;
|
cabinName?: string;
|
||||||
restrictions?: VehicleRestrictions;
|
restrictions?: VehicleRestrictions;
|
||||||
simulatorVersion: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VehicleRestrictions {
|
export interface VehicleRestrictions {
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,6 @@ export default {
|
|||||||
},
|
},
|
||||||
darkMode: 'selector',
|
darkMode: 'selector',
|
||||||
plugins: [],
|
plugins: [],
|
||||||
purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
|
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"root":["./src/i18n.ts","./src/main.ts","./src/vite-env.d.ts","./src/mixins/useVehicleMixin.ts","./src/stores/api.store.ts","./src/stores/global.store.ts","./src/types/api.types.ts","./src/types/common.types.ts","./src/utils/dateUtils.ts","./src/utils/trainUtils.ts","./src/App.vue","./src/components/App/MainBottom.vue","./src/components/App/MainContainer.vue","./src/components/App/MigrateInfo.vue","./src/components/App/Navbar.vue","./src/components/App/SettingsCard.vue","./src/components/App/UpdatePrompt.vue","./src/components/Timetable/TimetableContainer.vue","./src/components/Timetable/TimetableContent.vue","./src/components/Timetable/TimetableContentCZ.vue","./src/components/Timetable/TimetableWarnings.vue","./src/components/TimetableSearch/ActiveSearchInput.vue","./src/components/TimetableSearch/JournalSearchInput.vue","./src/components/TimetableSearch/LocalSearchInput.vue","./src/components/TimetableSearch/SearchContainer.vue","./src/components/TimetableSearch/SearchModeActions.vue","./src/components/TimetableViews/ActiveDataView.vue","./src/components/TimetableViews/CurrentTimetableView.vue","./src/components/TimetableViews/JournalStorageView.vue","./src/components/TimetableViews/LocalStorageView.vue"],"version":"5.9.3"}
|
{"root":["./src/http.ts","./src/i18n.ts","./src/main.ts","./src/vite-env.d.ts","./src/mixins/useVehicleMixin.ts","./src/stores/api.store.ts","./src/stores/global.store.ts","./src/types/api.types.ts","./src/types/common.types.ts","./src/utils/dateUtils.ts","./src/utils/trainUtils.ts","./src/App.vue","./src/components/App/MainBottom.vue","./src/components/App/MainContainer.vue","./src/components/App/MigrateInfo.vue","./src/components/App/Navbar.vue","./src/components/App/SettingsCard.vue","./src/components/App/UpdatePrompt.vue","./src/components/Timetable/TimetableContainer.vue","./src/components/Timetable/TimetableContent.vue","./src/components/Timetable/TimetableContentCZ.vue","./src/components/Timetable/TimetableWarnings.vue","./src/components/TimetableSearch/ActiveSearchInput.vue","./src/components/TimetableSearch/JournalSearchInput.vue","./src/components/TimetableSearch/LocalSearchInput.vue","./src/components/TimetableSearch/SearchContainer.vue","./src/components/TimetableSearch/SearchModeActions.vue","./src/components/TimetableViews/ActiveDataView.vue","./src/components/TimetableViews/CurrentTimetableView.vue","./src/components/TimetableViews/JournalStorageView.vue","./src/components/TimetableViews/LocalStorageView.vue"],"version":"5.9.3"}
|
||||||
+2
-2
@@ -14,8 +14,8 @@ export default defineConfig({
|
|||||||
cleanupOutdatedCaches: true,
|
cleanupOutdatedCaches: true,
|
||||||
runtimeCaching: [
|
runtimeCaching: [
|
||||||
{
|
{
|
||||||
urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/(getSceneries|getVehicles)/i,
|
urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/(getSceneries|getVehiclesData)/i,
|
||||||
handler: 'NetworkFirst',
|
handler: 'StaleWhileRevalidate',
|
||||||
options: {
|
options: {
|
||||||
expiration: {
|
expiration: {
|
||||||
maxAgeSeconds: 3600
|
maxAgeSeconds: 3600
|
||||||
|
|||||||
@@ -1577,11 +1577,6 @@ async@^3.2.3:
|
|||||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
|
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
|
||||||
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
|
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
|
||||||
version "0.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
|
||||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
|
||||||
|
|
||||||
at-least-node@^1.0.0:
|
at-least-node@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
||||||
@@ -1606,15 +1601,6 @@ available-typed-arrays@^1.0.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
possible-typed-array-names "^1.0.0"
|
possible-typed-array-names "^1.0.0"
|
||||||
|
|
||||||
axios@^1.13.6:
|
|
||||||
version "1.13.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.13.6.tgz#c3f92da917dc209a15dd29936d20d5089b6b6c98"
|
|
||||||
integrity sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==
|
|
||||||
dependencies:
|
|
||||||
follow-redirects "^1.15.11"
|
|
||||||
form-data "^4.0.5"
|
|
||||||
proxy-from-env "^1.1.0"
|
|
||||||
|
|
||||||
babel-plugin-polyfill-corejs2@^0.4.10:
|
babel-plugin-polyfill-corejs2@^0.4.10:
|
||||||
version "0.4.13"
|
version "0.4.13"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz#7d445f0e0607ebc8fb6b01d7e8fb02069b91dd8b"
|
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz#7d445f0e0607ebc8fb6b01d7e8fb02069b91dd8b"
|
||||||
@@ -1774,13 +1760,6 @@ color-name@~1.1.4:
|
|||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
combined-stream@^1.0.8:
|
|
||||||
version "1.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
|
||||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
|
||||||
dependencies:
|
|
||||||
delayed-stream "~1.0.0"
|
|
||||||
|
|
||||||
commander@^2.20.0:
|
commander@^2.20.0:
|
||||||
version "2.20.3"
|
version "2.20.3"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||||
@@ -1901,11 +1880,6 @@ define-properties@^1.2.1:
|
|||||||
has-property-descriptors "^1.0.0"
|
has-property-descriptors "^1.0.0"
|
||||||
object-keys "^1.1.1"
|
object-keys "^1.1.1"
|
||||||
|
|
||||||
delayed-stream@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
|
||||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
|
||||||
|
|
||||||
didyoumean@^1.2.2:
|
didyoumean@^1.2.2:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
|
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
|
||||||
@@ -2164,11 +2138,6 @@ fill-range@^7.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
to-regex-range "^5.0.1"
|
to-regex-range "^5.0.1"
|
||||||
|
|
||||||
follow-redirects@^1.15.11:
|
|
||||||
version "1.15.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340"
|
|
||||||
integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==
|
|
||||||
|
|
||||||
for-each@^0.3.3, for-each@^0.3.5:
|
for-each@^0.3.3, for-each@^0.3.5:
|
||||||
version "0.3.5"
|
version "0.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47"
|
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47"
|
||||||
@@ -2192,17 +2161,6 @@ foreground-child@^3.3.1:
|
|||||||
cross-spawn "^7.0.6"
|
cross-spawn "^7.0.6"
|
||||||
signal-exit "^4.0.1"
|
signal-exit "^4.0.1"
|
||||||
|
|
||||||
form-data@^4.0.5:
|
|
||||||
version "4.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.5.tgz#b49e48858045ff4cbf6b03e1805cebcad3679053"
|
|
||||||
integrity sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==
|
|
||||||
dependencies:
|
|
||||||
asynckit "^0.4.0"
|
|
||||||
combined-stream "^1.0.8"
|
|
||||||
es-set-tostringtag "^2.1.0"
|
|
||||||
hasown "^2.0.2"
|
|
||||||
mime-types "^2.1.12"
|
|
||||||
|
|
||||||
fraction.js@^4.3.7:
|
fraction.js@^4.3.7:
|
||||||
version "4.3.7"
|
version "4.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
||||||
@@ -2794,18 +2752,6 @@ micromatch@^4.0.8:
|
|||||||
braces "^3.0.3"
|
braces "^3.0.3"
|
||||||
picomatch "^2.3.1"
|
picomatch "^2.3.1"
|
||||||
|
|
||||||
mime-db@1.52.0:
|
|
||||||
version "1.52.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
|
||||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
|
||||||
|
|
||||||
mime-types@^2.1.12:
|
|
||||||
version "2.1.35"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
|
||||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
|
||||||
dependencies:
|
|
||||||
mime-db "1.52.0"
|
|
||||||
|
|
||||||
minimatch@^10.1.1:
|
minimatch@^10.1.1:
|
||||||
version "10.2.4"
|
version "10.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.4.tgz#465b3accbd0218b8281f5301e27cedc697f96fde"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.4.tgz#465b3accbd0218b8281f5301e27cedc697f96fde"
|
||||||
@@ -3079,11 +3025,6 @@ pretty-bytes@^6.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz#38cd6bb46f47afbf667c202cfc754bffd2016a3b"
|
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz#38cd6bb46f47afbf667c202cfc754bffd2016a3b"
|
||||||
integrity sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==
|
integrity sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==
|
||||||
|
|
||||||
proxy-from-env@^1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
|
||||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
|
||||||
|
|
||||||
punycode@^2.1.0:
|
punycode@^2.1.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||||
|
|||||||
Reference in New Issue
Block a user