@saooti/octopus-sdk 41.12.1-beta2 → 41.12.1
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/.claude/settings.local.json +9 -1
- package/CHANGELOG.md +3 -14
- package/PLAN-fix-dist-bare-imports.md +122 -0
- package/PLAN_test_utils_single_entry.md +194 -0
- package/TO_SLOT.md +43 -0
- package/package.json +1 -1
- package/src/api/rubriquesApi.ts +0 -13
- package/src/components/display/filter/AdvancedSearch.vue +0 -6
- package/src/components/layouts/PresentationLayout.vue +4 -1
- package/src/components/misc/ClassicNotifications.vue +1 -4
- package/src/components/pages/PlaylistsPage.vue +1 -0
- package/src/helper/downloadHelper.ts +23 -12
- package/src/stores/AuthStore.ts +1 -2
- package/src/stores/NotificationStore.ts +0 -6
- package/BUILD_FIX.md +0 -105
|
@@ -11,7 +11,15 @@
|
|
|
11
11
|
"Bash(npm:*)",
|
|
12
12
|
"Bash(npx vitest:*)",
|
|
13
13
|
"Bash(./node_modules/.bin/vitest run:*)",
|
|
14
|
-
"Bash(npx eslint:*)"
|
|
14
|
+
"Bash(npx eslint:*)",
|
|
15
|
+
"Bash(node -e \"console.log\\(require.resolve\\('./package.json'\\)\\)\")",
|
|
16
|
+
"Bash(node --experimental-vm-modules -e ' *)",
|
|
17
|
+
"Bash(node -e ' *)",
|
|
18
|
+
"Read(//home/julien/Workspace/frontoffice/code/frontend/**)",
|
|
19
|
+
"Read(//home/julien/Workspace/frontoffice/**)",
|
|
20
|
+
"Bash(git rm *)",
|
|
21
|
+
"Bash(grep -vE '\\\\-[A-Za-z0-9_-]{8}\\\\.mjs$')",
|
|
22
|
+
"Bash(grep -E '\\\\-[A-Za-z0-9_-]{8}\\\\.mjs$')"
|
|
15
23
|
]
|
|
16
24
|
}
|
|
17
25
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
-
## 41.12.1 (
|
|
3
|
+
## 41.12.1 (19/08/2026)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- Ajout de nouvelles fonctions dans l'api `rubriqueApi`
|
|
8
|
-
- Option de `AdvancedSearch` pour ne pas afficher le filtre de groupe
|
|
9
|
-
- Ajout callback sur fermeture de notifications
|
|
10
|
-
|
|
11
|
-
**Fixes**
|
|
12
|
-
|
|
13
|
-
- Correction d'une anomalie de chargement du style de la modale utilisée par
|
|
14
|
-
`ClassicNotifications`
|
|
15
|
-
|
|
16
|
-
**Misc**
|
|
5
|
+
### Fixes
|
|
17
6
|
|
|
18
|
-
-
|
|
7
|
+
- Gestion des erreurs dans downloadHelper
|
|
19
8
|
|
|
20
9
|
## 41.12.0 (13/07/2026)
|
|
21
10
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Plan: fix octopus-sdk's dist output for plain `npm install` consumers
|
|
2
|
+
|
|
3
|
+
## Background
|
|
4
|
+
|
|
5
|
+
Consumer apps (frontoffice, podcastmaker) currently only pass their test
|
|
6
|
+
suites against `@saooti/octopus-sdk` when it is `npm link`ed to this repo.
|
|
7
|
+
A plain `npm install` of the published package breaks Vitest in those repos
|
|
8
|
+
with:
|
|
9
|
+
|
|
10
|
+
- `TypeError: Unknown file extension ".vue"` for
|
|
11
|
+
`vue-material-design-icons/*.vue`
|
|
12
|
+
- `Error: Cannot find module '.../dayjs/locale/de' ... Did you mean
|
|
13
|
+
"dayjs/locale/de.js"?`
|
|
14
|
+
|
|
15
|
+
Vitest externalizes normal `node_modules` packages by default and lets
|
|
16
|
+
Node's native ESM resolver load them directly. That resolver can't handle a
|
|
17
|
+
raw `.vue` specifier, and — since `dayjs` ships no `"exports"` map — it
|
|
18
|
+
requires exact file names for subpath imports. This only "worked" when the
|
|
19
|
+
SDK was npm-linked because a linked package resolves outside `node_modules`
|
|
20
|
+
and dodges Vitest's externalization heuristic, letting Vite's own resolver
|
|
21
|
+
(which is lenient about extensions and knows `.vue`) handle it instead. That
|
|
22
|
+
was incidental, not a real fix, and consumer repos currently paper over it
|
|
23
|
+
with a `test.server.deps.inline` entry in their `vitest.config.js`.
|
|
24
|
+
|
|
25
|
+
Root cause is in this repo's `vite.config.js` build config, not in the
|
|
26
|
+
consumer apps.
|
|
27
|
+
|
|
28
|
+
## Root causes
|
|
29
|
+
|
|
30
|
+
1. **`vue-material-design-icons` externalized wholesale.** The `external`
|
|
31
|
+
callback in `vite.config.js` externalizes every bare (non-relative,
|
|
32
|
+
non-`@/`) import indiscriminately. `vue-material-design-icons` ships raw
|
|
33
|
+
`.vue` SFCs rather than pre-compiled JS, so externalizing it re-emits
|
|
34
|
+
`import X from "vue-material-design-icons/ChevronDown.vue"` verbatim into
|
|
35
|
+
`dist/*.mjs`. Confirmed via:
|
|
36
|
+
```sh
|
|
37
|
+
grep -rhoE 'from "[^".][^"]*\.vue"' dist/*.mjs | sort -u
|
|
38
|
+
```
|
|
39
|
+
→ 58 distinct `vue-material-design-icons/*.vue` specifiers across the
|
|
40
|
+
dist chunks.
|
|
41
|
+
|
|
42
|
+
2. **`dayjs/locale/*` imported without an extension.**
|
|
43
|
+
`src/components/composable/useDayjs.ts` has:
|
|
44
|
+
```ts
|
|
45
|
+
import "dayjs/locale/de";
|
|
46
|
+
import "dayjs/locale/es";
|
|
47
|
+
import "dayjs/locale/fr";
|
|
48
|
+
import "dayjs/locale/it";
|
|
49
|
+
import "dayjs/locale/sl";
|
|
50
|
+
```
|
|
51
|
+
`dayjs` has no `"exports"` map in its `package.json`, so Node's strict ESM
|
|
52
|
+
resolver needs the exact file name.
|
|
53
|
+
|
|
54
|
+
Swept the rest of `dist/*.mjs` for other bare/extensionless external
|
|
55
|
+
specifiers (`grep -rhoE 'from "[^".][^"]*"' *.mjs`, filtered against the
|
|
56
|
+
known peer/runtime deps) — nothing else came back. `qrcode.vue` is a real
|
|
57
|
+
package name (its own `package.json` resolves it), not a raw SFC path, so
|
|
58
|
+
it's fine as-is. No other externalized package (`video.js`, `vue-select`,
|
|
59
|
+
etc.) needs bundling.
|
|
60
|
+
|
|
61
|
+
## Steps
|
|
62
|
+
|
|
63
|
+
### 1. Bundle `vue-material-design-icons` instead of externalizing it
|
|
64
|
+
|
|
65
|
+
In `vite.config.js`, change the `external` callback:
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
external: (id) =>
|
|
69
|
+
!id.startsWith('vue-material-design-icons') &&
|
|
70
|
+
!id.startsWith('.') && !id.startsWith('@/') && !id.startsWith('@tests/') && !path.isAbsolute(id)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The `vue()` plugin is already part of the build pipeline, so Rollup will
|
|
74
|
+
compile these icon SFCs into plain JS as part of the bundle — no raw `.vue`
|
|
75
|
+
specifier will remain in `dist`. Icons are tiny SVG wrappers, so this is a
|
|
76
|
+
negligible size cost spread across existing chunks.
|
|
77
|
+
|
|
78
|
+
### 2. Fully-specify the dayjs locale imports
|
|
79
|
+
|
|
80
|
+
In `src/components/composable/useDayjs.ts`, add `.js` to all five locale
|
|
81
|
+
imports:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import "dayjs/locale/de.js";
|
|
85
|
+
import "dayjs/locale/es.js";
|
|
86
|
+
import "dayjs/locale/fr.js";
|
|
87
|
+
import "dayjs/locale/it.js";
|
|
88
|
+
import "dayjs/locale/sl.js";
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`dayjs` stays a peer dependency (correct — consumer apps must own a single
|
|
92
|
+
dayjs instance); only the specifier changes.
|
|
93
|
+
|
|
94
|
+
### 3. Verify
|
|
95
|
+
|
|
96
|
+
- Full rebuild (`npm run build`) and re-run the `grep -rhoE 'from
|
|
97
|
+
"[^".][^"]*"' *.mjs` sweep over `dist/` — should come back clean of raw
|
|
98
|
+
`.vue` and extensionless subpath imports.
|
|
99
|
+
- In `frontoffice/code/frontend`: remove the `@saooti/octopus-sdk` symlink,
|
|
100
|
+
do a plain `npm install @saooti/octopus-sdk@<new version>`, remove the
|
|
101
|
+
`test.server.deps.inline` entry from `vitest.config.js`, and run the full
|
|
102
|
+
test suite — should still be green.
|
|
103
|
+
- Repeat the same unlink/reinstall/remove-inline/test check in
|
|
104
|
+
`podcastmaker`, since it depends on the same SDK and would hit (or has
|
|
105
|
+
hit) the identical failure.
|
|
106
|
+
|
|
107
|
+
### 4. Cleanup once verified
|
|
108
|
+
|
|
109
|
+
- Remove the `test.server.deps.inline: ['@saooti/octopus-sdk',
|
|
110
|
+
'vue-material-design-icons']` block from `frontend/vitest.config.js` (and
|
|
111
|
+
podcastmaker's equivalent, if it was ever added there).
|
|
112
|
+
- Leave the existing dev-mode `optimizeDeps.exclude` / `server.fs.allow`
|
|
113
|
+
npm-link accommodations in the consumer apps' `vite.config.js` alone —
|
|
114
|
+
those are about local-dev HMR ergonomics when linked, unrelated to this
|
|
115
|
+
test-time module resolution bug.
|
|
116
|
+
|
|
117
|
+
## Expected outcome
|
|
118
|
+
|
|
119
|
+
Once `dist/*.mjs` contains only specifiers Node's native ESM resolver can
|
|
120
|
+
load unassisted, Vitest's default externalization of `node_modules`
|
|
121
|
+
packages works correctly for a plain `npm install` of `@saooti/octopus-sdk`
|
|
122
|
+
— no `deps.inline` workaround needed in any consumer app.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Plan: single bundled entry point for octopus-sdk test utilities
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
octopus-sdk is consumed by frontoffice (and potentially podcastmaker) via
|
|
6
|
+
`npm link`. Frontoffice's Vite/Vitest and octopus-sdk's own Vite config both
|
|
7
|
+
define a global `@` alias pointing at their *own* `src/`. Because linked
|
|
8
|
+
packages are transformed from raw source (not the built `dist/`), any
|
|
9
|
+
octopus-sdk source file that imports something via `@/...` gets that alias
|
|
10
|
+
resolved against **frontoffice's** `src/` when transformed inside frontoffice's
|
|
11
|
+
Vite instance — wrong target, resolution failure.
|
|
12
|
+
|
|
13
|
+
This was already fixed for octopus-sdk's main bundle: `vite.config.js` builds
|
|
14
|
+
`index.ts` to `dist/index.mjs` with `@/...` imports resolved and inlined at
|
|
15
|
+
SDK build time (see `rollupOptions.external`), so consumers importing
|
|
16
|
+
`@saooti/octopus-sdk` never hit raw source needing alias resolution.
|
|
17
|
+
|
|
18
|
+
The gap: octopus-sdk's **test utilities** (`tests/utils.ts`,
|
|
19
|
+
`tests/mocks/*.ts`) are exported via `package.json`'s
|
|
20
|
+
`"./tests/*": "./tests/*"`, which passes through raw `.ts` source
|
|
21
|
+
unconditionally. Frontoffice's `tests/utils.ts` and ~70 spec files import
|
|
22
|
+
these paths directly, so they hit the same alias collision whenever the
|
|
23
|
+
SDK source touches `@/...` (e.g. `AuthStore.ts` now imports
|
|
24
|
+
`rubriquesApi` from `@/api`, which is a *transitive* import from
|
|
25
|
+
`tests/utils.ts` importing `useAuthStore`).
|
|
26
|
+
|
|
27
|
+
## Decision
|
|
28
|
+
|
|
29
|
+
Bundle the test utilities into **one** built entry point, `dist/tests.mjs`,
|
|
30
|
+
built the same way as the main `index.mjs` (aliases resolved at SDK build
|
|
31
|
+
time). Consumers import everything from one path:
|
|
32
|
+
`@saooti/octopus-sdk/tests`.
|
|
33
|
+
|
|
34
|
+
This is *not* just a mechanical repackaging: the current `tests/mocks/i18n.ts`
|
|
35
|
+
and `tests/mocks/useRouter.ts` work by **side effect** — importing the file
|
|
36
|
+
calls `vi.mock(...)` at module-evaluation time. That only works because ES
|
|
37
|
+
module imports are evaluated in source order relative to other imports in the
|
|
38
|
+
importing file, and each of these mock files is imported as the very first
|
|
39
|
+
line of ~70 spec files. If those files were merged into one shared module
|
|
40
|
+
naively, importing that module would force *both* mocks (vue-i18n AND
|
|
41
|
+
vue-router) onto every spec file that imports it — a real behavior change for
|
|
42
|
+
specs that don't want vue-router mocked, and a correctness risk for anything
|
|
43
|
+
that relies on the real router.
|
|
44
|
+
|
|
45
|
+
**Fix: turn the mock modules into plain factory functions with no import-time
|
|
46
|
+
side effects, and have each spec file call `vi.mock()` explicitly, referencing
|
|
47
|
+
the imported factory.** This is Vitest's own documented supported pattern:
|
|
48
|
+
`vi.mock()` calls are hoisted above imports by Vitest's transform, and a
|
|
49
|
+
factory argument may reference an imported identifier as long as that
|
|
50
|
+
identifier's name is prefixed `mock` (Vitest hoists that specific import
|
|
51
|
+
alongside the `vi.mock` call). Concretely:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
// before (side effect, implicit)
|
|
55
|
+
import '@saooti/octopus-sdk/tests/mocks/i18n';
|
|
56
|
+
|
|
57
|
+
// after (explicit, still correctly hoisted)
|
|
58
|
+
import { mockI18n } from '@saooti/octopus-sdk/tests';
|
|
59
|
+
vi.mock('vue-i18n', mockI18n);
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This keeps mocking fully selective per spec file, fixes the alias-collision
|
|
63
|
+
bug at the root (SDK build resolves its own aliases), and gives a single,
|
|
64
|
+
low-maintenance entry point rather than a hand-maintained list of build
|
|
65
|
+
entries per mock file.
|
|
66
|
+
|
|
67
|
+
## Steps
|
|
68
|
+
|
|
69
|
+
### 1. octopus-sdk: convert mock modules to factories
|
|
70
|
+
|
|
71
|
+
- `tests/mocks/i18n.ts`: change from a `vi.mock(...)` side-effect call to
|
|
72
|
+
`export function mockI18n() { return { useI18n: () => ({...}), createI18n: () => {} }; }`
|
|
73
|
+
(same object literal as today, just returned instead of passed inline).
|
|
74
|
+
- `tests/mocks/useRouter.ts`: same transform →
|
|
75
|
+
`export function mockUseRouter() { return { useRoute: () => ({...}), useRouter: () => ({...}) }; }`.
|
|
76
|
+
- `tests/mocks/useAdvancedParamInit.ts`: same transform →
|
|
77
|
+
`export function mockAdvancedParamInit() { return { useAdvancedParamInit: () => ({...}) }; }`.
|
|
78
|
+
Note this one mocks an SDK-internal path (`@/components/composable/route/useAdvancedParamInit`),
|
|
79
|
+
not a third-party package — keep that target path as-is, only the
|
|
80
|
+
side-effect-to-factory conversion changes.
|
|
81
|
+
- `tests/mocks/rights.ts` (`mockEmission`, `mockPodcast`): no behavior change
|
|
82
|
+
needed, already plain functions — just gets folded into the same bundle.
|
|
83
|
+
|
|
84
|
+
### 2. octopus-sdk: single entry point
|
|
85
|
+
|
|
86
|
+
- Create `tests/index.ts` that re-exports everything currently split across
|
|
87
|
+
`tests/utils.ts` and `tests/mocks/*.ts`: `mount`, `VueWrapper`,
|
|
88
|
+
`localisation`, `setupAuthStore`, `setupPlayerStore`, `combineStoreSetups`,
|
|
89
|
+
`setupPinia`, `mockI18n`, `mockUseRouter`, `mockAdvancedParamInit`,
|
|
90
|
+
`mockEmission`, `mockPodcast`.
|
|
91
|
+
(Either keep `tests/utils.ts` as the implementation file and have
|
|
92
|
+
`tests/index.ts` just re-export, or merge directly — whichever keeps the
|
|
93
|
+
smaller diff.)
|
|
94
|
+
- `vite.config.js`: change `build.lib.entry` from a single string to an
|
|
95
|
+
object with two entries:
|
|
96
|
+
```js
|
|
97
|
+
entry: {
|
|
98
|
+
index: path.resolve(__dirname, 'index.ts'),
|
|
99
|
+
tests: path.resolve(__dirname, 'tests/index.ts'),
|
|
100
|
+
},
|
|
101
|
+
fileName: (_format, entryName) => `${entryName}.mjs`,
|
|
102
|
+
```
|
|
103
|
+
Keep the existing `resolve.alias` (`@`, `@tests`, `vue`, `hls.js`) — the
|
|
104
|
+
`@tests` alias already needs to exist here (not just in `vitest.config.js`)
|
|
105
|
+
since `tests/mocks/i18n.ts` references `@tests/utils` internally; this was
|
|
106
|
+
already added to `vite.config.js` in a prior WIP pass on this branch — verify
|
|
107
|
+
it's still there, add it if not, and drop the now-redundant duplicate alias
|
|
108
|
+
from `vitest.config.js`.
|
|
109
|
+
- `cleanStaleChunks()` (in `vite.config.js`) currently only scans the top level
|
|
110
|
+
of `dist/`. With `tests: '...'` as an entry name (no `/` in it, unlike the
|
|
111
|
+
earlier multi-entry draft), output stays flat as `dist/tests.mjs` — no
|
|
112
|
+
recursive scanning needed. Confirm this after building; only revisit if the
|
|
113
|
+
entry name changes to something with a path segment.
|
|
114
|
+
- `package.json` `exports`: replace `"./tests/*": "./tests/*"` with
|
|
115
|
+
```json
|
|
116
|
+
"./tests": {
|
|
117
|
+
"types": "./tests/index.ts",
|
|
118
|
+
"default": "./dist/tests.mjs"
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
(`types` points at raw `.ts` source, same as today's behavior — no need for
|
|
122
|
+
`unplugin-dts` to cover this entry.)
|
|
123
|
+
|
|
124
|
+
### 3. octopus-sdk: migrate its own internal specs (36 files)
|
|
125
|
+
|
|
126
|
+
octopus-sdk's own test suite imports `tests/mocks/i18n`, `tests/mocks/useRouter`,
|
|
127
|
+
`tests/mocks/useAdvancedParamInit` directly too (`grep -rl "mocks/i18n\|mocks/useRouter\|mocks/useAdvancedParamInit\|mocks/rights" tests --include="*.spec.ts"` → 36 files as of this writing). Each needs the same
|
|
128
|
+
mechanical rewrite as frontoffice (step 4). Since these are same-repo,
|
|
129
|
+
relative imports (e.g. `from '../mocks/i18n'` or `@tests/mocks/i18n`) — adjust
|
|
130
|
+
the codemod pattern accordingly, or just import from the new `@tests` (i.e.
|
|
131
|
+
`tests/index.ts`) alias directly.
|
|
132
|
+
|
|
133
|
+
### 4. frontoffice: migrate consumer imports
|
|
134
|
+
|
|
135
|
+
- `tests/utils.ts`: change
|
|
136
|
+
```ts
|
|
137
|
+
export { mount, VueWrapper } from '@saooti/octopus-sdk/tests/utils';
|
|
138
|
+
export { setupAuthStore, combineStoreSetups, setupPinia } from '@saooti/octopus-sdk/tests/utils';
|
|
139
|
+
```
|
|
140
|
+
to import from `'@saooti/octopus-sdk/tests'` instead, and additionally
|
|
141
|
+
re-export `mockI18n`, `mockUseRouter` (and `mockAdvancedParamInit`,
|
|
142
|
+
`mockEmission`, `mockPodcast` if useful) so spec files can keep pulling
|
|
143
|
+
everything from the local `@tests/utils` alias as they do today.
|
|
144
|
+
- Mechanical codemod across spec files (66 files for i18n, 6 for useRouter —
|
|
145
|
+
counts as of this writing, re-run the greps below to confirm current
|
|
146
|
+
numbers):
|
|
147
|
+
```
|
|
148
|
+
grep -rl "octopus-sdk/tests/mocks/i18n" tests
|
|
149
|
+
grep -rl "octopus-sdk/tests/mocks/useRouter" tests
|
|
150
|
+
```
|
|
151
|
+
Replace:
|
|
152
|
+
```ts
|
|
153
|
+
import '@saooti/octopus-sdk/tests/mocks/i18n';
|
|
154
|
+
```
|
|
155
|
+
with:
|
|
156
|
+
```ts
|
|
157
|
+
import { mockI18n } from '@tests/utils';
|
|
158
|
+
vi.mock('vue-i18n', mockI18n);
|
|
159
|
+
```
|
|
160
|
+
(needs `import { vi } from 'vitest';` present — most spec files already
|
|
161
|
+
import `vi` for other reasons; add it where missing.)
|
|
162
|
+
Same pattern for `useRouter`:
|
|
163
|
+
```ts
|
|
164
|
+
import { mockUseRouter } from '@tests/utils';
|
|
165
|
+
vi.mock('vue-router', mockUseRouter);
|
|
166
|
+
```
|
|
167
|
+
This is regular enough to script with a small codemod (sed/ts-morph) rather
|
|
168
|
+
than hand-editing 70+ files — verify the mechanical replacement still lets
|
|
169
|
+
each file pass its own tests, since ordering (mock call before other
|
|
170
|
+
imports that transitively pull in `vue-i18n`/`vue-router`) still matters:
|
|
171
|
+
place these two lines where the old side-effect import used to be
|
|
172
|
+
(typically line 1) to preserve the same evaluation order.
|
|
173
|
+
|
|
174
|
+
### 5. Verify
|
|
175
|
+
|
|
176
|
+
- `cd octopus-sdk && npm run build` — confirm `dist/tests.mjs` is produced and
|
|
177
|
+
`dist/index.mjs` still builds correctly.
|
|
178
|
+
- `cd octopus-sdk && npx vitest run` — full SDK suite green after step 3.
|
|
179
|
+
- `cd frontoffice/code/frontend && npx vitest run` — full frontend suite green
|
|
180
|
+
after step 4. Pay particular attention to any spec that relies on **real**
|
|
181
|
+
`vue-router` behavior today (i.e. does *not* currently import the
|
|
182
|
+
`useRouter` mock) — confirm the codemod didn't accidentally add a
|
|
183
|
+
`vi.mock('vue-router', ...)` call to those.
|
|
184
|
+
- Run `npm run lint` on all touched files in both repos (touched files only,
|
|
185
|
+
no `--fix`-then-commit sweep, per project convention).
|
|
186
|
+
|
|
187
|
+
### Out of scope
|
|
188
|
+
|
|
189
|
+
- `"./src/*"` export mapping (raw source passthrough) is untouched — it's
|
|
190
|
+
used extensively by non-test app code in frontoffice (`main.ts`, `router.ts`,
|
|
191
|
+
several components) and is a separate, larger concern than test utilities.
|
|
192
|
+
- podcastmaker: searched at plan-writing time, found no references to
|
|
193
|
+
`octopus-sdk/tests/*` — re-check before assuming it's unaffected, in case
|
|
194
|
+
that changes before this plan is implemented.
|
package/TO_SLOT.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Stub components converted to scoped slots
|
|
2
|
+
|
|
3
|
+
The SDK used to ship several "stub" components — empty `<div />` placeholders —
|
|
4
|
+
that were overridden by the real frontoffice implementation at build time via
|
|
5
|
+
an implicit Vite alias trick. That trick breaks once the SDK is pre-built as a
|
|
6
|
+
library (see `~/Documents/FIX_BUILD_SDK.md`), so each usage was moved to an
|
|
7
|
+
explicit scoped-slot API instead (or, for two deeply-nested cases, to runtime
|
|
8
|
+
global component resolution — see below). All identified stubs are now
|
|
9
|
+
converted; the stub `.vue` files themselves have been deleted since nothing in
|
|
10
|
+
the SDK references them by import anymore.
|
|
11
|
+
|
|
12
|
+
- `EditBox.vue` (deleted)
|
|
13
|
+
- `EmissionPage.vue` — **Done** (`#edit-box` slot)
|
|
14
|
+
- `ParticipantPage.vue` — **Done** (`#edit-box` slot)
|
|
15
|
+
- `PlaylistPage.vue` — **Done** (`#edit-box` slot)
|
|
16
|
+
- `PodcastModuleBox.vue` — **Done** (`#edit-box` slot, passed through `PodcastPage.vue`)
|
|
17
|
+
- `EditBoxRadio.vue` (deleted)
|
|
18
|
+
- `RadioPage.vue` — **Done** (`#edit-box-radio` slot)
|
|
19
|
+
- `RecordingItemButton.vue` (deleted)
|
|
20
|
+
- `PodcastModuleBox.vue` — **Done** (`#recording-item-button` slot, passed through `PodcastPage.vue`)
|
|
21
|
+
- `RssSection.vue` (deleted) / `CommentMoreActionsAdmin.vue` (deleted)
|
|
22
|
+
- `ClipboardModal.vue`, `CommentMoreActions.vue` — **Done**, but via a different mechanism than the rest of this list. Both stubs are reached through multiple, and in the comments case recursive, layers of intermediate components (`ClipboardModal` is reached from 5 independent top-level pages via `ShareAnonymous`; `CommentMoreActions` is 4 layers deep under `CommentSection`/`CommentList`/`CommentItem`, which are self-recursive for comment replies). Threading scoped slots through every layer/entry point wasn't practical here, so instead the SDK leaves the bare `<RssSection>`/`<CommentMoreActionsAdmin>` tags unimported in `ClipboardModal.vue`/`CommentMoreActions.vue` and lets Vue resolve them at runtime against the consuming app's global component registry. The consuming app registers the real implementations once via `app.component("RssSection", ...)` / `app.component("CommentMoreActionsAdmin", ...)` (see frontoffice's `main.ts`). Apps that don't register them simply render nothing there (a dev-only console warning, stripped in prod).
|
|
23
|
+
|
|
24
|
+
## Non-stub `@/`-alias collisions fixed via provide/inject
|
|
25
|
+
|
|
26
|
+
A follow-up audit found the same `@/`-alias collision affecting real (non-stub)
|
|
27
|
+
SDK code, not just placeholder components: SDK source importing a path via
|
|
28
|
+
`@/...` that happens to collide with an unrelated frontoffice file at the same
|
|
29
|
+
relative path, where the SDK genuinely depended on frontoffice's version to
|
|
30
|
+
work correctly. Unlike the component stubs, these aren't extension points by
|
|
31
|
+
design, and duplicating frontoffice's logic into the SDK isn't appropriate
|
|
32
|
+
(the real implementation is either backend-contract-specific or pulls in
|
|
33
|
+
frontoffice-only data), so both were fixed with Vue's `provide`/`inject`
|
|
34
|
+
instead: the SDK exposes an injection key with a safe default (its own
|
|
35
|
+
implementation), and frontoffice provides its richer implementation once at
|
|
36
|
+
the app root (`app.provide(...)` in `main.ts`, alongside the `app.component()`
|
|
37
|
+
calls above). Keys are defined in `src/components/composable/keys.ts` and
|
|
38
|
+
re-exported from the root `index.ts`.
|
|
39
|
+
|
|
40
|
+
- `api/initialize.ts` (`checkToken`)
|
|
41
|
+
- `RecaptchaModal.vue` — **Done**. SDK's own `api/initialize.ts` never defined `checkToken` (only frontoffice's override did), yet `RecaptchaModal.vue` called it — a live bug in waiting. Now resolved via `inject(CHECK_TOKEN_KEY, async () => true)`; the SDK no longer imports `@/api/initialize` at all. `sendMail` (frontoffice-only, unused by the SDK) was left untouched.
|
|
42
|
+
- `i18n.ts` (`loadLocaleMessages`)
|
|
43
|
+
- `FooterSection.vue` — **Done**. Frontoffice's `loadLocaleMessages` merges ~13 frontoffice-only locale bundles into the message set; SDK's own version only loads its base translations, and `setLocaleMessage` replaces rather than merges — so an un-aliased SDK call would have wiped most of the app's translated UI text on every language switch. Now resolved via `inject(LOAD_LOCALE_MESSAGES_KEY, loadSdkLocaleMessages)`, defaulting to the SDK's own loader.
|
package/package.json
CHANGED
package/src/api/rubriquesApi.ts
CHANGED
|
@@ -24,18 +24,6 @@ async function searchRubriquages(organisationIds: Array<string>, searchOptions?:
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* Fetch rubriquage data by ID
|
|
29
|
-
* @param rubriquageId ID of the rubriquage to fetch
|
|
30
|
-
* @returns The rubriquage
|
|
31
|
-
*/
|
|
32
|
-
async function getRubriquage(rubriquageId: number): Promise<Rubriquage> {
|
|
33
|
-
return classicApi.fetchData<Rubriquage>({
|
|
34
|
-
api: ModuleApi.DEFAULT,
|
|
35
|
-
path: `rubriquage/${rubriquageId}`
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
27
|
async function searchRubriques(searchOptions?: {
|
|
40
28
|
rubriquageId?: number;
|
|
41
29
|
organisationId?: string|Array<string>;
|
|
@@ -73,7 +61,6 @@ async function getCachedRubrique(rubriqueId: number): Promise<Rubrique> {
|
|
|
73
61
|
}
|
|
74
62
|
|
|
75
63
|
export const rubriquesApi = {
|
|
76
|
-
getRubriquage,
|
|
77
64
|
getRubrique,
|
|
78
65
|
getCachedRubrique,
|
|
79
66
|
searchRubriquages,
|
|
@@ -181,8 +181,6 @@ const props = withDefaults(defineProps<{
|
|
|
181
181
|
rubriqueFilter?: Array<RubriquageFilter>;
|
|
182
182
|
/** The filter on groups */
|
|
183
183
|
emissionGroups?: Array<EmissionGroup>;
|
|
184
|
-
/** Force hide the emission group filter */
|
|
185
|
-
hideEmissionGroups?: boolean;
|
|
186
184
|
}>(), {
|
|
187
185
|
sort: "DATE",
|
|
188
186
|
monetisable: "UNDEFINED",
|
|
@@ -219,10 +217,6 @@ const filterStore = useFilterStore();
|
|
|
219
217
|
const authStore = useAuthStore();
|
|
220
218
|
|
|
221
219
|
onMounted(async() => {
|
|
222
|
-
if (props.hideEmissionGroups) {
|
|
223
|
-
showEmissionGroups.value = false;
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
220
|
// Only show emission groups if there are some
|
|
227
221
|
const nbGroups = await groupsApi.count({
|
|
228
222
|
organisationIds: [props.organisationId]
|
|
@@ -14,10 +14,7 @@
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
15
|
import { storeToRefs } from 'pinia';
|
|
16
16
|
import { useNotificationStore } from '../../stores/NotificationStore';
|
|
17
|
-
|
|
18
|
-
const MessageModal = defineAsyncComponent(() => import('./modal/MessageModal.vue'));
|
|
19
|
-
|
|
20
|
-
import { defineAsyncComponent } from 'vue';
|
|
17
|
+
import MessageModal from './modal/MessageModal.vue';
|
|
21
18
|
|
|
22
19
|
const {
|
|
23
20
|
clearNotification
|
|
@@ -14,17 +14,28 @@ export default {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
xhr.responseType = "blob";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
|
|
18
|
+
return new Promise<void>((resolve, reject) => {
|
|
19
|
+
xhr.onload = function () {
|
|
20
|
+
if (xhr.status !== 200) {
|
|
21
|
+
reject(new Error(`Download failed with status ${xhr.status}`));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const urlCreator = window.URL || window.webkitURL;
|
|
25
|
+
const imageUrl = urlCreator.createObjectURL(this.response);
|
|
26
|
+
const tag = document.createElement("a");
|
|
27
|
+
tag.href = imageUrl;
|
|
28
|
+
tag.target = "_blank";
|
|
29
|
+
tag.download = nameOfDownload.replace(/ /g, "_");
|
|
30
|
+
document.body.appendChild(tag);
|
|
31
|
+
tag.click();
|
|
32
|
+
document.body.removeChild(tag);
|
|
33
|
+
resolve();
|
|
34
|
+
};
|
|
35
|
+
xhr.onerror = function () {
|
|
36
|
+
reject(new Error("Download failed"));
|
|
37
|
+
};
|
|
38
|
+
xhr.send();
|
|
39
|
+
});
|
|
29
40
|
},
|
|
30
41
|
};
|
package/src/stores/AuthStore.ts
CHANGED
|
@@ -227,8 +227,7 @@ export const useAuthStore = defineStore("AuthStore", {
|
|
|
227
227
|
});
|
|
228
228
|
this.authUpdateOrganisation(activeOrganisation);
|
|
229
229
|
this.fetchProfileAsynchrone();
|
|
230
|
-
} catch
|
|
231
|
-
console.error(error);
|
|
230
|
+
} catch {
|
|
232
231
|
if (this.authReload > 5) {
|
|
233
232
|
return;
|
|
234
233
|
}
|
|
@@ -15,8 +15,6 @@ interface Notification {
|
|
|
15
15
|
type: NotificationType;
|
|
16
16
|
/** When set to false, disallow manual closing of modal notification (default: true) */
|
|
17
17
|
closeable?: boolean;
|
|
18
|
-
/** Callback called when the notification is closed */
|
|
19
|
-
closeCallback?: () => void;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
export const useNotificationStore = defineStore('notifications', () => {
|
|
@@ -36,10 +34,6 @@ export const useNotificationStore = defineStore('notifications', () => {
|
|
|
36
34
|
if (notif !== null) {
|
|
37
35
|
const idx = notificationQueue.value.indexOf(notif);
|
|
38
36
|
notificationQueue.value.splice(idx, 1);
|
|
39
|
-
|
|
40
|
-
if (notif.closeCallback) {
|
|
41
|
-
notif.closeCallback();
|
|
42
|
-
}
|
|
43
37
|
}
|
|
44
38
|
}
|
|
45
39
|
|
package/BUILD_FIX.md
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# Fixing `@` alias resolution when consumed by other projects
|
|
2
|
-
|
|
3
|
-
## Problem
|
|
4
|
-
|
|
5
|
-
`octopus-sdk` currently publishes raw TypeScript source. When a consumer (e.g. frontoffice)
|
|
6
|
-
bundles the SDK, it processes source files with its own Vite config, so `@/` imports resolve
|
|
7
|
-
against the consumer's `src/` instead of the SDK's. This affects both dev and production builds.
|
|
8
|
-
|
|
9
|
-
## Solution: build the SDK as a library
|
|
10
|
-
|
|
11
|
-
The SDK should be pre-built so all `@` aliases are resolved before any consumer sees the files.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 1. Install `vite-plugin-dts`
|
|
16
|
-
|
|
17
|
-
```sh
|
|
18
|
-
npm install -D vite-plugin-dts
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 2. Update `vite.config.js`
|
|
24
|
-
|
|
25
|
-
Add a `lib` build alongside the existing app config. The alias resolution in the `resolve` block
|
|
26
|
-
ensures `@` is rewritten to relative paths in the output.
|
|
27
|
-
|
|
28
|
-
```js
|
|
29
|
-
import dts from 'vite-plugin-dts';
|
|
30
|
-
|
|
31
|
-
// In the build config:
|
|
32
|
-
build: {
|
|
33
|
-
lib: {
|
|
34
|
-
entry: path.resolve(__dirname, 'index.ts'),
|
|
35
|
-
formats: ['es'],
|
|
36
|
-
fileName: 'index',
|
|
37
|
-
},
|
|
38
|
-
outDir: 'dist',
|
|
39
|
-
rollupOptions: {
|
|
40
|
-
// Mark all dependencies as external so they are not bundled
|
|
41
|
-
external: (id) => !id.startsWith('.') && !path.isAbsolute(id),
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
plugins: [
|
|
45
|
-
vue(),
|
|
46
|
-
dts({ rollupTypes: true }),
|
|
47
|
-
],
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Run `npm run build` to produce `dist/index.js` and `dist/index.d.ts`.
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## 3. Update `package.json`
|
|
55
|
-
|
|
56
|
-
Point `exports` to the built output instead of raw source:
|
|
57
|
-
|
|
58
|
-
```json
|
|
59
|
-
"exports": {
|
|
60
|
-
".": {
|
|
61
|
-
"types": "./dist/index.d.ts",
|
|
62
|
-
"default": "./dist/index.js"
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
"files": ["dist"]
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## 4. Development workflow
|
|
71
|
-
|
|
72
|
-
With a built package, `npm link` / `yalc link` alone is no longer enough — consumers need the
|
|
73
|
-
built output, not the source.
|
|
74
|
-
|
|
75
|
-
**Option A — watch build (recommended for active SDK development):**
|
|
76
|
-
|
|
77
|
-
```sh
|
|
78
|
-
# Terminal 1 — SDK
|
|
79
|
-
npm run build -- --watch
|
|
80
|
-
|
|
81
|
-
# Terminal 2 — frontoffice
|
|
82
|
-
npm run dev
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
frontoffice picks up changes via the symlink each time the SDK rebuild completes.
|
|
86
|
-
HMR in frontoffice will trigger on the rebuilt file, not on source edits directly.
|
|
87
|
-
|
|
88
|
-
**Option B — yalc push on change:**
|
|
89
|
-
|
|
90
|
-
```sh
|
|
91
|
-
# In octopus-sdk, after each change:
|
|
92
|
-
npm run build && yalc push
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
frontoffice receives the new build automatically if `yalc` is configured with `--watch`.
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## What to revert in frontoffice
|
|
100
|
-
|
|
101
|
-
Once the SDK is built, remove from frontoffice's `vite.config.js`:
|
|
102
|
-
|
|
103
|
-
- `optimizeDeps.exclude: ['@saooti/octopus-sdk']` — no longer needed
|
|
104
|
-
- `server.watch.ignored: ['!**/node_modules/@saooti/octopus-sdk/**']` — no longer needed
|
|
105
|
-
- `server.fs.allow: ['../../../octopus-sdk']` — no longer needed (for npm link setups)
|