Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit 444039f

Browse files
normalized all remaining links into _links
1 parent 6013c21 commit 444039f

File tree

11 files changed

+97
-92
lines changed

11 files changed

+97
-92
lines changed

src/SqlStreamStoreBrowser.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,20 @@ const self$ = store.hal$.links$
3636
interface SqlStreamStoreBrowserState {
3737
loading: boolean;
3838
mediaType: string;
39-
links: HalLinks;
39+
_links: HalLinks;
4040
self: HalLink;
4141
}
4242
const state$ = createState<SqlStreamStoreBrowserState>(
4343
obs.merge(
4444
self$.map(self => ['self', () => self]),
45-
store.hal$.links$.map(links => ['links', () => links]),
45+
store.hal$.links$.map(links => ['_links', () => links]),
4646
store.hal$.forms$.map(forms => ['forms', () => forms]),
4747
store.hal$.loading$.map(loading => ['loading', () => loading]),
4848
store.hal$.mediaType$.map(mediaType => ['mediaType', () => mediaType]),
4949
),
5050
obs.of({
51+
_links: {},
5152
forms: {},
52-
links: {},
5353
loading: false,
5454
mediaType: mediaTypes.hal,
5555
self: {

src/components/HyperMediaControls/index.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,26 @@ const state$ = createState<HyperMediaControlsState>(
2222

2323
interface HyperMediaControlsProps {
2424
actions: any;
25-
links: HalLinks;
25+
_links: HalLinks;
2626
forms: { [rel: string]: HalResource & JSONSchema7 };
2727
}
2828

2929
const HyperMediaControls: StatelessComponent<
3030
HyperMediaControlsProps & HyperMediaControlsState
31-
> = ({ actions, forms, href, links }) => (
31+
> = ({ actions, forms, href, _links }) => (
3232
<Card>
3333
<CardActions>
3434
<div>
35-
{Object.keys(links)
35+
{Object.keys(_links)
3636
.filter(rel => !navigation.has(rel))
37-
.filter(rel => isNotSelf(rel, links))
37+
.filter(rel => isNotSelf(rel, _links))
3838
.map(rel => (
3939
<LinkButton
4040
key={rel}
4141
rel={rel}
42-
link={links[rel][0]}
42+
link={_links[rel][0]}
4343
color={'primary'}
44-
curies={links[rels.curies]}
44+
curies={_links[rels.curies]}
4545
/>
4646
))}
4747
{Object.keys(forms).map(rel => (
@@ -51,7 +51,7 @@ const HyperMediaControls: StatelessComponent<
5151
link={{ href }}
5252
actions={actions}
5353
schema={forms[rel]}
54-
curies={links[rels.curies]}
54+
curies={_links[rels.curies]}
5555
/>
5656
))}
5757
</div>

src/components/NavigationLinks.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,17 @@ const FeedNavigationLink: StatelessComponent<
4343
},
4444
);
4545
interface NavigationLinksProps {
46-
links: HalLinks;
46+
_links: HalLinks;
4747
}
4848

4949
const NavigationLinks: StatelessComponent<NavigationLinksProps> = ({
50-
links,
50+
_links,
5151
}) => (
5252
<nav>
5353
{[...navigation].map(rel => (
5454
<FeedNavigationLink
5555
key={rel}
56-
link={(links[rel] || [])[0]}
56+
link={(_links[rel] || [])[0]}
5757
rel={rel}
5858
/>
5959
))}

src/stream-store/Viewer/HalViewer/Stream.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from '../../../components/StripeyTable';
1111
import { connect, createState } from '../../../reactive';
1212
import { HalResource } from '../../../types';
13-
import { resolveLinks } from '../../../utils';
13+
import { hal } from '../../../utils';
1414
import rels from '../../rels';
1515
import store from '../../store';
1616
import { HalViewerProps } from './types';
@@ -30,7 +30,7 @@ const messages$ = store.hal$.body$
3030
.map(([{ _embedded }, url]) =>
3131
_embedded[rels.message].map(({ _links, ...message }) => ({
3232
...message,
33-
_links: resolveLinks(url, _links),
33+
_links: hal.resolveLinks(url, _links),
3434
})),
3535
);
3636

src/stream-store/Viewer/HalViewer/StreamBrowser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ComponentType } from 'react';
22
import { Observable as obs } from 'rxjs';
33
import StreamBrowser from '../../../components/StreamBrowser';
44
import { connect, createState } from '../../../reactive';
5-
import { HalLink, HalResource } from '../../../types';
5+
import { HalResource } from '../../../types';
66
import rels from '../../rels';
77
import store from '../../store';
88
import { HalViewerProps } from './types';

src/stream-store/Viewer/HalViewer/StreamMessage.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
} from '../../../components/StripeyTable';
3333
import { connect, createState } from '../../../reactive';
3434
import { HalResource, NavigatableProps } from '../../../types';
35-
import { http } from '../../../utils';
35+
import { hal, http } from '../../../utils';
3636
import rels from '../../rels';
3737
import store from '../../store';
3838
import { HalViewerProps } from './types';
@@ -200,15 +200,9 @@ const StreamMessageJson = withStyles(style)(class extends PureComponent<
200200
this.setState({
201201
loading: false,
202202
streams: Object.values(
203-
responses
204-
.flatMap(({ body }) => getStreamLinks(body as HalResource))
205-
.reduce(
206-
(akk, { href, title }) => ({
207-
...akk,
208-
[href]: { href, title },
209-
}),
210-
{},
211-
),
203+
responses.flatMap(({ body }) =>
204+
getStreamLinks(hal.normalizeResource(body as HalResource)),
205+
),
212206
),
213207
});
214208
};
@@ -244,6 +238,7 @@ const StreamMessageJson = withStyles(style)(class extends PureComponent<
244238
render() {
245239
const { json, classes } = this.props;
246240
const { streams, loading, open } = this.state;
241+
247242
return (
248243
<div>
249244
<Inspector

src/stream-store/Viewer/HalViewer/index.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,19 @@ const views: { [rel: string]: ComponentType<HalViewerProps> } = {
2828

2929
const HalViewer: StatelessComponent<HalViewerProps> = ({
3030
forms,
31-
links,
31+
_links,
3232
self,
3333
}) => (
3434
<section>
35-
<NavigationLinks links={links} />
36-
<HyperMediaControls actions={formActions} forms={forms} links={links} />
35+
<NavigationLinks _links={_links} />
36+
<HyperMediaControls
37+
actions={formActions}
38+
forms={forms}
39+
_links={_links}
40+
/>
3741
{createElement<HalViewerProps>(views[self] || views._unrecognized, {
42+
_links,
3843
forms,
39-
links,
4044
self,
4145
})}
4246
</section>

src/stream-store/Viewer/HalViewer/types.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ import { HalLinks, HalResource } from '../../../types';
33

44
export interface HalViewerProps {
55
self: string;
6-
links: HalLinks;
6+
_links: HalLinks;
77
forms: { [rel: string]: HalResource & JSONSchema7 };
88
}

src/stream-store/store/hal.ts

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,21 @@
11
import { JSONSchema7 } from 'json-schema';
22
import { Observable as obs } from 'rxjs';
3-
import { HalLink, HalResource } from '../../types';
4-
import { resolveLinks } from '../../utils';
3+
import { HalResource } from '../../types';
4+
import { hal } from '../../utils';
55
import mediaTypes from '../../utils/mediaTypes';
66
import actions from '../actions';
77
import mediaType$ from './mediaType';
88

9-
interface Links {
10-
[rel: string]: HalLink | HalLink[];
11-
}
12-
13-
interface Embedded {
14-
[rel: string]: HalResource | HalResource[];
15-
}
16-
17-
const normalizeEmbedded = (
18-
maybeArray: HalResource | HalResource[],
19-
): HalResource[] => (Array.isArray(maybeArray) ? maybeArray : [maybeArray]);
20-
21-
const normalizeLinks = (maybeArray: HalLink | HalLink[]): HalLink[] =>
22-
Array.isArray(maybeArray) ? maybeArray : [maybeArray];
23-
24-
const normalize = ({
25-
_links,
26-
_embedded,
27-
...resource
28-
}: {
29-
_links: Links;
30-
_embedded: Embedded;
31-
}): HalResource => ({
32-
...resource,
33-
_embedded: Object.keys(_embedded || {}).reduce(
34-
(akk, rel) => ({
35-
...akk,
36-
[rel]: normalizeEmbedded(_embedded[rel]).map(normalize),
37-
}),
38-
{},
39-
),
40-
_links: Object.keys(_links || {}).reduce(
41-
(akk, rel) => ({
42-
...akk,
43-
[rel]: normalizeLinks(_links[rel]),
44-
}),
45-
{},
46-
),
47-
});
48-
499
const body$ = actions.get.response
5010
.zip(mediaType$)
5111
.filter(([body, mediaType]) => mediaType === mediaTypes.hal)
52-
.map(([{ body }]) => normalize(body as HalResource));
12+
.map(([{ body }]) => hal.normalizeResource(body as HalResource));
5313

5414
const url$ = actions.get.response.map(({ url }) => url);
5515

5616
const links$ = body$
5717
.zip(url$)
58-
.map(([{ _links }, url]) => resolveLinks(url, _links));
18+
.map(([{ _links }, url]) => hal.resolveLinks(url, _links));
5919

6020
const isJsonSchema = (schema: JSONSchema7 & HalResource) =>
6121
schema && schema.$schema && schema.$schema.endsWith('schema#');

src/utils/hal.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { resolve } from 'uri-js';
2+
import { HalLink, HalLinks, HalResource } from '../types';
3+
4+
const resolveLinks = (url: string, links: HalLinks): HalLinks =>
5+
Object.keys(links).reduce(
6+
(akk, rel) => ({
7+
...akk,
8+
[rel]: links[rel].map(({ href, ...link }) => ({
9+
...link,
10+
href: resolve(url, href || './', { tolerant: true }),
11+
rel,
12+
})),
13+
}),
14+
// tslint:disable-next-line:no-object-literal-type-assertion
15+
{} as HalLinks,
16+
);
17+
18+
interface Links {
19+
[rel: string]: HalLink | HalLink[];
20+
}
21+
22+
interface Embedded {
23+
[rel: string]: HalResource | HalResource[];
24+
}
25+
26+
const normalizeEmbedded = (
27+
maybeArray: HalResource | HalResource[],
28+
): HalResource[] => (Array.isArray(maybeArray) ? maybeArray : [maybeArray]);
29+
30+
const normalizeLinks = (maybeArray: HalLink | HalLink[]): HalLink[] =>
31+
Array.isArray(maybeArray) ? maybeArray : [maybeArray];
32+
33+
const normalizeResource = ({
34+
_links,
35+
_embedded,
36+
...resource
37+
}: {
38+
_links: Links;
39+
_embedded: Embedded;
40+
}): HalResource => ({
41+
...resource,
42+
_embedded: Object.keys(_embedded || {}).reduce(
43+
(akk, rel) => ({
44+
...akk,
45+
[rel]: normalizeEmbedded(_embedded[rel]).map(normalizeResource),
46+
}),
47+
{},
48+
),
49+
_links: Object.keys(_links || {}).reduce(
50+
(akk, rel) => ({
51+
...akk,
52+
[rel]: normalizeLinks(_links[rel]),
53+
}),
54+
{},
55+
),
56+
});
57+
58+
export default {
59+
normalizeResource,
60+
resolveLinks,
61+
};

0 commit comments

Comments
 (0)