Skip to content

Commit

Permalink
build: fix types; improve build
Browse files Browse the repository at this point in the history
  • Loading branch information
Apkawa committed Feb 12, 2024
1 parent c86a4f2 commit e8c37eb
Show file tree
Hide file tree
Showing 31 changed files with 3,376 additions and 470 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,6 @@ jobs:
uses: JamesIves/github-pages-deploy-action@v4
with:
# Потом когда сделаю версию на vue то поменяю на apps/web/dist/
folder: apps/mvp/dist # The folder the action should deploy.
folder: apps/web/dist # The folder the action should deploy.
clean: true # Automatically remove deleted files from the deploy branch
target-folder: ${{ steps.target_folder.outputs.value }}
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@
- [ ] i18n, начальный язык - русский
- [ ] Браузерные расширения
- [ ] Телеграм бот \
https://github.com/revenkroz/telegram-web-app-bot-example

https://github.com/revenkroz/telegram-web-app-bot-example

## Обратная связь

Expand Down
2 changes: 1 addition & 1 deletion apps/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@
- [ ] e2e
- [ ] Пишем интерфейс и его элементы в [storybook](https://storybook.js.org/docs/vue/get-started/introduction)
- [ ] e2e в [storybook](https://storybook.js.org/docs/vue/writing-tests/introduction) + nightwatch \
https://nightwatchjs.org/blog/component-driven-development-with-storybook-and-nightwatch/
https://nightwatchjs.org/blog/component-driven-development-with-storybook-and-nightwatch/
- [ ] Браузерные расширения
10 changes: 4 additions & 6 deletions apps/web/env.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
/// <reference types="vite/client" />


export type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;
type DeepWriteable<T> = { -readonly [P in keyof T]: DeepWriteable<T[P]> };
export type ArrayElement<A> = A extends readonly (infer T)[] ? T : never
type DeepWriteable<T> = { -readonly [P in keyof T]: DeepWriteable<T[P]> }
type Cast<X, Y> = X extends Y ? X : Y
type FromEntries<T> = T extends [infer Key, any][]
? { [K in Cast<Key, string>]: Extract<ArrayElement<T>, [K, any]>[1]}
? { [K in Cast<Key, string>]: Extract<ArrayElement<T>, [K, any]>[1] }
: { [key in string]: any }

export type FromEntriesWithReadOnly<T> = FromEntries<DeepWriteable<T>>


declare global {
interface ObjectConstructor {
fromEntries<T>(obj: T): FromEntriesWithReadOnly<T>
}
}
}
4 changes: 2 additions & 2 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"test": "npm run test:unit",
"test:unit": "vitest",
"test:unit": "vitest run",
"test:e2e": "nightwatch tests/e2e/*",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"lint": "eslint ./src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/",
"dev:storybook": "storybook dev -p 6006",
"build:storybook": "storybook build",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/RecipeCalculator/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ export const EXAMPLE_RECIPE = `
Морковь 1 cup
Редис 2 cup
Зеленый лук 8 шт
`;
`
4 changes: 1 addition & 3 deletions apps/web/src/components/RecipeCalculator/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import RecipeCalculator from './RecipeCalculator.vue'

export {
RecipeCalculator
}
export { RecipeCalculator }
84 changes: 43 additions & 41 deletions apps/web/src/components/RecipeCalculator/state.ts
Original file line number Diff line number Diff line change
@@ -1,97 +1,99 @@
import {EXAMPLE_RECIPE} from './constants';
import { EXAMPLE_RECIPE } from './constants'

export interface RecipeState {
rawRecipe: string,
scale: number,
newScale: number,
rawRecipe: string
scale: number
newScale: number
}

const RecipeStateDefaults: RecipeState = {
rawRecipe: EXAMPLE_RECIPE,
scale: 1,
newScale: 1,
};
newScale: 1
}

const RECIPE_STATE_KEYS = Object.keys(RecipeStateDefaults) as (keyof RecipeState)[];
const RECIPE_STATE_KEYS = Object.keys(RecipeStateDefaults) as (keyof RecipeState)[]

// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem.
export function base64ToBytes(base64: string): string {
const binString = atob(base64);
const binString = atob(base64)
// @ts-ignore
const buffer = Uint8Array.from(binString, (m) => m.codePointAt(0));
return new TextDecoder().decode(buffer);
const buffer = Uint8Array.from(binString, (m) => m.codePointAt(0))
return new TextDecoder().decode(buffer)
}

// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem.
export function bytesToBase64(bytes: string): string {
const binString = String.fromCodePoint(...new TextEncoder().encode(bytes));
return btoa(binString);
const binString = String.fromCodePoint(...new TextEncoder().encode(bytes))
return btoa(binString)
}

const removeUndefinedValuesFromObject = <T extends object>(obj: T): T => {
// @ts-ignore
Object.keys(obj).forEach((key) => obj[key] === undefined && delete obj[key]);
return obj;
};
Object.keys(obj).forEach((key) => obj[key] === undefined && delete obj[key])
return obj
}

type PartialRecipeState = Record<keyof RecipeState, string | undefined>

export function loadStateFromUrl(url: URL): PartialRecipeState {
const obj = Object.fromEntries(RECIPE_STATE_KEYS.map(key => [key, url.searchParams.get(key) || undefined]));
const obj = Object.fromEntries(
RECIPE_STATE_KEYS.map((key) => [key, url.searchParams.get(key) || undefined])
)
if (obj['rawRecipe']) {
obj.rawRecipe = base64ToBytes(obj.rawRecipe);
obj.rawRecipe = base64ToBytes(obj.rawRecipe)
}
return obj as PartialRecipeState;
return obj as PartialRecipeState
}

export function loadStateFromLocalStorage(): PartialRecipeState {
return Object.fromEntries(
RECIPE_STATE_KEYS.map(key => [key, localStorage.getItem(key) || undefined]),
) as PartialRecipeState;
RECIPE_STATE_KEYS.map((key) => [key, localStorage.getItem(key) || undefined])
) as PartialRecipeState
}


export function loadState(): RecipeState {
const urlState = removeUndefinedValuesFromObject(loadStateFromUrl(new URL(window.location.toString())));
const storageState = removeUndefinedValuesFromObject(loadStateFromLocalStorage());
const urlState = removeUndefinedValuesFromObject(
loadStateFromUrl(new URL(window.location.toString()))
)
const storageState = removeUndefinedValuesFromObject(loadStateFromLocalStorage())

const state = {...RecipeStateDefaults, ...storageState, ...urlState};
const state = { ...RecipeStateDefaults, ...storageState, ...urlState }

return {
rawRecipe: state.rawRecipe || RecipeStateDefaults.rawRecipe,
scale: Number.parseInt((state.scale || RecipeStateDefaults.scale).toString()),
newScale: Number.parseInt((state.newScale || RecipeStateDefaults.newScale).toString())

}
}

export function saveStateToUrl(url: URL, state: RecipeState): URL {
const _url = new URL(url.toString());
RECIPE_STATE_KEYS.map(key => {
let v = state[key];
const _url = new URL(url.toString())
RECIPE_STATE_KEYS.map((key) => {
let v = state[key]
if (v) {
if (key == 'rawRecipe') {
v = bytesToBase64(v.toString());
v = bytesToBase64(v.toString())
} else {
v = v.toString();
v = v.toString()
}
_url.searchParams.set(key, v);
_url.searchParams.set(key, v)
}
});
return _url;
})
return _url
}

export function saveStateLocalStorage(state: RecipeState): void {
RECIPE_STATE_KEYS.map(key => {
const v = state[key];
RECIPE_STATE_KEYS.map((key) => {
const v = state[key]
if (v) {
localStorage.setItem(key, v.toString());
localStorage.setItem(key, v.toString())
}
});
})
}

export function saveState(state: RecipeState): void {
const url = saveStateToUrl(new URL(window.location.toString()), state);
window.history.replaceState('', '', url.toString());
saveStateLocalStorage(state);
}
const url = saveStateToUrl(new URL(window.location.toString()), state)
window.history.replaceState('', '', url.toString())
saveStateLocalStorage(state)
}
8 changes: 4 additions & 4 deletions apps/web/src/components/RecipeCalculator/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export function valueDisplay(value?: number | number[]): string {
let v = '';
let v = ''
if (value) {
v = value.toString();
v = value.toString()
if (Array.isArray(value)) {
v = value.join(' - ');
v = value.join(' - ')
}
}
return v;
return v
}
4 changes: 2 additions & 2 deletions apps/web/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {createRouter, createWebHashHistory} from 'vue-router';
import HomeView from '../views/HomeView.vue';
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
Expand Down
5 changes: 3 additions & 2 deletions apps/web/tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"include": [
"env.d.ts",
"src/**/*",
"src/**/*.vue"
"src/**/*.vue",
"../../node_modules/@vue/runtime-core/dist/runtime-core.d.ts"
],
"exclude": [
"src/**/__tests__/*"
Expand All @@ -18,6 +19,6 @@
"./src/*"
]
},
"verbatimModuleSyntax": false,
"verbatimModuleSyntax": false
}
}
10 changes: 5 additions & 5 deletions apps/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import nightwatchPlugin from 'vite-plugin-nightwatch'
import { ViteFaviconsPlugin } from 'vite-plugin-favicon2';
import { ViteFaviconsPlugin } from 'vite-plugin-favicon2'
import checker from 'vite-plugin-checker'



// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(), vueJsx(), nightwatchPlugin(),
checker({typescript: true}),
vue(),
vueJsx(),
nightwatchPlugin(),
checker({ typescript: true }),
ViteFaviconsPlugin('./public/food_recipe_calculator_icon.png')
],
resolve: {
Expand Down
Loading

0 comments on commit e8c37eb

Please sign in to comment.