[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] branch master updated: some fixes
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] branch master updated: some fixes |
Date: |
Tue, 27 Apr 2021 14:58:55 +0200 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository merchant-backoffice.
The following commit(s) were added to refs/heads/master by this push:
new c9b0e41 some fixes
c9b0e41 is described below
commit c9b0e41116d3347c844ac00bda401e84d67ffd4d
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue Apr 27 09:57:09 2021 -0300
some fixes
---
CHANGELOG.md | 1 +
packages/frontend/.gitignore | 1 +
packages/frontend/.storybook/main.js | 9 +-
packages/frontend/.storybook/preview.js | 1 +
packages/frontend/package.json | 12 +-
packages/frontend/src/InstanceRoutes.tsx | 60 ++--
.../src/components/form/InputSearchProduct.tsx | 34 ++-
.../src/components/form/InputSecured.stories.tsx | 10 +-
.../frontend/src/components/form/InputStock.tsx | 16 +-
.../src/components/product/ProductForm.tsx | 9 +-
.../src/components/product/ProductList.tsx | 9 +-
packages/frontend/src/hooks/backend.ts | 36 ++-
packages/frontend/src/messages/en.po | 3 +
.../paths/instance/orders/create/CreatePage.tsx | 6 +-
.../orders/create/InventoryProductForm.tsx | 39 +--
.../orders/create/NonInventoryProductForm.tsx | 88 +++++-
.../src/paths/instance/orders/create/index.tsx | 8 +-
.../paths/instance/orders/details/DetailPage.tsx | 30 +-
.../src/paths/instance/orders/details/Timeline.tsx | 27 +-
.../paths/instance/products/create/CreatePage.tsx | 2 +-
.../src/paths/instance/products/create/index.tsx | 12 +-
.../src/paths/instance/products/list/Table.tsx | 40 ++-
.../frontend/src/paths/instance/update/index.tsx | 2 +-
packages/frontend/src/schemas/index.ts | 11 +-
.../frontend/tests/__mocks__/fileTransformer.js | 9 +
packages/frontend/tests/stories.test.tsx | 37 +++
pnpm-lock.yaml | 323 ++++++++++++++++++---
27 files changed, 642 insertions(+), 193 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5d7b60d..b2df239 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0
- product detail: we could have some button that brings us to the detailed
screen for the product
- navigation to another instance should not do full refresh
- cleanup instance and token management, because code is a mess and can be
refactored
+
## [Unreleased]
- fixed bug when updating token and not admin
- showing a yellow bar on non-default instance navigation (admin)
diff --git a/packages/frontend/.gitignore b/packages/frontend/.gitignore
index 71f7c3d..df14910 100644
--- a/packages/frontend/.gitignore
+++ b/packages/frontend/.gitignore
@@ -3,3 +3,4 @@
/storybook-static
/docs
/single
+/coverage
diff --git a/packages/frontend/.storybook/main.js
b/packages/frontend/.storybook/main.js
index 7dc5cc2..6e3ec15 100644
--- a/packages/frontend/.storybook/main.js
+++ b/packages/frontend/.storybook/main.js
@@ -14,10 +14,10 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
- /**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
module.exports = {
@@ -34,7 +34,6 @@ module.exports = {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
-
// Make whatever fine-grained changes you need
config.module.rules.push({
test: [/\.pot?$/, /\.mo$/],
diff --git a/packages/frontend/.storybook/preview.js
b/packages/frontend/.storybook/preview.js
index 012e9f8..7330bbe 100644
--- a/packages/frontend/.storybook/preview.js
+++ b/packages/frontend/.storybook/preview.js
@@ -47,6 +47,7 @@ export const globalTypes = {
export const decorators = [
(Story, { globals }) => {
+
return <MessageProvider locale={globals.locale} onError="warn"
messages={messages[globals.locale]} pathSep={null} onError={() => null}>
<Story />
</MessageProvider>
diff --git a/packages/frontend/package.json b/packages/frontend/package.json
index 34eff24..02e598b 100644
--- a/packages/frontend/package.json
+++ b/packages/frontend/package.json
@@ -94,6 +94,7 @@
"messageformat-po-loader": "^0.3.0",
"node-sass": "^5.0.0",
"preact-cli": "^3.0.5",
+ "preact-render-to-json": "^3.6.6",
"preact-render-to-string": "^5.1.16",
"rimraf": "^3.0.2",
"sass-loader": "10.1.1",
@@ -107,6 +108,13 @@
"setupFiles": [
"<rootDir>/tests/__mocks__/browserMocks.ts",
"<rootDir>/tests/__mocks__/setupTests.ts"
- ]
+ ],
+ "collectCoverage": true,
+ "moduleNameMapper": {
+ "\\.(css|less)$": "identity-obj-proxy"
+ },
+ "transform": {
+
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|po)$":
"<rootDir>/tests/__mocks__/fileTransformer.js"
+ }
}
-}
+}
\ No newline at end of file
diff --git a/packages/frontend/src/InstanceRoutes.tsx
b/packages/frontend/src/InstanceRoutes.tsx
index eabf463..aa97914 100644
--- a/packages/frontend/src/InstanceRoutes.tsx
+++ b/packages/frontend/src/InstanceRoutes.tsx
@@ -23,7 +23,7 @@ import { createHashHistory } from 'history';
import { Fragment, FunctionComponent, h, VNode } from 'preact';
import { useMessageTemplate } from 'preact-messages';
import { Route, route, Router } from 'preact-router';
-import { useCallback, useEffect, useMemo } from "preact/hooks";
+import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
import { Loading } from './components/exception/loading';
import { NotificationCard } from './components/menu';
import { InstanceContextProvider, useBackendContext } from './context/backend';
@@ -41,10 +41,11 @@ import TransferListPage from
'./paths/instance/transfers/list';
import InstanceUpdatePage, { Props as InstanceUpdatePageProps } from
"./paths/instance/update";
import LoginPage from './paths/login';
import NotFoundPage from './paths/notfound';
-
+import { Notification } from './utils/types';
export enum InstancePaths {
// details = '/',
+ error = '/error',
update = '/update',
product_list = '/products',
@@ -64,7 +65,7 @@ export enum InstancePaths {
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
-const noop = () => {}
+const noop = () => { }
export enum AdminPaths {
list_instances = '/instances',
@@ -83,6 +84,7 @@ export function InstanceRoutes({ id, admin }: Props): VNode {
const { changeBackend, addTokenCleaner } = useBackendContext();
const cleaner = useCallback(() => { updateToken(undefined); }, [id]);
const i18n = useMessageTemplate('');
+ const [globalNotification, setGlobalNotification] = useState<Notification &
{to:string} | undefined>(undefined)
useEffect(() => {
addTokenCleaner(cleaner);
@@ -100,10 +102,15 @@ export function InstanceRoutes({ id, admin }: Props):
VNode {
const value = useMemo(() => ({ id, token, admin }), [id, token, admin])
- const LoginPageServerError = (error: HttpError) => <Fragment>
- <NotificationCard notification={{ message: `Server reported a problem:
HTTP status #${error.status}`, description: `Got message: ${error.message}
from: ${error.info?.url}`, type: 'ERROR' }} />
- <LoginPage onConfirm={updateLoginStatus} />
- </Fragment>
+ const ServerErrorRedirectTo = (to: InstancePaths | AdminPaths) => (error:
HttpError) => {
+ setGlobalNotification({
+ message: `HTTP status #${error.status}: Server reported a problem`,
+ description: `Got message: "${error.message}" from: ${error.info?.url}`,
+ type: 'ERROR',
+ to
+ })
+ return <Redirect to={to} />
+ }
const LoginPageAccessDenied = () => <Fragment>
<NotificationCard notification={{ message: i18n`Access denied`,
description: i18n`Check your token is valid`, type: 'ERROR', }} />
@@ -126,14 +133,23 @@ export function InstanceRoutes({ id, admin }: Props):
VNode {
}
if (props) {
return <Next {...props} />
- }
- return <Next />
-
+ }
+ return <Next />
+
}
}
return <InstanceContextProvider value={value}>
- <Router history={createHashHistory()}>
+
+ <NotificationCard notification={globalNotification} />
+
+ <Router history={createHashHistory()} onChange={(e) => {
+ const movingOutFromNotification = globalNotification && e.url !==
globalNotification.to
+ if (movingOutFromNotification) {
+ setGlobalNotification(undefined)
+ }
+ }} >
+
<Route path="/" component={Redirect} to={InstancePaths.order_list} />
{/**
@@ -144,7 +160,7 @@ export function InstanceRoutes({ id, admin }: Props): VNode
{
onCreate={() => { route(AdminPaths.new_instance) }}
onUpdate={(id: string): void => { route(`/instance/${id}/update`); }}
onUnauthorized={LoginPageAccessDenied}
- onLoadError={LoginPageServerError}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
/>
}
@@ -159,7 +175,8 @@ export function InstanceRoutes({ id, admin }: Props): VNode
{
<Route path={AdminPaths.update_instance}
component={AdminInstanceUpdatePage}
onBack={() => route(AdminPaths.list_instances)}
onConfirm={() => { route(AdminPaths.list_instances); }}
- onUpdateError={noop}
+ onUpdateError={ServerErrorRedirectTo(AdminPaths.list_instances)}
+ onLoadError={ServerErrorRedirectTo(AdminPaths.list_instances)}
onNotFound={NotFoundPage}
/>
}
@@ -173,7 +190,7 @@ export function InstanceRoutes({ id, admin }: Props): VNode
{
onUpdateError={noop}
onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onUnauthorized={LoginPageAccessDenied}
- onLoadError={LoginPageServerError}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
/>
{/**
@@ -181,19 +198,22 @@ export function InstanceRoutes({ id, admin }: Props):
VNode {
*/}
<Route path={InstancePaths.product_list} component={ProductListPage}
onUnauthorized={LoginPageAccessDenied}
- onLoadError={LoginPageServerError}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
onCreate={() => { route(InstancePaths.product_new) }}
onSelect={(id: string) => {
route(InstancePaths.product_update.replace(':pid', id)) }}
onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
<Route path={InstancePaths.product_update} component={ProductUpdatePage}
onUnauthorized={LoginPageAccessDenied}
- onLoadError={LoginPageServerError}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.product_list)}
onConfirm={() => { route(InstancePaths.product_list); }}
onBack={() => { route(InstancePaths.product_list); }}
onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
- <Route path={InstancePaths.product_new} component={ProductCreatePage}
+ <Route path={InstancePaths.product_new}
+ component={ProductCreatePage}
+ onConfirm={() => { route(InstancePaths.product_list); }}
+ onBack={() => { route(InstancePaths.product_list); }}
/>
{/**
@@ -203,12 +223,12 @@ export function InstanceRoutes({ id, admin }: Props):
VNode {
onCreate={() => { route(InstancePaths.order_new) }}
onSelect={(id: string) => {
route(InstancePaths.order_details.replace(':oid', id)) }}
onUnauthorized={LoginPageAccessDenied}
- onLoadError={LoginPageServerError}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
<Route path={InstancePaths.order_details} component={OrderDetailsPage}
onUnauthorized={LoginPageAccessDenied}
- onLoadError={LoginPageServerError}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.order_list)}
onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
onBack={() => { route(InstancePaths.order_list) }}
/>
@@ -222,7 +242,7 @@ export function InstanceRoutes({ id, admin }: Props): VNode
{
*/}
<Route path={InstancePaths.transfers_list} component={TransferListPage}
onUnauthorized={LoginPageAccessDenied}
- onLoadError={LoginPageServerError}
+ onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
/>
diff --git a/packages/frontend/src/components/form/InputSearchProduct.tsx
b/packages/frontend/src/components/form/InputSearchProduct.tsx
index 1bdc94f..3dbbcf7 100644
--- a/packages/frontend/src/components/form/InputSearchProduct.tsx
+++ b/packages/frontend/src/components/form/InputSearchProduct.tsx
@@ -24,6 +24,7 @@ import { InputWithAddon } from "./InputWithAddon";
import { FormErrors, FormProvider, useField } from "./Field";
import { useInstanceProducts } from "../../hooks/product";
import { useState } from "preact/hooks";
+import emptyImage from "../../assets/empty.png";
type Entity = MerchantBackend.Products.ProductDetail & WithId
@@ -47,13 +48,13 @@ export function InputSearchProduct<T>({ selected, onChange
}: Props) {
return <article class="media">
<figure class="media-left">
<p class="image is-128x128">
- <img src="https://avatars.dicebear.com/v2/gridy/Ms.-Lora-Kiehn.svg"
/>
+ <img src={selected.image ? selected.image : emptyImage} />
</p>
</figure>
<div class="media-content">
<div class="content">
- <p class="media-meta">Product #{selected.id}</p>
- <p>{selected.description}</p>
+ <p class="media-meta">Product id: <b>{selected.id}</b></p>
+ <p>Description: {selected.description}</p>
<div class="buttons is-right mt-5">
<button class="button" onClick={() =>
onChange(undefined)}>clear</button>
</div>
@@ -64,7 +65,7 @@ export function InputSearchProduct<T>({ selected, onChange }:
Props) {
return <FormProvider<ProductSearch> errors={errors} object={prodForm}
valueHandler={setProdName} >
- <InputWithAddon<ProductSearch>
+ <InputWithAddon<ProductSearch>
name="name"
addonBefore={<span class="icon" ><i class="mdi mdi-magnify" /></span>}
>
@@ -102,17 +103,30 @@ function ProductList({ name, onSelect }:
ProductListProps) {
</div>
</div>
} else {
+ const filtered = result.data.filter(p => re.test(p.id) ||
re.test(p.description))
products = <div class="dropdown-content">
- {result.data.filter(p => re.test(p.description)).map(p => (
- <div class="dropdown-item" onClick={() => onSelect(p)}>
- {p.description}
- </div>
- ))}
+ {!filtered.length ?
+ <div class="dropdown-item" >
+ no results
+ </div> :
+ result.data.filter(p => re.test(p.id) ||
re.test(p.description)).map(p => (
+ <div class="dropdown-item" onClick={() => onSelect(p)} style={{
cursor: 'pointer' }}>
+ <table>
+ <tr>
+ <td style={{width:32}}>
+ <div class="image" style={{minWidth:32}}><img
src={p.image} style={{ width: 32, height: 32 }} /></div>
+ </td>
+ <td><b>{p.id}</b>: {p.description}</td>
+ </tr>
+ </table>
+ </div>
+ ))
+ }
</div>
}
}
return <div class="dropdown is-active">
- <div class="dropdown-menu" id="dropdown-menu" role="menu">
+ <div class="dropdown-menu" id="dropdown-menu" role="menu"
style={{minWidth: '20rem'}}>
{products}
</div>
</div>
diff --git a/packages/frontend/src/components/form/InputSecured.stories.tsx
b/packages/frontend/src/components/form/InputSecured.stories.tsx
index a83036a..9ec3bee 100644
--- a/packages/frontend/src/components/form/InputSecured.stories.tsx
+++ b/packages/frontend/src/components/form/InputSecured.stories.tsx
@@ -28,13 +28,11 @@ export default {
title: 'Fields/InputSecured',
component: InputSecured,
};
-{/* <FormProvider<Entity> errors={errors} object={value}
valueHandler={valueHandler} > */ }
-{/* <InputSecured<Entity> name="auth_token" /> */ }
-type T = {auth_token: string | null}
+type T = { auth_token: string | null }
export const InitialValueEmpty = () => {
- const [state, setState] = useState<Partial<T>>({auth_token: ''})
+ const [state, setState] = useState<Partial<T>>({ auth_token: '' })
return <FormProvider<T> object={state} errors={{}} valueHandler={setState}>
Initial value: ''
<InputSecured<T> name="auth_token" />
@@ -42,14 +40,14 @@ export const InitialValueEmpty = () => {
}
export const InitialValueToken = () => {
- const [state, setState] = useState<Partial<T>>({auth_token: 'token'})
+ const [state, setState] = useState<Partial<T>>({ auth_token: 'token' })
return <FormProvider<T> object={state} errors={{}} valueHandler={setState}>
<InputSecured<T> name="auth_token" />
</FormProvider>
}
export const InitialValueNull = () => {
- const [state, setState] = useState<Partial<T>>({auth_token: null})
+ const [state, setState] = useState<Partial<T>>({ auth_token: null })
return <FormProvider<T> object={state} errors={{}} valueHandler={setState}>
Initial value: ''
<InputSecured<T> name="auth_token" />
diff --git a/packages/frontend/src/components/form/InputStock.tsx
b/packages/frontend/src/components/form/InputStock.tsx
index 50307b6..f9c9c10 100644
--- a/packages/frontend/src/components/form/InputStock.tsx
+++ b/packages/frontend/src/components/form/InputStock.tsx
@@ -62,13 +62,15 @@ export function InputStock<T>({ name, readonly,
alreadyExist }: Props<T>) {
const [addedStock, setAddedStock] = useState<StockDelta>({ incoming: 0,
lost: 0 })
useLayoutEffect(() => {
- console.log(formValue)
-
- onChange({
- ...formValue,
- current: (formValue?.current || 0) + addedStock.incoming,
- lost: (formValue?.lost || 0) + addedStock.lost
- } as any)
+ if (!formValue) {
+ onChange(undefined as any)
+ } else {
+ onChange({
+ ...formValue,
+ current: (formValue?.current || 0) + addedStock.incoming,
+ lost: (formValue?.lost || 0) + addedStock.lost
+ } as any)
+ }
}, [formValue, addedStock])
if (!formValue) {
diff --git a/packages/frontend/src/components/product/ProductForm.tsx
b/packages/frontend/src/components/product/ProductForm.tsx
index af5eed0..8ed6436 100644
--- a/packages/frontend/src/components/product/ProductForm.tsx
+++ b/packages/frontend/src/components/product/ProductForm.tsx
@@ -56,8 +56,8 @@ export function ProductForm({ onSubscribe, initial,
alreadyExist, }: Props) {
const submit = useCallback((): Entity | undefined => {
try {
- (alreadyExist ? updateSchema : createSchema).validateSync(value, {
abortEarly: false })
- const stock:Stock = (value as any).stock;
+ (alreadyExist ? updateSchema : createSchema).validateSync(value, {
abortEarly: false })
+ const stock: Stock = (value as any).stock;
delete (value as any).stock;
if (!stock) {
@@ -68,7 +68,6 @@ export function ProductForm({ onSubscribe, initial,
alreadyExist, }: Props) {
value.next_restock = stock.nextRestock instanceof Date ? { t_ms:
stock.nextRestock.getTime() } : stock.nextRestock;
value.address = stock.address;
}
- console.log(value)
return value as MerchantBackend.Products.ProductDetail & { product_id:
string }
} catch (err) {
const errors = err.inner as yup.ValidationError[]
@@ -86,8 +85,8 @@ export function ProductForm({ onSubscribe, initial,
alreadyExist, }: Props) {
return <div>
<FormProvider<Entity> name="product" errors={errors} object={value}
valueHandler={valueHandler} >
- {alreadyExist ? undefined : <InputWithAddon<Entity> name="product_id"
addonBefore={`${backend.url}/product/`} /> }
-
+ {alreadyExist ? undefined : <InputWithAddon<Entity> name="product_id"
addonBefore={`${backend.url}/product/`} />}
+
<InputImage<Entity> name="image" />
<Input<Entity> name="description" inputType="multiline" />
<Input<Entity> name="unit" />
diff --git a/packages/frontend/src/components/product/ProductList.tsx
b/packages/frontend/src/components/product/ProductList.tsx
index b313cf5..a62fd01 100644
--- a/packages/frontend/src/components/product/ProductList.tsx
+++ b/packages/frontend/src/components/product/ProductList.tsx
@@ -16,6 +16,7 @@
import { h, VNode } from "preact"
import { MerchantBackend } from "../../declaration"
import { multiplyPrice } from "../../utils/amount"
+import emptyImage from "../../assets/empty.png";
interface Props {
list: MerchantBackend.Product[],
@@ -40,16 +41,18 @@ export function ProductList({ list, actions = [] }: Props):
VNode {
<tbody>
{list.map((entry, index) => {
return <tr>
- <td>image</td>
+ <td>
+ <img style={{ height: 32, width: 32 }} src={entry.image ?
entry.image : emptyImage} />
+ </td>
<td >{entry.description}</td>
<td >
- {entry.quantity} {entry.unit}
+ {entry.quantity === 0 ? '--' : `${entry.quantity} ${entry.unit}`}
</td>
<td >{entry.price}</td>
<td >{multiplyPrice(entry.price, entry.quantity)}</td>
<td class="is-actions-cell right-sticky">
{actions.map(a => {
- <div class="buttons is-right">
+ return <div class="buttons is-right">
<button class="button is-small is-danger jb-modal"
type="button" onClick={() => a.handler(entry, index)}>
{a.name}
</button>
diff --git a/packages/frontend/src/hooks/backend.ts
b/packages/frontend/src/hooks/backend.ts
index f9466a0..94c26e2 100644
--- a/packages/frontend/src/hooks/backend.ts
+++ b/packages/frontend/src/hooks/backend.ts
@@ -27,7 +27,6 @@ import { useEffect, useState } from 'preact/hooks';
export function mutateAll(re: RegExp) {
cache.keys().filter(key => {
- // console.log(key, re.test(key))
return re.test(key)
}).forEach(key => mutate(key, null))
}
@@ -140,7 +139,7 @@ function buildRequestOk<T>(res: any, url: string, hasToken:
boolean): HttpRespon
function buildRequestFailed(ex: AxiosError<MerchantBackend.ErrorDetail>, url:
string, hasToken: boolean): HttpResponseClientError | HttpResponseServerError |
HttpResponseUnexpectedError {
const status = ex.response?.status
-
+
const info = {
data: ex.request?.data,
params: ex.request?.params,
@@ -165,7 +164,7 @@ function buildRequestFailed(ex:
AxiosError<MerchantBackend.ErrorDetail>, url: st
serverError: true,
status,
info,
- message: ex.response?.data?.hint || ex.message,
+ message: `${ex.response?.data?.hint} (code ${ex.response?.data?.code})`
|| ex.message,
error: ex.response?.data
}
return error;
@@ -181,19 +180,34 @@ function buildRequestFailed(ex:
AxiosError<MerchantBackend.ErrorDetail>, url: st
return error
}
+
export async function request<T>(url: string, options: RequestOptions = {}):
Promise<HttpResponseOk<T>> {
const headers = options.token ? { Authorization: `Bearer ${options.token}` }
: undefined
+ // use this when simulating an error message from the server
+ // if (url.match(/\/orders\/.*/)) {
+ // const pepe: any = {
+ // message: 'qweqwe',
+ // request: {
+ // data: {
+
+ // },
+ // params: {
+
+ // },
+ // },
+ // response: {
+ // data: {
+ // hint: "This part is the hint",
+ // code: 2008,
+ // },
+ // status: 500,
+ // }
+ // };
+ // throw buildRequestFailed(pepe, url, !!options.token);
+ // }
try {
- // // http://localhost:9966/instances/blog/private/instances
- // // Hack, endpoint should respond 404
- // if (/^\/instances\/[^/]*\/private\/instances$/.test(new
URL(url).pathname)) {
- // console.warn(`HACK: Not going to query ${url}, instead return 404`)
- // throw ({ response: { status: 404 }, message: 'not found' })
- // }
-
-
const res = await axios({
url,
responseType: 'json',
diff --git a/packages/frontend/src/messages/en.po
b/packages/frontend/src/messages/en.po
index 3dc7eca..32a78a1 100644
--- a/packages/frontend/src/messages/en.po
+++ b/packages/frontend/src/messages/en.po
@@ -376,6 +376,9 @@ msgstr "Profit"
msgid "fields.product.stock.label"
msgstr "Stock"
+msgid "fields.product.quantity.label"
+msgstr "Quantity"
+
msgid "fields.product.sold.label"
msgstr "Sold"
diff --git a/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
b/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
index b26fed2..d3f6243 100644
--- a/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
+++ b/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
@@ -267,13 +267,9 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
{productList.length > 0 &&
<ProductList list={productList}
actions={[{
- name: 'Update', handler: (e, index) => {
- removeFromNewProduct(index);
- setEditingProduct(e);
- }
- }, {
name: 'Remove', handler: (e, index) => {
removeFromNewProduct(index);
+ setEditingProduct(e);
}
}]}
/>
diff --git
a/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx
b/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx
index 6aa08f0..54733d5 100644
---
a/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx
+++
b/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx
@@ -32,7 +32,8 @@ interface Props {
}
export function InventoryProductForm({ currentProducts, onAddProduct }:
Props): VNode {
- const [state, setState] = useState<Partial<Form>>({})
+ const initialState = { quantity: 1 }
+ const [state, setState] = useState<Partial<Form>>(initialState)
const [errors, setErrors] = useState<FormErrors<Form>>({})
const submit = (): void => {
@@ -40,27 +41,31 @@ export function InventoryProductForm({ currentProducts,
onAddProduct }: Props):
setErrors({ product: { message: 'select a product first' } });
return;
}
- if (!state.quantity || state.quantity <= 0) {
- setErrors({ quantity: { message: 'should be greater than 0' } });
- return;
- }
- const currentStock = state.product.total_stock - state.product.total_lost
- state.product.total_sold
- const p = currentProducts[state.product.id]
- if (p) {
- if (state.quantity + p.quantity > currentStock) {
- setErrors({ quantity: { message: `cannot be greater than current stock
and quantity previously added. max: ${currentStock - p.quantity}` } });
- return;
- }
- onAddProduct(state.product, state.quantity + p.quantity)
+ if (state.product.total_stock === -1) {
+ onAddProduct(state.product, 1)
} else {
- if (state.quantity > currentStock) {
- setErrors({ quantity: { message: `cannot be greater than current stock
${currentStock}` } });
+ if (!state.quantity || state.quantity <= 0) {
+ setErrors({ quantity: { message: 'should be greater than 0' } });
return;
}
- onAddProduct(state.product, state.quantity)
+ const currentStock = state.product.total_stock -
state.product.total_lost - state.product.total_sold
+ const p = currentProducts[state.product.id]
+ if (p) {
+ if (state.quantity + p.quantity > currentStock) {
+ setErrors({ quantity: { message: `cannot be greater than current
stock and quantity previously added. max: ${currentStock - p.quantity}` } });
+ return;
+ }
+ onAddProduct(state.product, state.quantity + p.quantity)
+ } else {
+ if (state.quantity > currentStock) {
+ setErrors({ quantity: { message: `cannot be greater than current
stock ${currentStock}` } });
+ return;
+ }
+ onAddProduct(state.product, state.quantity)
+ }
}
- setState({})
+ setState(initialState)
}
return <FormProvider<Form> errors={errors} object={state}
valueHandler={setState}>
diff --git
a/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx
b/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx
index dfd6b22..bf6a91e 100644
---
a/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx
+++
b/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx
@@ -14,11 +14,21 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
import { Fragment, h, VNode } from "preact";
-import { useEffect, useState } from "preact/hooks";
+import { useCallback, useEffect, useState } from "preact/hooks";
+import { FormErrors, FormProvider } from "../../../../components/form/Field";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { InputImage } from "../../../../components/form/InputImage";
+import { InputNumber } from "../../../../components/form/InputNumber";
+import { Stock } from "../../../../components/form/InputStock";
+import { InputTaxes } from "../../../../components/form/InputTaxes";
import { ConfirmModal } from "../../../../components/modal";
-import { ProductForm } from "../../../../components/product/ProductForm";
import { MerchantBackend } from "../../../../declaration";
import { useListener } from "../../../../hooks";
+import {
+ NonInventoryProductSchema as schema
+} from '../../../../schemas';
+import * as yup from 'yup';
type Entity = MerchantBackend.Product
@@ -35,11 +45,11 @@ export function NonInventoryProductFrom({ value,
onAddProduct }: Props): VNode {
setShowCreateProduct(editing)
}, [editing])
- const [submitForm, addFormSubmitter] =
useListener<Partial<MerchantBackend.Products.ProductAddDetail> |
undefined>((result) => {
+ const [submitForm, addFormSubmitter] =
useListener<Partial<MerchantBackend.Product> | undefined>((result) => {
if (result) {
setShowCreateProduct(false)
onAddProduct({
- quantity: result.total_stock || 0,
+ quantity: result.quantity || 0,
taxes: result.taxes || [],
description: result.description || '',
image: result.image || '',
@@ -49,18 +59,72 @@ export function NonInventoryProductFrom({ value,
onAddProduct }: Props): VNode {
}
})
- const initial: Partial<MerchantBackend.Products.ProductAddDetail> = {
- ...value,
- total_stock: value?.quantity || 0,
- taxes: []
- }
-
return <Fragment>
<div class="buttons">
<button class="button is-success" onClick={() =>
setShowCreateProduct(true)} >add new product</button>
</div>
{showCreateProduct && <ConfirmModal active onCancel={() =>
setShowCreateProduct(false)} onConfirm={submitForm}>
- <ProductForm initial={initial} onSubscribe={addFormSubmitter} />
+ <ProductForm initial={value} onSubscribe={addFormSubmitter} />
</ConfirmModal>}
</Fragment>
-}
\ No newline at end of file
+}
+
+interface ProductProps {
+ onSubscribe: (c: () => Entity | undefined) => void;
+ initial?: Partial<Entity>;
+}
+
+interface NonInventoryProduct {
+ quantity: number;
+ description: string;
+ unit: string;
+ price: string;
+ image: string;
+ taxes: MerchantBackend.Tax[];
+}
+
+export function ProductForm({ onSubscribe, initial }: ProductProps) {
+ const [value, valueHandler] = useState<Partial<NonInventoryProduct>>({
+ taxes: [],
+ ...initial,
+ })
+ const [errors, setErrors] = useState<FormErrors<NonInventoryProduct>>({})
+
+ const submit = useCallback((): Entity | undefined => {
+ try {
+ const validated = schema.validateSync(value, { abortEarly: false })
+ const result : MerchantBackend.Product = {
+ description: validated.description,
+ image: validated.image,
+ price: validated.price,
+ quantity: validated.quantity,
+ taxes: validated.taxes,
+ unit: validated.unit,
+ }
+ return result
+ } catch (err) {
+ const errors = err.inner as yup.ValidationError[]
+ const pathMessages = errors.reduce((prev, cur) => !cur.path ? prev : ({
...prev, [cur.path]: { type: cur.type, params: cur.params, message: cur.message
} }), {})
+ setErrors(pathMessages)
+ }
+ }, [value])
+
+ useEffect(() => {
+ onSubscribe(submit)
+ }, [submit])
+
+ return <div>
+ <FormProvider<NonInventoryProduct> name="product" errors={errors}
object={value} valueHandler={valueHandler} >
+
+ <InputImage<NonInventoryProduct> name="image" />
+ <Input<NonInventoryProduct> name="description" inputType="multiline" />
+ <Input<NonInventoryProduct> name="unit" />
+ <InputCurrency<NonInventoryProduct> name="price" />
+
+ <InputNumber<NonInventoryProduct> name="quantity" />
+
+ <InputTaxes<NonInventoryProduct> name="taxes" />
+
+ </FormProvider>
+ </div>
+}
diff --git a/packages/frontend/src/paths/instance/orders/create/index.tsx
b/packages/frontend/src/paths/instance/orders/create/index.tsx
index c918b03..01d2e6c 100644
--- a/packages/frontend/src/paths/instance/orders/create/index.tsx
+++ b/packages/frontend/src/paths/instance/orders/create/index.tsx
@@ -39,11 +39,7 @@ interface Props {
export default function OrderCreate({ onConfirm, onBack }: Props): VNode {
const { createOrder } = useOrderAPI()
const [notif, setNotif] = useState<Notification | undefined>(undefined)
- const [createdOk, setCreatedOk] = useState<Entity | undefined>(undefined);
- if (createdOk) {
- return <OrderCreatedSuccessfully entity={createdOk} onConfirm={onConfirm}
onCreateAnother={() => setCreatedOk(undefined)} />
- }
return <Fragment>
<NotificationCard notification={{
@@ -57,9 +53,7 @@ export default function OrderCreate({ onConfirm, onBack }:
Props): VNode {
<CreatePage
onBack={onBack}
onCreate={(request: MerchantBackend.Orders.PostOrderRequest) => {
- createOrder(request).then((response) => {
- setCreatedOk({ request, response: response.data })
- }).catch((error) => {
+ createOrder(request).then(onConfirm).catch((error) => {
setNotif({
message: 'could not create order',
type: "ERROR",
diff --git a/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
b/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
index 7f1353f..e2e8fe7 100644
--- a/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
+++ b/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
@@ -48,11 +48,6 @@ type Claimed =
MerchantBackend.Orders.CheckPaymentClaimedResponse
function ClaimedPage({ id, order }: { id: string; order:
MerchantBackend.Orders.CheckPaymentClaimedResponse }) {
const events: Event[] = []
- events.push({
- when: new Date(),
- description: 'now',
- type: 'now'
- })
events.push({
when: new Date(order.contract_terms.timestamp.t_ms),
description: 'order created',
@@ -79,7 +74,6 @@ function ClaimedPage({ id, order }: { id: string; order:
MerchantBackend.Orders.
type: 'delivery'
})
- events.sort((a, b) => a.when.getTime() - b.when.getTime())
const [value, valueHandler] = useState<Partial<Claimed>>(order)
return <div>
@@ -154,15 +148,17 @@ function ClaimedPage({ id, order }: { id: string; order:
MerchantBackend.Orders.
</div>
</section>
- <section class="section">
- <div class="columns">
- <div class="column is-12" >
- <div class="title">Product list</div>
- <ProductList list={order.contract_terms.products} />
+ {order.contract_terms.products.length > 0 &&
+ <section class="section">
+ <div class="columns">
+ <div class="column is-12" >
+ <div class="title">Product list</div>
+ <ProductList list={order.contract_terms.products} />
+ </div>
+ <div class="column" />
</div>
- <div class="column" />
- </div>
- </section>
+ </section>
+ }
</div>
<div class="column" />
@@ -172,11 +168,6 @@ function ClaimedPage({ id, order }: { id: string; order:
MerchantBackend.Orders.
}
function PaidPage({ id, order, onRefund }: { id: string; order:
MerchantBackend.Orders.CheckPaymentPaidResponse, onRefund: (id: string) => void
}) {
const events: Event[] = []
- events.push({
- when: new Date(),
- description: 'now',
- type: 'now'
- })
events.push({
when: new Date(order.contract_terms.timestamp.t_ms),
description: 'order created',
@@ -223,7 +214,6 @@ function PaidPage({ id, order, onRefund }: { id: string;
order: MerchantBackend.
type: 'wired',
})
- events.sort((a, b) => a.when.getTime() - b.when.getTime())
const [value, valueHandler] = useState<Partial<Paid>>(order)
const refundable = new Date().getTime() <
order.contract_terms.refund_deadline.t_ms
diff --git a/packages/frontend/src/paths/instance/orders/details/Timeline.tsx
b/packages/frontend/src/paths/instance/orders/details/Timeline.tsx
index 3881e26..a7a8121 100644
--- a/packages/frontend/src/paths/instance/orders/details/Timeline.tsx
+++ b/packages/frontend/src/paths/instance/orders/details/Timeline.tsx
@@ -15,12 +15,37 @@
*/
import { format } from "date-fns";
import { h } from "preact";
+import { useEffect, useState } from "preact/hooks";
interface Props {
events: Event[]
}
-export function Timeline({ events }: Props) {
+export function Timeline({ events:e }: Props) {
+ const events = [...e]
+ events.push({
+ when: new Date(),
+ description: 'now',
+ type: 'now'
+ })
+
+ events.sort((a, b) => a.when.getTime() - b.when.getTime())
+
+ const [state, setState] = useState(events)
+ useEffect(() => {
+ const handle = setTimeout(() => {
+ const eventsWithoutNow = state.filter(e => e.type !== 'now')
+ eventsWithoutNow.push({
+ when: new Date(),
+ description: 'now',
+ type: 'now'
+ })
+ setState(eventsWithoutNow)
+ },1000)
+ return () => {
+ clearTimeout(handle)
+ }
+ })
return <div class="timeline">
{events.map(e => {
return <div class="timeline-item">
diff --git
a/packages/frontend/src/paths/instance/products/create/CreatePage.tsx
b/packages/frontend/src/paths/instance/products/create/CreatePage.tsx
index 1255d24..427ebc0 100644
--- a/packages/frontend/src/paths/instance/products/create/CreatePage.tsx
+++ b/packages/frontend/src/paths/instance/products/create/CreatePage.tsx
@@ -25,7 +25,7 @@ import { ProductForm } from
"../../../../components/product/ProductForm";
import { MerchantBackend } from "../../../../declaration";
import { useListener } from "../../../../hooks";
-type Entity = MerchantBackend.Products.ProductDetail & { product_id: string}
+type Entity = MerchantBackend.Products.ProductAddDetail & { product_id: string}
interface Props {
onCreate: (d: Entity) => void;
diff --git a/packages/frontend/src/paths/instance/products/create/index.tsx
b/packages/frontend/src/paths/instance/products/create/index.tsx
index e31ccdc..ed997c4 100644
--- a/packages/frontend/src/paths/instance/products/create/index.tsx
+++ b/packages/frontend/src/paths/instance/products/create/index.tsx
@@ -25,7 +25,6 @@ import { NotificationCard } from
'../../../../components/menu';
import { MerchantBackend } from '../../../../declaration';
import { useProductAPI } from '../../../../hooks/product';
import { Notification } from '../../../../utils/types';
-import { CreatedSuccessfully } from './CreatedSuccessfully';
import { CreatePage } from './CreatePage';
export type Entity = MerchantBackend.Products.ProductAddDetail
@@ -36,20 +35,13 @@ interface Props {
export default function CreateProduct({ onConfirm, onBack }: Props): VNode {
const { createProduct } = useProductAPI()
const [notif, setNotif] = useState<Notification | undefined>(undefined)
- const [createdOk, setCreatedOk] = useState<Entity | undefined>(undefined);
-
- if (createdOk) {
- return <CreatedSuccessfully entity={createdOk} onConfirm={onConfirm}
onCreateAnother={() => setCreatedOk(undefined)} />
- }
return <Fragment>
<NotificationCard notification={notif} />
<CreatePage
onBack={onBack}
- onCreate={(request: MerchantBackend.Products.ProductDetail & {
product_id: string}) => {
- createProduct(request).then(() => {
- setCreatedOk(request)
- }).catch((error) => {
+ onCreate={(request: MerchantBackend.Products.ProductAddDetail) => {
+ createProduct(request).then(() => onConfirm()).catch((error) => {
setNotif({
message: 'could not create product',
type: "ERROR",
diff --git a/packages/frontend/src/paths/instance/products/list/Table.tsx
b/packages/frontend/src/paths/instance/products/list/Table.tsx
index 8fc6540..b548b56 100644
--- a/packages/frontend/src/paths/instance/products/list/Table.tsx
+++ b/packages/frontend/src/paths/instance/products/list/Table.tsx
@@ -27,6 +27,7 @@ import { FormErrors, FormProvider } from
"../../../../components/form/Field"
import { InputCurrency } from "../../../../components/form/InputCurrency"
import { InputNumber } from "../../../../components/form/InputNumber"
import { MerchantBackend, WithId } from "../../../../declaration"
+import emptyImage from "../../../../assets/empty.png";
type Entity = MerchantBackend.Products.ProductDetail & WithId
@@ -108,7 +109,9 @@ function Table({ rowSelection, rowSelectionHandler,
instances, onSelect, onUpdat
}
return <Fragment><tr>
- <td onClick={() => rowSelection !== i.id &&
rowSelectionHandler(i.id)} style={{ cursor: 'pointer' }} ><img src={i.image}
style={{ border: 'solid black 1px', width: 100, height: 100 }} /></td>
+ <td onClick={() => rowSelection !== i.id &&
rowSelectionHandler(i.id)} style={{ cursor: 'pointer' }} >
+ <img src={i.image ? i.image : emptyImage} style={{ border:
'solid black 1px', width: 100, height: 100 }} />
+ </td>
<td onClick={() => rowSelection !== i.id &&
rowSelectionHandler(i.id)} style={{ cursor: 'pointer' }} >{i.description}</td>
<td onClick={() => rowSelection !== i.id &&
rowSelectionHandler(i.id)} style={{ cursor: 'pointer' }} >{i.price} /
{i.unit}</td>
<td onClick={() => rowSelection !== i.id &&
rowSelectionHandler(i.id)} style={{ cursor: 'pointer' }} >{sum(i.taxes)}</td>
@@ -150,7 +153,30 @@ interface FastProductUpdate {
price: string;
}
-function FastProductUpdateForm({ product, onUpdate, onCancel }:
FastProductUpdateFormProps) {
+function FastProductWithInfiniteStockUpdateForm({ product, onUpdate, onCancel
}: FastProductUpdateFormProps) {
+ const [value, valueHandler] = useState<{price:string}>({price:
product.price})
+
+ return <Fragment>
+ <FormProvider<FastProductUpdate> name="added" object={value}
valueHandler={valueHandler as any} >
+ <InputCurrency<FastProductUpdate> name="price" />
+ </FormProvider>
+
+ <div class="buttons is-right mt-5">
+ <button class="button" onClick={onCancel} ><Message id="Cancel"
/></button>
+ <button class="button is-info" onClick={() => {
+
+ return onUpdate({
+ ...product,
+ price: value.price,
+ })
+
+ }}><Message id="Confirm" /></button>
+ </div>
+
+ </Fragment>
+}
+
+function FastProductWithManagedStockUpdateForm({ product, onUpdate, onCancel
}: FastProductUpdateFormProps) {
const [value, valueHandler] = useState<FastProductUpdate>({
incoming: 0, lost: 0, price: product.price
})
@@ -170,7 +196,6 @@ function FastProductUpdateForm({ product, onUpdate,
onCancel }: FastProductUpdat
)
const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !==
undefined)
- const isDirty = Object.keys(value).some(k => !!(value as any)[k])
return <Fragment>
<FormProvider<FastProductUpdate> name="added" errors={errors}
object={value} valueHandler={valueHandler as any} >
@@ -189,12 +214,12 @@ function FastProductUpdateForm({ product, onUpdate,
onCancel }: FastProductUpdat
<div class="buttons is-right mt-5">
<button class="button" onClick={onCancel} ><Message id="Cancel"
/></button>
- <button class="button is-info" disabled={hasErrors || !isDirty}
onClick={() => {
+ <button class="button is-info" disabled={hasErrors} onClick={() => {
return onUpdate({
...product,
total_stock: product.total_stock + value.incoming,
- total_lost: product.total_lost+ value.lost,
+ total_lost: product.total_lost + value.lost,
price: value.price,
})
@@ -202,7 +227,12 @@ function FastProductUpdateForm({ product, onUpdate,
onCancel }: FastProductUpdat
</div>
</Fragment>
+}
+function FastProductUpdateForm(props: FastProductUpdateFormProps) {
+ return props.product.total_stock === -1 ?
+ <FastProductWithInfiniteStockUpdateForm {...props} /> :
+ <FastProductWithManagedStockUpdateForm {...props} />
}
function EmptyTable(): VNode {
diff --git a/packages/frontend/src/paths/instance/update/index.tsx
b/packages/frontend/src/paths/instance/update/index.tsx
index c1bd457..81c9a06 100644
--- a/packages/frontend/src/paths/instance/update/index.tsx
+++ b/packages/frontend/src/paths/instance/update/index.tsx
@@ -27,7 +27,7 @@ export interface Props {
onUnauthorized: () => VNode;
onNotFound: () => VNode;
onLoadError: (e: HttpError) => VNode;
- onUpdateError: (e: Error) => void;
+ onUpdateError: (e: HttpError) => void;
}
diff --git a/packages/frontend/src/schemas/index.ts
b/packages/frontend/src/schemas/index.ts
index 54a3a8e..4e0e1c8 100644
--- a/packages/frontend/src/schemas/index.ts
+++ b/packages/frontend/src/schemas/index.ts
@@ -188,4 +188,13 @@ export const TaxSchema = yup.object().shape({
tax: yup.string()
.required()
.test('amount', 'the amount is not valid', currencyWithAmountIsValid),
-})
\ No newline at end of file
+})
+
+export const NonInventoryProductSchema = yup.object().shape({
+ quantity: yup.number().required().positive(),
+ description: yup.string().required(),
+ unit: yup.string().ensure().required(),
+ price: yup.string()
+ .required()
+ .test('amount', 'the amount is not valid', currencyWithAmountIsValid),
+})
diff --git a/packages/frontend/tests/__mocks__/fileTransformer.js
b/packages/frontend/tests/__mocks__/fileTransformer.js
new file mode 100644
index 0000000..fb0ad54
--- /dev/null
+++ b/packages/frontend/tests/__mocks__/fileTransformer.js
@@ -0,0 +1,9 @@
+// fileTransformer.js
+const path = require('path');
+
+module.exports = {
+ process(src, filename, config, options) {
+ return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
+ },
+};
+
diff --git a/packages/frontend/tests/stories.test.tsx
b/packages/frontend/tests/stories.test.tsx
new file mode 100644
index 0000000..afc9a11
--- /dev/null
+++ b/packages/frontend/tests/stories.test.tsx
@@ -0,0 +1,37 @@
+import { mount } from 'enzyme';
+import { h } from 'preact';
+import * as ctx from '../src/context/backend';
+
+const fs = require('fs');
+
+function getFiles (dir: string, files_: string[] = []){
+ var files = fs.readdirSync(dir);
+ for (var i in files){
+ var name = dir + '/' + files[i];
+ if (fs.statSync(name).isDirectory()){
+ getFiles(name, files_);
+ } else {
+ files_.push(name);
+ }
+ }
+ return files_;
+}
+
+const re = RegExp('.*\.stories.tsx')
+
+it('render every story', () => {
+ jest.spyOn(ctx, 'useConfigContext').mockImplementation(() => ({ version:
'1.0.0', currency: 'EUR' }));
+
+ getFiles('./src').filter(f => re.test(f)).map(f => {
+ const s = require('../'+f)
+ delete s.default
+ Object.keys(s).forEach(k => {
+ const Component = s[k];
+ try {
+ mount(<Component {...Component.args}/>);
+ } catch (error) {
+ console.error(`problem rendering ${f} example ${k}`, error)
+ }
+ })
+ })
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 259207a..e3dc9fb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -54,6 +54,7 @@ importers:
messageformat-po-loader: 0.3.0_messageformat@2.3.0
node-sass: 5.0.0
preact-cli: 3.0.5_5ba117d350dffefc029551565eae09b5
+ preact-render-to-json: 3.6.6_preact@10.5.13
preact-render-to-string: 5.1.16_preact@10.5.13
rimraf: 3.0.2
sass-loader: 10.1.1_node-sass@5.0.0
@@ -109,6 +110,7 @@ importers:
preact: ^10.5.13
preact-cli: ^3.0.5
preact-messages: workspace:*
+ preact-render-to-json: ^3.6.6
preact-render-to-string: ^5.1.16
preact-router: ^3.2.1
rimraf: ^3.0.2
@@ -153,6 +155,10 @@ packages:
dev: true
resolution:
integrity:
sha512-BwKEkO+2a67DcFeS3RLl0Z3Gs2OvdXewuWjc1Hfokhb5eQWP9YRYH1/+VrVZvql2CfjOiNGqSAFOYt4lsqTHzg==
+ /@babel/compat-data/7.13.15:
+ dev: true
+ resolution:
+ integrity:
sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==
/@babel/core/7.12.9:
dependencies:
'@babel/code-frame': 7.12.13
@@ -199,6 +205,36 @@ packages:
node: '>=6.9.0'
resolution:
integrity:
sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==
+ /@babel/core/7.13.16:
+ dependencies:
+ '@babel/code-frame': 7.12.13
+ '@babel/generator': 7.13.16
+ '@babel/helper-compilation-targets': 7.13.16_@babel+core@7.13.16
+ '@babel/helper-module-transforms': 7.13.14
+ '@babel/helpers': 7.13.17
+ '@babel/parser': 7.13.16
+ '@babel/template': 7.12.13
+ '@babel/traverse': 7.13.17
+ '@babel/types': 7.13.17
+ convert-source-map: 1.7.0
+ debug: 4.3.1
+ gensync: 1.0.0-beta.2
+ json5: 2.2.0
+ semver: 6.3.0
+ source-map: 0.5.7
+ dev: true
+ engines:
+ node: '>=6.9.0'
+ resolution:
+ integrity:
sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==
+ /@babel/generator/7.13.16:
+ dependencies:
+ '@babel/types': 7.13.17
+ jsesc: 2.5.2
+ source-map: 0.5.7
+ dev: true
+ resolution:
+ integrity:
sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==
/@babel/generator/7.13.9:
dependencies:
'@babel/types': 7.13.0
@@ -232,6 +268,18 @@ packages:
'@babel/core': ^7.0.0
resolution:
integrity:
sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA==
+ /@babel/helper-compilation-targets/7.13.16_@babel+core@7.13.16:
+ dependencies:
+ '@babel/compat-data': 7.13.15
+ '@babel/core': 7.13.16
+ '@babel/helper-validator-option': 7.12.17
+ browserslist: 4.16.5
+ semver: 6.3.0
+ dev: true
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ resolution:
+ integrity:
sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==
/@babel/helper-create-class-features-plugin/7.13.11_@babel+core@7.13.10:
dependencies:
'@babel/core': 7.13.10
@@ -304,12 +352,24 @@ packages:
dev: true
resolution:
integrity:
sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ==
+ /@babel/helper-member-expression-to-functions/7.13.12:
+ dependencies:
+ '@babel/types': 7.13.17
+ dev: true
+ resolution:
+ integrity:
sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==
/@babel/helper-module-imports/7.12.13:
dependencies:
'@babel/types': 7.13.0
dev: true
resolution:
integrity:
sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==
+ /@babel/helper-module-imports/7.13.12:
+ dependencies:
+ '@babel/types': 7.13.17
+ dev: true
+ resolution:
+ integrity:
sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==
/@babel/helper-module-transforms/7.13.0:
dependencies:
'@babel/helper-module-imports': 7.12.13
@@ -324,6 +384,19 @@ packages:
dev: true
resolution:
integrity:
sha512-Ls8/VBwH577+pw7Ku1QkUWIyRRNHpYlts7+qSqBBFCW3I8QteB9DxfcZ5YJpOwH6Ihe/wn8ch7fMGOP1OhEIvw==
+ /@babel/helper-module-transforms/7.13.14:
+ dependencies:
+ '@babel/helper-module-imports': 7.13.12
+ '@babel/helper-replace-supers': 7.13.12
+ '@babel/helper-simple-access': 7.13.12
+ '@babel/helper-split-export-declaration': 7.12.13
+ '@babel/helper-validator-identifier': 7.12.11
+ '@babel/template': 7.12.13
+ '@babel/traverse': 7.13.17
+ '@babel/types': 7.13.17
+ dev: true
+ resolution:
+ integrity:
sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==
/@babel/helper-optimise-call-expression/7.12.13:
dependencies:
'@babel/types': 7.13.0
@@ -355,12 +428,27 @@ packages:
dev: true
resolution:
integrity:
sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw==
+ /@babel/helper-replace-supers/7.13.12:
+ dependencies:
+ '@babel/helper-member-expression-to-functions': 7.13.12
+ '@babel/helper-optimise-call-expression': 7.12.13
+ '@babel/traverse': 7.13.17
+ '@babel/types': 7.13.17
+ dev: true
+ resolution:
+ integrity:
sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==
/@babel/helper-simple-access/7.12.13:
dependencies:
'@babel/types': 7.13.0
dev: true
resolution:
integrity:
sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==
+ /@babel/helper-simple-access/7.13.12:
+ dependencies:
+ '@babel/types': 7.13.17
+ dev: true
+ resolution:
+ integrity:
sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==
/@babel/helper-skip-transparent-expression-wrappers/7.12.1:
dependencies:
'@babel/types': 7.13.0
@@ -398,6 +486,14 @@ packages:
dev: true
resolution:
integrity:
sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==
+ /@babel/helpers/7.13.17:
+ dependencies:
+ '@babel/template': 7.12.13
+ '@babel/traverse': 7.13.17
+ '@babel/types': 7.13.17
+ dev: true
+ resolution:
+ integrity:
sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==
/@babel/highlight/7.13.10:
dependencies:
'@babel/helper-validator-identifier': 7.12.11
@@ -413,6 +509,13 @@ packages:
hasBin: true
resolution:
integrity:
sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q==
+ /@babel/parser/7.13.16:
+ dev: true
+ engines:
+ node: '>=6.0.0'
+ hasBin: true
+ resolution:
+ integrity:
sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==
/@babel/plugin-proposal-async-generator-functions/7.13.8_@babel+core@7.13.10:
dependencies:
'@babel/core': 7.13.10
@@ -1279,18 +1382,24 @@ packages:
'@babel/core': ^7.0.0-0
resolution:
integrity:
sha512-yCVtABcmvQjRsX2elcZFUV5Q5kDDpHdtXKKku22hNDma60lYuhKmtp1ykZ/okRCPLT2bR5S+cA1kvtBdAFlDTQ==
- /@babel/runtime-corejs3/7.13.10:
+ /@babel/runtime-corejs3/7.13.17:
dependencies:
- core-js-pure: 3.9.1
+ core-js-pure: 3.11.0
regenerator-runtime: 0.13.7
dev: true
resolution:
- integrity:
sha512-x/XYVQ1h684pp1mJwOV4CyvqZXqbc8CMsMGUnAbuc82ZCdv1U63w5RSUzgDSXQHG5Rps/kiksH6g2D5BuaKyXg==
+ integrity:
sha512-RGXINY1YvduBlGrP+vHjJqd/nK7JVpfM4rmZLGMx77WoL3sMrhheA0qxii9VNn1VHnxJLEyxmvCB+Wqc+x/FMw==
/@babel/runtime/7.13.10:
dependencies:
regenerator-runtime: 0.13.7
resolution:
integrity:
sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
+ /@babel/runtime/7.13.17:
+ dependencies:
+ regenerator-runtime: 0.13.7
+ dev: true
+ resolution:
+ integrity:
sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==
/@babel/template/7.12.13:
dependencies:
'@babel/code-frame': 7.12.13
@@ -1313,6 +1422,19 @@ packages:
dev: true
resolution:
integrity:
sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==
+ /@babel/traverse/7.13.17:
+ dependencies:
+ '@babel/code-frame': 7.12.13
+ '@babel/generator': 7.13.16
+ '@babel/helper-function-name': 7.12.13
+ '@babel/helper-split-export-declaration': 7.12.13
+ '@babel/parser': 7.13.16
+ '@babel/types': 7.13.17
+ debug: 4.3.1
+ globals: 11.12.0
+ dev: true
+ resolution:
+ integrity:
sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==
/@babel/types/7.13.0:
dependencies:
'@babel/helper-validator-identifier': 7.12.11
@@ -1321,6 +1443,13 @@ packages:
dev: true
resolution:
integrity:
sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==
+ /@babel/types/7.13.17:
+ dependencies:
+ '@babel/helper-validator-identifier': 7.12.11
+ to-fast-properties: 2.0.0
+ dev: true
+ resolution:
+ integrity:
sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==
/@base2/pretty-print-object/1.0.0:
dev: true
resolution:
@@ -1331,7 +1460,7 @@ packages:
integrity:
sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
/@cnakazawa/watch/1.0.4:
dependencies:
- exec-sh: 0.3.4
+ exec-sh: 0.3.6
minimist: 1.2.5
dev: true
engines:
@@ -1719,17 +1848,17 @@ packages:
integrity:
sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==
/@jest/transform/26.6.2:
dependencies:
- '@babel/core': 7.13.10
+ '@babel/core': 7.13.16
'@jest/types': 26.6.2
babel-plugin-istanbul: 6.0.0
- chalk: 4.1.0
+ chalk: 4.1.1
convert-source-map: 1.7.0
fast-json-stable-stringify: 2.1.0
graceful-fs: 4.2.6
jest-haste-map: 26.6.2
jest-regex-util: 26.0.0
jest-util: 26.6.2
- micromatch: 4.0.2
+ micromatch: 4.0.4
pirates: 4.0.1
slash: 3.0.0
source-map: 0.6.1
@@ -1743,9 +1872,9 @@ packages:
dependencies:
'@types/istanbul-lib-coverage': 2.0.3
'@types/istanbul-reports': 3.0.0
- '@types/node': 14.14.35
+ '@types/node': 15.0.0
'@types/yargs': 15.0.13
- chalk: 4.1.0
+ chalk: 4.1.1
dev: true
engines:
node: '>= 10.14.2'
@@ -2962,13 +3091,13 @@ packages:
node: '>=6'
resolution:
integrity:
sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
- /@testing-library/dom/7.30.0:
+ /@testing-library/dom/7.30.4:
dependencies:
'@babel/code-frame': 7.12.13
- '@babel/runtime': 7.13.10
+ '@babel/runtime': 7.13.17
'@types/aria-query': 4.2.1
aria-query: 4.2.2
- chalk: 4.1.0
+ chalk: 4.1.1
dom-accessibility-api: 0.5.4
lz-string: 1.4.4
pretty-format: 26.6.2
@@ -2976,7 +3105,7 @@ packages:
engines:
node: '>=10'
resolution:
- integrity:
sha512-v4GzWtltaiDE0yRikLlcLAfEiiK8+ptu6OuuIebm9GdC2XlZTNDPGEfM2UkEtnH7hr9TRq2sivT5EA9P1Oy7bw==
+ integrity:
sha512-GObDVMaI4ARrZEXaRy4moolNAxWPKvEYNV/fa6Uc2eAzR/t4otS6A7EhrntPBIQLeehL9DbVhscvvv7gd6hWqA==
/@testing-library/preact-hooks/1.1.0_8a3b8354086a0a31d950b2aa8b26d524:
dependencies:
'@testing-library/preact': 2.0.1_preact@10.5.13
@@ -2989,7 +3118,7 @@ packages:
integrity:
sha512-+JIor+NsOHkK3oIrwMDGKGHXTN0JJi462dBJlj4FNbGaDPTlctE6eu2ranWQirh7/FJMkWfzQCP+tk7jmY8ZrQ==
/@testing-library/preact/2.0.1_preact@10.5.13:
dependencies:
- '@testing-library/dom': 7.30.0
+ '@testing-library/dom': 7.30.4
preact: 10.5.13
dev: true
engines:
@@ -3031,7 +3160,7 @@ packages:
integrity:
sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==
/@types/babel__traverse/7.11.1:
dependencies:
- '@babel/types': 7.13.0
+ '@babel/types': 7.13.17
dev: true
resolution:
integrity:
sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==
@@ -3066,14 +3195,14 @@ packages:
integrity: sha1-pYHWiDR+EOUN18F9byiAoQNUMZ0=
/@types/glob/7.1.3:
dependencies:
- '@types/minimatch': 3.0.3
- '@types/node': 14.14.35
+ '@types/minimatch': 3.0.4
+ '@types/node': 15.0.0
dev: true
resolution:
integrity:
sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==
/@types/graceful-fs/4.1.5:
dependencies:
- '@types/node': 14.14.35
+ '@types/node': 15.0.0
dev: true
resolution:
integrity:
sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==
@@ -3144,10 +3273,10 @@ packages:
dev: true
resolution:
integrity:
sha512-my6fLBvpY70KattTNzYOK6KU1oR1+UCz9ug/JbcF5UrEmeCt9P7DV2t7L8+t18mMPINqGQCE4O8PLOPbI84gxw==
- /@types/minimatch/3.0.3:
+ /@types/minimatch/3.0.4:
dev: true
resolution:
- integrity:
sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
+ integrity:
sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==
/@types/node-fetch/2.5.8:
dependencies:
'@types/node': 14.14.35
@@ -3159,6 +3288,14 @@ packages:
dev: true
resolution:
integrity:
sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==
+ /@types/node/14.14.42:
+ dev: true
+ resolution:
+ integrity:
sha512-88QoObqn9WYIUMRzOx92GmSHmU3JCyukC2ulEv8tFjUG9VeV2FQ/cA7VQ1gi+rB/+gBMVvzVFcTnz8RdMDVIWw==
+ /@types/node/15.0.0:
+ dev: true
+ resolution:
+ integrity:
sha512-YN1d+ae2MCb4U0mMa+Zlb5lWTdpFShbAj5nmte6lel27waMMBfivrm0prC16p/Di3DyTrmerrYUT8/145HXxVw==
/@types/normalize-package-data/2.4.0:
dev: true
resolution:
@@ -3266,7 +3403,7 @@ packages:
integrity:
sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==
/@types/webpack-sources/2.1.0:
dependencies:
- '@types/node': 14.14.35
+ '@types/node': 14.14.42
'@types/source-list-map': 0.1.2
source-map: 0.7.3
dev: true
@@ -3840,6 +3977,15 @@ packages:
node: '>= 8'
resolution:
integrity:
sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
+ /anymatch/3.1.2:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.2.3
+ dev: true
+ engines:
+ node: '>= 8'
+ resolution:
+ integrity:
sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
/app-root-dir/1.0.2:
dev: true
resolution:
@@ -3863,8 +4009,8 @@ packages:
integrity:
sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
/aria-query/4.2.2:
dependencies:
- '@babel/runtime': 7.13.10
- '@babel/runtime-corejs3': 7.13.10
+ '@babel/runtime': 7.13.17
+ '@babel/runtime-corejs3': 7.13.17
dev: true
engines:
node: '>=6.0'
@@ -4897,6 +5043,19 @@ packages:
hasBin: true
resolution:
integrity:
sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==
+ /browserslist/4.16.5:
+ dependencies:
+ caniuse-lite: 1.0.30001216
+ colorette: 1.2.2
+ electron-to-chromium: 1.3.720
+ escalade: 3.1.1
+ node-releases: 1.1.71
+ dev: true
+ engines:
+ node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7
+ hasBin: true
+ resolution:
+ integrity:
sha512-C2HAjrM1AI/djrpAUU/tr4pml1DqLIzJKSLDBXBrNErl9ZCCTXdhwxdJjYc16953+mBWf7Lw+uUJgpgb8cN71A==
/bser/2.1.1:
dependencies:
node-int64: 0.4.0
@@ -5167,6 +5326,10 @@ packages:
dev: true
resolution:
integrity:
sha512-ic/jXfa6tgiPBAISWk16jRI2q8YfjxHnSG7ddSL1ptrIP8Uy11SayFrjXRAk3NumHpDb21fdTkbTxb/hOrFrnQ==
+ /caniuse-lite/1.0.30001216:
+ dev: true
+ resolution:
+ integrity:
sha512-1uU+ww/n5WCJRwUcc9UH/W6925Se5aNnem/G5QaSDga2HzvjYMs8vRbekGUN/PnTZ7ezTHcxxTEb9fgiMYwH6Q==
/capture-exit/2.0.0:
dependencies:
rsvp: 4.8.5
@@ -5239,6 +5402,15 @@ packages:
node: '>=10'
resolution:
integrity:
sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
+ /chalk/4.1.1:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+ dev: true
+ engines:
+ node: '>=10'
+ resolution:
+ integrity:
sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
/char-regex/1.0.2:
dev: true
engines:
@@ -5840,6 +6012,11 @@ packages:
dev: true
resolution:
integrity:
sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA==
+ /core-js-pure/3.11.0:
+ dev: true
+ requiresBuild: true
+ resolution:
+ integrity:
sha512-PxEiQGjzC+5qbvE7ZIs5Zn6BynNeZO9zHhrrWmkRff2SZLq0CE/H5LuZOJHhmOQ8L38+eMzEHAmPYWrUtDfuDQ==
/core-js-pure/3.9.1:
dev: true
requiresBuild: true
@@ -6843,6 +7020,10 @@ packages:
dev: true
resolution:
integrity:
sha512-WCn+ZaU3V8WttlLNSOGOAlR2XpxibGre7slwGrYBB6oTjYPgP29LNDGG6wLvLTMseLdE+G1vno7PfY7JyDV48g==
+ /electron-to-chromium/1.3.720:
+ dev: true
+ resolution:
+ integrity:
sha512-B6zLTxxaOFP4WZm6DrvgRk8kLFYWNhQ5TrHMC0l5WtkMXhU5UbnvWoTfeEwqOruUSlNMhVLfYak7REX6oC5Yfw==
/element-resize-detector/1.2.2:
dependencies:
batch-processor: 1.0.0
@@ -7431,10 +7612,10 @@ packages:
dev: true
resolution:
integrity:
sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
- /exec-sh/0.3.4:
+ /exec-sh/0.3.6:
dev: true
resolution:
- integrity:
sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==
+ integrity:
sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==
/execa/1.0.0:
dependencies:
cross-spawn: 6.0.5
@@ -7907,7 +8088,7 @@ packages:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
- mime-types: 2.1.29
+ mime-types: 2.1.30
dev: true
engines:
node: '>= 6'
@@ -9954,7 +10135,7 @@ packages:
integrity:
sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==
/jest-diff/26.6.2:
dependencies:
- chalk: 4.1.0
+ chalk: 4.1.1
diff-sequences: 26.6.2
jest-get-type: 26.3.0
pretty-format: 26.6.2
@@ -10020,15 +10201,15 @@ packages:
dependencies:
'@jest/types': 26.6.2
'@types/graceful-fs': 4.1.5
- '@types/node': 14.14.35
- anymatch: 3.1.1
+ '@types/node': 15.0.0
+ anymatch: 3.1.2
fb-watchman: 2.0.1
graceful-fs: 4.2.6
jest-regex-util: 26.0.0
jest-serializer: 26.6.2
jest-util: 26.6.2
jest-worker: 26.6.2
- micromatch: 4.0.2
+ micromatch: 4.0.4
sane: 4.1.0
walker: 1.0.7
dev: true
@@ -10074,7 +10255,7 @@ packages:
integrity:
sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==
/jest-matcher-utils/26.6.2:
dependencies:
- chalk: 4.1.0
+ chalk: 4.1.1
jest-diff: 26.6.2
jest-get-type: 26.3.0
pretty-format: 26.6.2
@@ -10088,9 +10269,9 @@ packages:
'@babel/code-frame': 7.12.13
'@jest/types': 26.6.2
'@types/stack-utils': 2.0.0
- chalk: 4.1.0
+ chalk: 4.1.1
graceful-fs: 4.2.6
- micromatch: 4.0.2
+ micromatch: 4.0.4
pretty-format: 26.6.2
slash: 3.0.0
stack-utils: 2.0.3
@@ -10161,7 +10342,7 @@ packages:
/jest-resolve/26.6.2:
dependencies:
'@jest/types': 26.6.2
- chalk: 4.1.0
+ chalk: 4.1.1
graceful-fs: 4.2.6
jest-pnp-resolver: 1.2.2_jest-resolve@26.6.2
jest-util: 26.6.2
@@ -10237,7 +10418,7 @@ packages:
integrity:
sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==
/jest-serializer/26.6.2:
dependencies:
- '@types/node': 14.14.35
+ '@types/node': 15.0.0
graceful-fs: 4.2.6
dev: true
engines:
@@ -10246,11 +10427,11 @@ packages:
integrity:
sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==
/jest-snapshot/26.6.2:
dependencies:
- '@babel/types': 7.13.0
+ '@babel/types': 7.13.17
'@jest/types': 26.6.2
'@types/babel__traverse': 7.11.1
'@types/prettier': 2.2.3
- chalk: 4.1.0
+ chalk: 4.1.1
expect: 26.6.2
graceful-fs: 4.2.6
jest-diff: 26.6.2
@@ -10261,7 +10442,7 @@ packages:
jest-resolve: 26.6.2
natural-compare: 1.4.0
pretty-format: 26.6.2
- semver: 7.3.4
+ semver: 7.3.5
dev: true
engines:
node: '>= 10.14.2'
@@ -10270,11 +10451,11 @@ packages:
/jest-util/26.6.2:
dependencies:
'@jest/types': 26.6.2
- '@types/node': 14.14.35
- chalk: 4.1.0
+ '@types/node': 15.0.0
+ chalk: 4.1.1
graceful-fs: 4.2.6
is-ci: 2.0.0
- micromatch: 4.0.2
+ micromatch: 4.0.4
dev: true
engines:
node: '>= 10.14.2'
@@ -11224,6 +11405,15 @@ packages:
node: '>=8'
resolution:
integrity:
sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
+ /micromatch/4.0.4:
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.2.3
+ dev: true
+ engines:
+ node: '>=8.6'
+ resolution:
+ integrity:
sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
/miller-rabin/4.0.1:
dependencies:
bn.js: 4.12.0
@@ -11238,6 +11428,12 @@ packages:
node: '>= 0.6'
resolution:
integrity:
sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==
+ /mime-db/1.47.0:
+ dev: true
+ engines:
+ node: '>= 0.6'
+ resolution:
+ integrity:
sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
/mime-types/2.1.29:
dependencies:
mime-db: 1.46.0
@@ -11246,6 +11442,14 @@ packages:
node: '>= 0.6'
resolution:
integrity:
sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==
+ /mime-types/2.1.30:
+ dependencies:
+ mime-db: 1.47.0
+ dev: true
+ engines:
+ node: '>= 0.6'
+ resolution:
+ integrity:
sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
/mime/1.6.0:
dev: true
engines:
@@ -11798,6 +12002,10 @@ packages:
node: '>=0.10.0'
resolution:
integrity: sha1-fn2Fi3gb18mRpBupde04EnVOmYw=
+ /object-inspect/1.10.2:
+ dev: true
+ resolution:
+ integrity:
sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==
/object-inspect/1.9.0:
dev: true
resolution:
@@ -12397,6 +12605,12 @@ packages:
node: '>=8.6'
resolution:
integrity:
sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
+ /picomatch/2.2.3:
+ dev: true
+ engines:
+ node: '>=8.6'
+ resolution:
+ integrity:
sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==
/pify/2.3.0:
dev: true
engines:
@@ -12977,6 +13191,14 @@ packages:
preact-render-to-string: '*'
resolution:
integrity:
sha512-Oc9HOjwX/3Zk1eXkmP7TMmtqbaROl7F0RWZ2Ni5Q/grmx3yBLJmarkUcOSKabkI/Usw2dU3RVju32Q3Pvy5qIw==
+ /preact-render-to-json/3.6.6_preact@10.5.13:
+ dependencies:
+ preact: 10.5.13
+ dev: true
+ peerDependencies:
+ preact: '*'
+ resolution:
+ integrity: sha1-9n9IWBkSrFP8n0hzvG1840L3HCA=
/preact-render-to-string/5.1.16_preact@10.5.13:
dependencies:
preact: 10.5.13
@@ -13053,7 +13275,7 @@ packages:
'@jest/types': 26.6.2
ansi-regex: 5.0.0
ansi-styles: 4.3.0
- react-is: 17.0.1
+ react-is: 17.0.2
dev: true
engines:
node: '>= 10'
@@ -13538,6 +13760,10 @@ packages:
dev: true
resolution:
integrity:
sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==
+ /react-is/17.0.2:
+ dev: true
+ resolution:
+ integrity:
sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
/react-lifecycles-compat/3.0.4:
dev: true
resolution:
@@ -14296,7 +14522,7 @@ packages:
'@cnakazawa/watch': 1.0.4
anymatch: 2.0.0
capture-exit: 2.0.0
- exec-sh: 0.3.4
+ exec-sh: 0.3.6
execa: 1.0.0
fb-watchman: 2.0.1
micromatch: 3.1.10
@@ -14487,6 +14713,15 @@ packages:
hasBin: true
resolution:
integrity:
sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
+ /semver/7.3.5:
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+ engines:
+ node: '>=10'
+ hasBin: true
+ resolution:
+ integrity:
sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
/send/0.17.1:
dependencies:
debug: 2.6.9
@@ -14656,7 +14891,7 @@ packages:
dependencies:
call-bind: 1.0.2
get-intrinsic: 1.1.1
- object-inspect: 1.9.0
+ object-inspect: 1.10.2
dev: true
resolution:
integrity:
sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-merchant-backoffice] branch master updated: some fixes,
gnunet <=