@autobusal/providers 1.40.1 → 1.40.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.40.2
4
+
5
+ ### Fixed
6
+
7
+ - **A missing blog/help/page slug showed the "system error" screen, not a
8
+ 404.** The public content screens load through `useSuspenseQuery`, whose
9
+ throw the ErrorBoundary rendered as a system error for every case; a 404
10
+ (unknown slug) or 422 (the articles endpoint's "invalid slug" on an
11
+ absent/unpublished article) is now shown as the styled 404. (Audit
12
+ CMS-01f/CMS-03d.)
13
+ - **The public navigation menu was always English.** obtapi localises the
14
+ labels off `Content-Language` - sent correctly - but the menu was cached
15
+ under a language-blind key, so it loaded once and a language switch never
16
+ refetched it. Keyed on the active language. (Audit CMS-07b.)
17
+
3
18
  ## 1.37.11
4
19
 
5
20
  ### Added
@@ -5,11 +5,29 @@ interface Props {
5
5
  children: JSX.Element[] | JSX.Element
6
6
  }
7
7
 
8
- class ErrorBoundary extends React.Component<Props> {
9
- state = { hasError: false };
8
+ /*
9
+ * Edited: Claude - Date: 2026-08-22 (audit findings CMS-01f / CMS-03d)
10
+ *
11
+ * A missing blog article, help article or static page is a 404, not a system
12
+ * error. The public content screens load through useSuspenseQuery, which
13
+ * throws the axios error up here; this boundary rendered the generic "system
14
+ * error" page for every throw, so a mistyped or deleted slug told the visitor
15
+ * something had broken on our side. An HTTP 404 (unknown slug) or 422 (the
16
+ * articles endpoint's "selected slug is invalid" on an unpublished/absent
17
+ * article) is the content not being there - shown as the styled 404. Anything
18
+ * else is still a real error.
19
+ */
20
+ function isMissing(error: unknown): boolean {
21
+ const status = (error as { response?: { status?: number } })?.response?.status;
10
22
 
11
- static getDerivedStateFromError() {
12
- return { hasError: true };
23
+ return status === 404 || status === 422;
24
+ }
25
+
26
+ class ErrorBoundary extends React.Component<Props, { hasError: boolean; missing: boolean }> {
27
+ state = { hasError: false, missing: false };
28
+
29
+ static getDerivedStateFromError(error: unknown) {
30
+ return { hasError: true, missing: isMissing(error) };
13
31
  }
14
32
 
15
33
  componentDidCatch(error: Error, info: React.ErrorInfo): void {
@@ -18,11 +36,11 @@ class ErrorBoundary extends React.Component<Props> {
18
36
 
19
37
  render() {
20
38
  if (this.state.hasError) {
21
- return <Message type="error" />;
39
+ return <Message type={ this.state.missing ? 'not_found' : 'error' } />;
22
40
  }
23
41
 
24
42
  return this.props.children;
25
43
  }
26
44
  }
27
45
 
28
- export default ErrorBoundary;
46
+ export default ErrorBoundary;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/providers",
3
- "version": "1.40.1",
3
+ "version": "1.40.2",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts"
package/services.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { useSuspenseQuery, UseSuspenseQueryResult } from '@tanstack/react-query';
2
+ import i18next from 'i18next';
2
3
  import apiClient from './Queries/apiClient';
3
4
  import { SettingsData, MenuData } from './types/settings';
4
5
  import useMenuStore from './stores/menu';
@@ -20,8 +21,18 @@ export const useGetSettings = (): UseSuspenseQueryResult<SettingsData> => (
20
21
  export const useGetMenu = (): UseSuspenseQueryResult<MenuData> => {
21
22
  const menuStore = useMenuStore();
22
23
 
24
+ /*
25
+ * Edited: Claude - Date: 2026-08-22 (audit finding CMS-07b)
26
+ *
27
+ * The language belongs in the key. obtapi localises the menu labels off
28
+ * Content-Language, which the client and BFF both send correctly - but the
29
+ * result was cached under a language-blind key, so the menu was fetched
30
+ * once (in whatever language was active at bootstrap, usually English) and
31
+ * a later switch never refetched it. Keying on the active language makes a
32
+ * switch load - and cache - that language's labels.
33
+ */
23
34
  return useSuspenseQuery({
24
- queryKey: ['get-menu'],
35
+ queryKey: ['get-menu', i18next.language],
25
36
  queryFn: async () => (
26
37
  await apiClient
27
38
  .get('/api/menus/get')