5htp-core 0.5.0-5 → 0.5.0-7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "5htp-core",
3
3
  "description": "Convenient TypeScript framework designed for Performance and Productivity.",
4
- "version": "0.5.0-5",
4
+ "version": "0.5.0-7",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -23,7 +23,6 @@ export type Props = {
23
23
  iconR?: ComponentChild,
24
24
 
25
25
  prefix?: ComponentChild,
26
- children?: ComponentChild | ComponentChild[],
27
26
  suffix?: ComponentChild,
28
27
 
29
28
  tag?: "a" | "button",
@@ -31,7 +30,6 @@ export type Props = {
31
30
  shape?: 'default' | 'icon' | 'tile' | 'pill',
32
31
  size?: TComponentSize,
33
32
  class?: string,
34
- title?: string,
35
33
 
36
34
  state?: [string, React.StateUpdater<string>],
37
35
  active?: boolean,
@@ -45,7 +43,14 @@ export type Props = {
45
43
  submenu?: ComponentChild,
46
44
  nav?: boolean | 'exact'
47
45
 
48
- } & (TButtonProps | TLinkProps)
46
+ // SEO: if icon only, should provinde a hint (aria-label)
47
+ } & ({
48
+ hint: string,
49
+ children?: ComponentChild | ComponentChild[],
50
+ } | {
51
+ children: ComponentChild | ComponentChild[],
52
+ hint?: string,
53
+ }) & (TButtonProps | TLinkProps)
49
54
 
50
55
  export type TButtonProps = {
51
56
 
@@ -84,6 +89,7 @@ export default ({
84
89
  iconR, suffix,
85
90
  submenu,
86
91
  nav,
92
+ hint,
87
93
 
88
94
  // Style
89
95
  class: className,
@@ -125,6 +131,12 @@ export default ({
125
131
  props.onClick = () => setActive(id);
126
132
  }
127
133
 
134
+ // Hint
135
+ if (hint !== undefined) {
136
+ props['aria-label'] = hint;
137
+ props.title = hint;
138
+ }
139
+
128
140
  // Shape classes
129
141
  const classNames: string[] = ['btn'];
130
142
  if (className)
@@ -162,6 +162,12 @@ export class NotFound extends CoreError {
162
162
  public static msgDefaut = "The resource you asked for was not found.";
163
163
  }
164
164
 
165
+ export class RateLimit extends CoreError {
166
+ public http = 429;
167
+ public title = "You're going too fast";
168
+ public static msgDefaut = "Please slow down a bit and retry again later.";
169
+ }
170
+
165
171
  export class Anomaly extends CoreError {
166
172
 
167
173
  public http = 500;
@@ -229,6 +235,8 @@ export const fromJson = ({ code, message, ...details }: TJsonError) => {
229
235
 
230
236
  case 404: return new NotFound( message, details );
231
237
 
238
+ case 429: return new RateLimit( message, details );
239
+
232
240
  default: return new Anomaly( message, details );
233
241
  }
234
242
 
@@ -58,7 +58,7 @@ export default class DocumentRenderer<TRouter extends Router> {
58
58
  public async page( html: string, page: Page, response: ServerResponse<TRouter> ) {
59
59
 
60
60
  // TODO: can be customized via page / route config
61
- const canonicalUrl = response.request.req.url;
61
+ const canonicalUrl = response.request.url;
62
62
 
63
63
  let attrsBody = {
64
64
  className: [...page.bodyClass].join(' '),
@@ -120,8 +120,12 @@ export default class ServerPage<TRouter extends Router = Router> extends PageRes
120
120
 
121
121
  private buildMetas() {
122
122
 
123
+ const shouldIndex = this.context.response.statusCode < 300;
124
+
123
125
  const metas = {
124
126
 
127
+ robots: shouldIndex ? 'index' : 'noindex',
128
+
125
129
  'og:type': 'website',
126
130
  'og:locale': this.app.identity.locale,
127
131
  'og:site_name': this.app.identity.web.title,