@biffo/cli 0.313.3 → 0.314.0
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/_skeletons/plugin-template/biffo.plugin.json +14 -2
- package/_skeletons/plugin-template/pyproject.toml +6 -0
- package/_skeletons/plugin-template/src/example_plugin/admin_app.py +50 -0
- package/_skeletons/plugin-template/src/example_plugin/user_app.py +31 -0
- package/_skeletons/plugin-template/tests/test_example_plugin_ingress_surfaces.py +119 -0
- package/_skeletons/plugin-template/uv.lock +39 -0
- package/_skeletons/sibling-template/apps/frontend/package.json +2 -2
- package/_skeletons/sibling-template/apps/frontend/pnpm-lock.yaml +60 -64
- package/package.json +1 -1
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
}
|
|
81
81
|
],
|
|
82
82
|
"ui_components": [
|
|
83
|
-
{ "type": "nav-link", "label": "Example Plugin", "path": "/admin/example-plugin" },
|
|
84
|
-
{ "type": "page", "label": "Widgets", "path": "/admin/example-plugin/widgets" }
|
|
83
|
+
{ "type": "nav-link", "label": "Example Plugin", "path": "/admin/plugins/example-plugin" },
|
|
84
|
+
{ "type": "page", "label": "Widgets", "path": "/admin/plugins/example-plugin/widgets" }
|
|
85
85
|
],
|
|
86
86
|
"seed": {
|
|
87
87
|
"dir": "db/seed",
|
|
@@ -89,5 +89,17 @@
|
|
|
89
89
|
},
|
|
90
90
|
"dependencies": {
|
|
91
91
|
"biffo-plugin-sdk": "^1.0"
|
|
92
|
+
},
|
|
93
|
+
"user_ingress": {
|
|
94
|
+
"required_group": "founder",
|
|
95
|
+
"app": "example_plugin.user_app:app"
|
|
96
|
+
},
|
|
97
|
+
"admin_ingress": {
|
|
98
|
+
"required_group": "admin",
|
|
99
|
+
"app": "example_plugin.admin_app:app"
|
|
100
|
+
},
|
|
101
|
+
"user_frontend": {
|
|
102
|
+
"dir": "web/dist",
|
|
103
|
+
"required_group": "founder"
|
|
92
104
|
}
|
|
93
105
|
}
|
|
@@ -15,6 +15,12 @@ dependencies = [
|
|
|
15
15
|
"biffo-plugin-sdk>=1.0,<2.0",
|
|
16
16
|
"aws-lambda-powertools[tracer]>=3.4.0",
|
|
17
17
|
"httpx>=0.28.1",
|
|
18
|
+
# ASGI apps for the `user_ingress`/`admin_ingress` surfaces (ADR-0021) —
|
|
19
|
+
# the shared plugin host imports and mounts `<module>:app` directly, so this
|
|
20
|
+
# is the only new runtime dependency the two placeholder apps need (no
|
|
21
|
+
# mangum/pyjwt: the host provides the Lambda entry and enforces
|
|
22
|
+
# `required_group` itself — see user_app.py's docstring).
|
|
23
|
+
"fastapi>=0.115.0",
|
|
18
24
|
]
|
|
19
25
|
|
|
20
26
|
[dependency-groups]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Placeholder ASGI app backing this plugin's `admin_ingress` surface (ADR-0021).
|
|
2
|
+
|
|
3
|
+
`biffo.plugin.json`'s `admin_ingress.app` names this module's `app` object. The
|
|
4
|
+
**shared plugin host** imports it, provides the Lambda entry, and mounts it at
|
|
5
|
+
`/api/v1/plugins/<name>/admin/*`, enforcing `admin_ingress.required_group`
|
|
6
|
+
(ADR-0011) before a request ever reaches here — see `user_app.py`'s docstring
|
|
7
|
+
for why this file does no auth of its own.
|
|
8
|
+
|
|
9
|
+
**This is also `web-admin/`'s one reader (biffo-template#2008).** The skeleton
|
|
10
|
+
shipped a full admin frontend at `web-admin/` that no manifest field referenced
|
|
11
|
+
— an orphan directory nothing would ever build or serve. `AdminIngress` in the
|
|
12
|
+
SDK is explicitly "the plugin's admin-gated API and optional static UI bundle":
|
|
13
|
+
unlike `user_frontend` (a separate declarative `dir`, served directly by the
|
|
14
|
+
host with no plugin code involved), the admin surface's static bundle is served
|
|
15
|
+
*by the app this field names* — `web-admin/`'s own `vite.config.ts` already
|
|
16
|
+
targets exactly this mount point (`base:
|
|
17
|
+
'/api/v1/plugins/example-plugin/admin/'`).
|
|
18
|
+
|
|
19
|
+
`web-admin/dist/` is the Vite build output — gitignored, and not built by this
|
|
20
|
+
repo's CI (that wiring is follow-up work; #2008's scope is declaring the
|
|
21
|
+
surfaces, not shipping the built bundle, mirroring `user_frontend.dir` above
|
|
22
|
+
pointing at `web/dist` before that directory exists either — see #2009). The
|
|
23
|
+
mount below is skipped when `dist/` is absent, so a fresh checkout and `pytest`
|
|
24
|
+
need no build step and no edits (this issue's "done when" criterion) — once
|
|
25
|
+
`web-admin` is built, dropping its `dist/` in place is enough to serve it, with
|
|
26
|
+
no further code change.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
|
|
33
|
+
from fastapi import FastAPI
|
|
34
|
+
from fastapi.staticfiles import StaticFiles
|
|
35
|
+
|
|
36
|
+
app = FastAPI(title="example-plugin admin ingress")
|
|
37
|
+
|
|
38
|
+
# src/example_plugin/admin_app.py -> src/example_plugin -> src -> repo root
|
|
39
|
+
# (plugin root, where web-admin/ lives alongside biffo.plugin.json).
|
|
40
|
+
WEB_ADMIN_DIST = Path(__file__).resolve().parent.parent.parent / "web-admin" / "dist"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.get("/ping")
|
|
44
|
+
def ping() -> dict[str, str]:
|
|
45
|
+
"""Identifies the plugin, so the mount can be proven real rather than guessed at."""
|
|
46
|
+
return {"plugin": "example-plugin", "surface": "admin_ingress"}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if WEB_ADMIN_DIST.is_dir():
|
|
50
|
+
app.mount("/", StaticFiles(directory=str(WEB_ADMIN_DIST), html=True), name="web-admin")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Placeholder ASGI app backing this plugin's `user_ingress` surface (ADR-0021).
|
|
2
|
+
|
|
3
|
+
`biffo.plugin.json`'s `user_ingress.app` names this module's `app` object. The
|
|
4
|
+
**shared plugin host** imports it, provides the Lambda entry, and mounts it at
|
|
5
|
+
`/api/v1/plugins/<name>/*` — a plugin declaring `user_ingress` ships no Lambda
|
|
6
|
+
handler and no infrastructure of its own for this surface (see `terraform/`:
|
|
7
|
+
nothing here needs a per-plugin resource).
|
|
8
|
+
|
|
9
|
+
**No auth in this file, on purpose.** The host enforces `user_ingress.required_group`
|
|
10
|
+
(ADR-0011) before a request ever reaches a mounted app — see
|
|
11
|
+
`biffo_plugin_sdk.user_serving`'s module docstring: its `require_group` dependency
|
|
12
|
+
is only for an `isolated: true` plugin running in its own Lambda outside the
|
|
13
|
+
shared host. Adding a second check here would be redundant at best and a
|
|
14
|
+
divergent enforcement path at worst.
|
|
15
|
+
|
|
16
|
+
This is intentionally a placeholder (biffo-template#2008): one route that
|
|
17
|
+
identifies the plugin, enough to prove the mount is real, not enough to be
|
|
18
|
+
mistaken for a feature. Replace it with your own user-facing routes.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from fastapi import FastAPI
|
|
24
|
+
|
|
25
|
+
app = FastAPI(title="example-plugin user ingress")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@app.get("/ping")
|
|
29
|
+
def ping() -> dict[str, str]:
|
|
30
|
+
"""Identifies the plugin, so the mount can be proven real rather than guessed at."""
|
|
31
|
+
return {"plugin": "example-plugin", "surface": "user_ingress"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Pins the three platform surfaces `biffo.plugin.json` declares (biffo-template#2008).
|
|
2
|
+
|
|
3
|
+
Before this, `_skeletons/plugin-template` declared none of `user_ingress`,
|
|
4
|
+
`admin_ingress` or `user_frontend` — the platform already serves all three
|
|
5
|
+
(the working reference is `keiranholloway/biffo-plugin-ideation`'s manifest),
|
|
6
|
+
but every scaffolded plugin started life exposing none of them. This test
|
|
7
|
+
guards three things at once:
|
|
8
|
+
|
|
9
|
+
1. the manifest actually validates against the SDK's real `PluginManifest`
|
|
10
|
+
(`extra="forbid"`, so a typo in a block's keys fails loudly rather than
|
|
11
|
+
silently dropping the surface — see `README.md`'s "Manifest validation"
|
|
12
|
+
section for why that model, not `registry-schema.json`, is authoritative);
|
|
13
|
+
2. each `*_ingress.app` reference actually resolves to a real, importable ASGI
|
|
14
|
+
app — not merely a string that looks right; and
|
|
15
|
+
3. each placeholder app answers with something that identifies the plugin,
|
|
16
|
+
so the mount is real rather than guessed at (this issue's own "done when").
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import importlib
|
|
22
|
+
|
|
23
|
+
from biffo_plugin_sdk.plugin import load_manifest
|
|
24
|
+
from fastapi import FastAPI
|
|
25
|
+
from fastapi.testclient import TestClient
|
|
26
|
+
|
|
27
|
+
from example_plugin.manifest import MANIFEST_PATH
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _resolve_app(app_ref: str) -> FastAPI:
|
|
31
|
+
"""Resolve a manifest `*_ingress.app` string ('<module>:<attr>') the same
|
|
32
|
+
way the shared plugin host would — a plain dynamic import, not a literal
|
|
33
|
+
reference to this test's own imports, so a manifest string that drifted
|
|
34
|
+
from the real module path would be caught here rather than passing by
|
|
35
|
+
coincidence."""
|
|
36
|
+
module_name, _, attr = app_ref.partition(":")
|
|
37
|
+
module = importlib.import_module(module_name)
|
|
38
|
+
return getattr(module, attr)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TestManifestDeclaresAllThreeSurfaces:
|
|
42
|
+
def test_manifest_validates_and_declares_user_ingress(self) -> None:
|
|
43
|
+
manifest = load_manifest(MANIFEST_PATH)
|
|
44
|
+
assert manifest.user_ingress is not None
|
|
45
|
+
assert manifest.user_ingress.required_group == "founder"
|
|
46
|
+
assert manifest.user_ingress.app == "example_plugin.user_app:app"
|
|
47
|
+
|
|
48
|
+
def test_manifest_declares_admin_ingress(self) -> None:
|
|
49
|
+
manifest = load_manifest(MANIFEST_PATH)
|
|
50
|
+
assert manifest.admin_ingress is not None
|
|
51
|
+
assert manifest.admin_ingress.required_group == "admin"
|
|
52
|
+
assert manifest.admin_ingress.app == "example_plugin.admin_app:app"
|
|
53
|
+
|
|
54
|
+
def test_manifest_declares_user_frontend(self) -> None:
|
|
55
|
+
manifest = load_manifest(MANIFEST_PATH)
|
|
56
|
+
assert manifest.user_frontend is not None
|
|
57
|
+
assert manifest.user_frontend.dir == "web/dist"
|
|
58
|
+
assert manifest.user_frontend.required_group == "founder"
|
|
59
|
+
|
|
60
|
+
def test_ui_components_no_longer_point_at_a_dead_admin_path(self) -> None:
|
|
61
|
+
"""The old `/admin/example-plugin` paths matched none of the three real
|
|
62
|
+
surfaces (this issue's own finding) — pin that they now sit under the
|
|
63
|
+
portal's real installed-plugin route instead."""
|
|
64
|
+
manifest = load_manifest(MANIFEST_PATH)
|
|
65
|
+
paths = {c.path for c in manifest.ui_components}
|
|
66
|
+
assert paths == {
|
|
67
|
+
"/admin/plugins/example-plugin",
|
|
68
|
+
"/admin/plugins/example-plugin/widgets",
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TestIngressAppsResolveAndIdentifyThePlugin:
|
|
73
|
+
def test_user_ingress_app_resolves_and_answers(self) -> None:
|
|
74
|
+
manifest = load_manifest(MANIFEST_PATH)
|
|
75
|
+
assert manifest.user_ingress is not None
|
|
76
|
+
app = _resolve_app(manifest.user_ingress.app)
|
|
77
|
+
|
|
78
|
+
response = TestClient(app).get("/ping")
|
|
79
|
+
|
|
80
|
+
assert response.status_code == 200
|
|
81
|
+
assert response.json() == {"plugin": "example-plugin", "surface": "user_ingress"}
|
|
82
|
+
|
|
83
|
+
def test_admin_ingress_app_resolves_and_answers(self) -> None:
|
|
84
|
+
manifest = load_manifest(MANIFEST_PATH)
|
|
85
|
+
assert manifest.admin_ingress is not None
|
|
86
|
+
app = _resolve_app(manifest.admin_ingress.app)
|
|
87
|
+
|
|
88
|
+
response = TestClient(app).get("/ping")
|
|
89
|
+
|
|
90
|
+
assert response.status_code == 200
|
|
91
|
+
assert response.json() == {"plugin": "example-plugin", "surface": "admin_ingress"}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class TestAdminIngressWebAdminOrphanResolution:
|
|
95
|
+
"""`web-admin/` had no manifest field referencing it (this issue's own
|
|
96
|
+
finding). `admin_app.py` is now its one reader — these pin that the
|
|
97
|
+
reference is real (the directory `admin_app` looks for is exactly
|
|
98
|
+
`web-admin/`, not a typo'd sibling) and that a repo state with no built
|
|
99
|
+
`dist/` yet (true of this skeleton and every fresh checkout, since `dist/`
|
|
100
|
+
is gitignored and nothing builds it here — see admin_app.py's docstring)
|
|
101
|
+
still imports and serves cleanly rather than raising at import time.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def test_web_admin_dist_path_points_at_the_real_directory(self) -> None:
|
|
105
|
+
from example_plugin.admin_app import WEB_ADMIN_DIST
|
|
106
|
+
|
|
107
|
+
assert WEB_ADMIN_DIST.parent.name == "web-admin"
|
|
108
|
+
assert WEB_ADMIN_DIST.name == "dist"
|
|
109
|
+
assert WEB_ADMIN_DIST.parent.is_dir(), "web-admin/ itself must still exist"
|
|
110
|
+
|
|
111
|
+
def test_static_mount_is_skipped_when_dist_is_absent(self) -> None:
|
|
112
|
+
from example_plugin.admin_app import WEB_ADMIN_DIST, app
|
|
113
|
+
|
|
114
|
+
assert not WEB_ADMIN_DIST.is_dir(), (
|
|
115
|
+
"this test asserts the no-build-yet behaviour; if dist/ has been "
|
|
116
|
+
"built locally, the skip path this test pins is not being exercised"
|
|
117
|
+
)
|
|
118
|
+
response = TestClient(app).get("/some/never-built/asset.js")
|
|
119
|
+
assert response.status_code == 404
|
|
@@ -2,6 +2,15 @@ version = 1
|
|
|
2
2
|
revision = 3
|
|
3
3
|
requires-python = ">=3.13"
|
|
4
4
|
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "annotated-doc"
|
|
7
|
+
version = "0.0.5"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" }
|
|
10
|
+
wheels = [
|
|
11
|
+
{ url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" },
|
|
12
|
+
]
|
|
13
|
+
|
|
5
14
|
[[package]]
|
|
6
15
|
name = "annotated-types"
|
|
7
16
|
version = "0.8.0"
|
|
@@ -70,6 +79,7 @@ source = { editable = "." }
|
|
|
70
79
|
dependencies = [
|
|
71
80
|
{ name = "aws-lambda-powertools", extra = ["tracer"] },
|
|
72
81
|
{ name = "biffo-plugin-sdk" },
|
|
82
|
+
{ name = "fastapi" },
|
|
73
83
|
{ name = "httpx" },
|
|
74
84
|
]
|
|
75
85
|
|
|
@@ -88,6 +98,7 @@ dev = [
|
|
|
88
98
|
requires-dist = [
|
|
89
99
|
{ name = "aws-lambda-powertools", extras = ["tracer"], specifier = ">=3.4.0" },
|
|
90
100
|
{ name = "biffo-plugin-sdk", specifier = ">=1.0,<2.0" },
|
|
101
|
+
{ name = "fastapi", specifier = ">=0.115.0" },
|
|
91
102
|
{ name = "httpx", specifier = ">=0.28.1" },
|
|
92
103
|
]
|
|
93
104
|
|
|
@@ -398,6 +409,22 @@ wheels = [
|
|
|
398
409
|
{ url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" },
|
|
399
410
|
]
|
|
400
411
|
|
|
412
|
+
[[package]]
|
|
413
|
+
name = "fastapi"
|
|
414
|
+
version = "0.141.1"
|
|
415
|
+
source = { registry = "https://pypi.org/simple" }
|
|
416
|
+
dependencies = [
|
|
417
|
+
{ name = "annotated-doc" },
|
|
418
|
+
{ name = "pydantic" },
|
|
419
|
+
{ name = "starlette" },
|
|
420
|
+
{ name = "typing-extensions" },
|
|
421
|
+
{ name = "typing-inspection" },
|
|
422
|
+
]
|
|
423
|
+
sdist = { url = "https://files.pythonhosted.org/packages/8a/02/91e3416a8fdd715abb903a952a6bec7cdd8d14eed55d415fc8595524c319/fastapi-0.141.1.tar.gz", hash = "sha256:e8822fc40db1e1858054d7a949a888695bc9bdce70139178e33bd2871a453ca1", size = 425799, upload-time = "2026-07-29T17:18:05.568Z" }
|
|
424
|
+
wheels = [
|
|
425
|
+
{ url = "https://files.pythonhosted.org/packages/cb/03/10388a42375ee7e4ac9b94eb2c5c569c8b5795e377e701c9ac3ad63de890/fastapi-0.141.1-py3-none-any.whl", hash = "sha256:bfb91aa2d334c61cb35ba9a116fc123b3d3df31640b801cf57a7a78ec3f603b3", size = 131954, upload-time = "2026-07-29T17:18:04.364Z" },
|
|
426
|
+
]
|
|
427
|
+
|
|
401
428
|
[[package]]
|
|
402
429
|
name = "filelock"
|
|
403
430
|
version = "3.32.3"
|
|
@@ -1005,6 +1032,18 @@ wheels = [
|
|
|
1005
1032
|
{ url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" },
|
|
1006
1033
|
]
|
|
1007
1034
|
|
|
1035
|
+
[[package]]
|
|
1036
|
+
name = "starlette"
|
|
1037
|
+
version = "1.6.0"
|
|
1038
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1039
|
+
dependencies = [
|
|
1040
|
+
{ name = "anyio" },
|
|
1041
|
+
]
|
|
1042
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b5/b4/205b0d5241d934e8add0c38aa924c4f9fb7330834ff11e5444db964ec3f9/starlette-1.6.0.tar.gz", hash = "sha256:d4e3ac5e546444960c710297a3c9fc3f7ebae1b7e963f3d36173b49da535be9b", size = 2716969, upload-time = "2026-08-08T18:27:57.512Z" }
|
|
1043
|
+
wheels = [
|
|
1044
|
+
{ url = "https://files.pythonhosted.org/packages/c8/cb/6a6a47d5b464bd08695d254f3da6e7986cc70c9fa5d778eda57538edfe56/starlette-1.6.0-py3-none-any.whl", hash = "sha256:a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c", size = 75969, upload-time = "2026-08-08T18:27:56.196Z" },
|
|
1045
|
+
]
|
|
1046
|
+
|
|
1008
1047
|
[[package]]
|
|
1009
1048
|
name = "tomli"
|
|
1010
1049
|
version = "2.4.1"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@biffo/design-tokens": "^0.248.2",
|
|
20
20
|
"amazon-cognito-identity-js": "^6.3.12",
|
|
21
|
-
"next": "^15.5.
|
|
21
|
+
"next": "^15.5.25",
|
|
22
22
|
"react": "^19.0.0",
|
|
23
23
|
"react-dom": "^19.0.0"
|
|
24
24
|
},
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@types/react-dom": "^19.0.3",
|
|
34
34
|
"@vitejs/plugin-react": "^4.7.0",
|
|
35
35
|
"eslint": "^9.18.0",
|
|
36
|
-
"eslint-config-next": "^15.5.
|
|
36
|
+
"eslint-config-next": "^15.5.25",
|
|
37
37
|
"jsdom": "^30.0.1",
|
|
38
38
|
"prettier": "^3.4.2",
|
|
39
39
|
"typescript": "^5.7.3",
|
|
@@ -24,8 +24,8 @@ importers:
|
|
|
24
24
|
specifier: ^6.3.12
|
|
25
25
|
version: 6.3.18
|
|
26
26
|
next:
|
|
27
|
-
specifier: ^15.5.
|
|
28
|
-
version: 15.5.
|
|
27
|
+
specifier: ^15.5.25
|
|
28
|
+
version: 15.5.25(@babel/core@7.29.7)(@playwright/test@1.62.1)(@types/node@22.20.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
|
29
29
|
react:
|
|
30
30
|
specifier: ^19.0.0
|
|
31
31
|
version: 19.2.7
|
|
@@ -64,8 +64,8 @@ importers:
|
|
|
64
64
|
specifier: ^9.18.0
|
|
65
65
|
version: 9.39.4
|
|
66
66
|
eslint-config-next:
|
|
67
|
-
specifier: ^15.5.
|
|
68
|
-
version: 15.5.
|
|
67
|
+
specifier: ^15.5.25
|
|
68
|
+
version: 15.5.25(eslint@9.39.4)(typescript@5.9.3)
|
|
69
69
|
jsdom:
|
|
70
70
|
specifier: ^30.0.1
|
|
71
71
|
version: 30.0.1
|
|
@@ -641,56 +641,56 @@ packages:
|
|
|
641
641
|
'@emnapi/core': ^1.7.1
|
|
642
642
|
'@emnapi/runtime': ^1.7.1
|
|
643
643
|
|
|
644
|
-
'@next/env@15.5.
|
|
645
|
-
resolution: {integrity: sha512-
|
|
644
|
+
'@next/env@15.5.25':
|
|
645
|
+
resolution: {integrity: sha512-42h1lLr07vl4gawALP1hsgRZjHB1xYa58JfUfHwr0f7jG/zhPakh5GHkADHXOC9ZxUvlQFOPIrp7s6qX4DezPQ==}
|
|
646
646
|
|
|
647
|
-
'@next/eslint-plugin-next@15.5.
|
|
648
|
-
resolution: {integrity: sha512-
|
|
647
|
+
'@next/eslint-plugin-next@15.5.25':
|
|
648
|
+
resolution: {integrity: sha512-dAzOqZQCAOgIq5yQpsuMBZcwxK0AtzGqHMQpxNWYLQlvf79rsP3SDwdGPNQC4ySaMSihOQXMO/VXubQ3JWW+3A==}
|
|
649
649
|
|
|
650
|
-
'@next/swc-darwin-arm64@15.5.
|
|
651
|
-
resolution: {integrity: sha512
|
|
650
|
+
'@next/swc-darwin-arm64@15.5.25':
|
|
651
|
+
resolution: {integrity: sha512-w+RR0v/QuApnWEjRGm1z6gcObKwGMb5YPA7V3bzBEVSBpMFUXprer0tS27UxjUcEnqbhL7Zuzohej79B6rYmBg==}
|
|
652
652
|
engines: {node: '>= 10'}
|
|
653
653
|
cpu: [arm64]
|
|
654
654
|
os: [darwin]
|
|
655
655
|
|
|
656
|
-
'@next/swc-darwin-x64@15.5.
|
|
657
|
-
resolution: {integrity: sha512-
|
|
656
|
+
'@next/swc-darwin-x64@15.5.25':
|
|
657
|
+
resolution: {integrity: sha512-QiGGBUSakt8S1H4Lt9Ehsh6Ja87axiBnQQgysOObvCbI7iUfJnRGntF1P64S4/ijuHFnSB8KLsEddkY3nN26uw==}
|
|
658
658
|
engines: {node: '>= 10'}
|
|
659
659
|
cpu: [x64]
|
|
660
660
|
os: [darwin]
|
|
661
661
|
|
|
662
|
-
'@next/swc-linux-arm64-gnu@15.5.
|
|
663
|
-
resolution: {integrity: sha512-
|
|
662
|
+
'@next/swc-linux-arm64-gnu@15.5.25':
|
|
663
|
+
resolution: {integrity: sha512-ehLos/66zo0d/mJCU5u96a/VDcr01aaUrX0o/i16UdInxz8qPTCDSxGtjk/Lps1sIr1RJFdiX3hxc0fxJo+cPA==}
|
|
664
664
|
engines: {node: '>= 10'}
|
|
665
665
|
cpu: [arm64]
|
|
666
666
|
os: [linux]
|
|
667
667
|
|
|
668
|
-
'@next/swc-linux-arm64-musl@15.5.
|
|
669
|
-
resolution: {integrity: sha512-
|
|
668
|
+
'@next/swc-linux-arm64-musl@15.5.25':
|
|
669
|
+
resolution: {integrity: sha512-ZVMrqLiJ7DiChgmbkQwFtdhAnUkSH/4p7tB29QY+giATb0Q/XGHNRSKAb/B8XGDHRUaA67NepOW5W8u3ZRJBAA==}
|
|
670
670
|
engines: {node: '>= 10'}
|
|
671
671
|
cpu: [arm64]
|
|
672
672
|
os: [linux]
|
|
673
673
|
|
|
674
|
-
'@next/swc-linux-x64-gnu@15.5.
|
|
675
|
-
resolution: {integrity: sha512-
|
|
674
|
+
'@next/swc-linux-x64-gnu@15.5.25':
|
|
675
|
+
resolution: {integrity: sha512-UOewtDGkTMJTiODrEdeLZ50yGb59xCZSriNpXkfPMxRRgwDkGc7i8mLWqV5076wEdb+Ca/XN7MhJyM3CupyNyQ==}
|
|
676
676
|
engines: {node: '>= 10'}
|
|
677
677
|
cpu: [x64]
|
|
678
678
|
os: [linux]
|
|
679
679
|
|
|
680
|
-
'@next/swc-linux-x64-musl@15.5.
|
|
681
|
-
resolution: {integrity: sha512-
|
|
680
|
+
'@next/swc-linux-x64-musl@15.5.25':
|
|
681
|
+
resolution: {integrity: sha512-UBHwA8AhkCZgtRfU1aJpunuAJe/6gZv6jDESQe4p5MjTb5V0YEeJBWCdNqx15Vj3x+5jmauRfeMJSjfQj9HGFQ==}
|
|
682
682
|
engines: {node: '>= 10'}
|
|
683
683
|
cpu: [x64]
|
|
684
684
|
os: [linux]
|
|
685
685
|
|
|
686
|
-
'@next/swc-win32-arm64-msvc@15.5.
|
|
687
|
-
resolution: {integrity: sha512-
|
|
686
|
+
'@next/swc-win32-arm64-msvc@15.5.25':
|
|
687
|
+
resolution: {integrity: sha512-QcFcPRr16djk5IqK5+e8O80eZfgWzIvVBXfitIq0tQ/uc+eyfdoZ0NmKc0cnbIJyfVwREapKuG97YcxWA9gcpA==}
|
|
688
688
|
engines: {node: '>= 10'}
|
|
689
689
|
cpu: [arm64]
|
|
690
690
|
os: [win32]
|
|
691
691
|
|
|
692
|
-
'@next/swc-win32-x64-msvc@15.5.
|
|
693
|
-
resolution: {integrity: sha512-
|
|
692
|
+
'@next/swc-win32-x64-msvc@15.5.25':
|
|
693
|
+
resolution: {integrity: sha512-zREeykps3ndWr9egJgvJKqVkkDuaw6Zrrg23cYBos0ygydFkAWYU4+PaPVwXzP1eAYQJe53ShSK45iDM529BOg==}
|
|
694
694
|
engines: {node: '>= 10'}
|
|
695
695
|
cpu: [x64]
|
|
696
696
|
os: [win32]
|
|
@@ -1271,9 +1271,6 @@ packages:
|
|
|
1271
1271
|
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
|
1272
1272
|
engines: {node: '>=6'}
|
|
1273
1273
|
|
|
1274
|
-
caniuse-lite@1.0.30001800:
|
|
1275
|
-
resolution: {integrity: sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==}
|
|
1276
|
-
|
|
1277
1274
|
caniuse-lite@1.0.30001810:
|
|
1278
1275
|
resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==}
|
|
1279
1276
|
|
|
@@ -1446,8 +1443,8 @@ packages:
|
|
|
1446
1443
|
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
|
1447
1444
|
engines: {node: '>=10'}
|
|
1448
1445
|
|
|
1449
|
-
eslint-config-next@15.5.
|
|
1450
|
-
resolution: {integrity: sha512-
|
|
1446
|
+
eslint-config-next@15.5.25:
|
|
1447
|
+
resolution: {integrity: sha512-hB1oClZzRO3vMAeMmBMch0FHNJ4irH74LvQWDEMHkJtG/Us9+SAsg1f5Pvcw9jz4tc8wSGnvbmF050BRAAIbBg==}
|
|
1451
1448
|
peerDependencies:
|
|
1452
1449
|
eslint: ^7.23.0 || ^8.0.0 || ^9.0.0
|
|
1453
1450
|
typescript: '>=3.3.1'
|
|
@@ -1539,6 +1536,7 @@ packages:
|
|
|
1539
1536
|
eslint@9.39.4:
|
|
1540
1537
|
resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==}
|
|
1541
1538
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
|
1539
|
+
deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
|
|
1542
1540
|
hasBin: true
|
|
1543
1541
|
peerDependencies:
|
|
1544
1542
|
jiti: '*'
|
|
@@ -2001,8 +1999,8 @@ packages:
|
|
|
2001
1999
|
natural-compare@1.4.0:
|
|
2002
2000
|
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
|
2003
2001
|
|
|
2004
|
-
next@15.5.
|
|
2005
|
-
resolution: {integrity: sha512-
|
|
2002
|
+
next@15.5.25:
|
|
2003
|
+
resolution: {integrity: sha512-OMWNulIIqKM2ykvC2qMjIt0IoavB4UB2SCs4iXJ6z6847FvyH8jBmBWcvrF5iuhTu8Przh20Fo/aoszIdqx4PA==}
|
|
2006
2004
|
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
|
|
2007
2005
|
hasBin: true
|
|
2008
2006
|
peerDependencies:
|
|
@@ -3109,34 +3107,34 @@ snapshots:
|
|
|
3109
3107
|
'@tybys/wasm-util': 0.10.3
|
|
3110
3108
|
optional: true
|
|
3111
3109
|
|
|
3112
|
-
'@next/env@15.5.
|
|
3110
|
+
'@next/env@15.5.25': {}
|
|
3113
3111
|
|
|
3114
|
-
'@next/eslint-plugin-next@15.5.
|
|
3112
|
+
'@next/eslint-plugin-next@15.5.25':
|
|
3115
3113
|
dependencies:
|
|
3116
3114
|
fast-glob: 3.3.1
|
|
3117
3115
|
|
|
3118
|
-
'@next/swc-darwin-arm64@15.5.
|
|
3116
|
+
'@next/swc-darwin-arm64@15.5.25':
|
|
3119
3117
|
optional: true
|
|
3120
3118
|
|
|
3121
|
-
'@next/swc-darwin-x64@15.5.
|
|
3119
|
+
'@next/swc-darwin-x64@15.5.25':
|
|
3122
3120
|
optional: true
|
|
3123
3121
|
|
|
3124
|
-
'@next/swc-linux-arm64-gnu@15.5.
|
|
3122
|
+
'@next/swc-linux-arm64-gnu@15.5.25':
|
|
3125
3123
|
optional: true
|
|
3126
3124
|
|
|
3127
|
-
'@next/swc-linux-arm64-musl@15.5.
|
|
3125
|
+
'@next/swc-linux-arm64-musl@15.5.25':
|
|
3128
3126
|
optional: true
|
|
3129
3127
|
|
|
3130
|
-
'@next/swc-linux-x64-gnu@15.5.
|
|
3128
|
+
'@next/swc-linux-x64-gnu@15.5.25':
|
|
3131
3129
|
optional: true
|
|
3132
3130
|
|
|
3133
|
-
'@next/swc-linux-x64-musl@15.5.
|
|
3131
|
+
'@next/swc-linux-x64-musl@15.5.25':
|
|
3134
3132
|
optional: true
|
|
3135
3133
|
|
|
3136
|
-
'@next/swc-win32-arm64-msvc@15.5.
|
|
3134
|
+
'@next/swc-win32-arm64-msvc@15.5.25':
|
|
3137
3135
|
optional: true
|
|
3138
3136
|
|
|
3139
|
-
'@next/swc-win32-x64-msvc@15.5.
|
|
3137
|
+
'@next/swc-win32-x64-msvc@15.5.25':
|
|
3140
3138
|
optional: true
|
|
3141
3139
|
|
|
3142
3140
|
'@nodelib/fs.scandir@2.1.5':
|
|
@@ -3716,8 +3714,6 @@ snapshots:
|
|
|
3716
3714
|
|
|
3717
3715
|
callsites@3.1.0: {}
|
|
3718
3716
|
|
|
3719
|
-
caniuse-lite@1.0.30001800: {}
|
|
3720
|
-
|
|
3721
3717
|
caniuse-lite@1.0.30001810: {}
|
|
3722
3718
|
|
|
3723
3719
|
chai@6.2.2: {}
|
|
@@ -3974,16 +3970,16 @@ snapshots:
|
|
|
3974
3970
|
|
|
3975
3971
|
escape-string-regexp@4.0.0: {}
|
|
3976
3972
|
|
|
3977
|
-
eslint-config-next@15.5.
|
|
3973
|
+
eslint-config-next@15.5.25(eslint@9.39.4)(typescript@5.9.3):
|
|
3978
3974
|
dependencies:
|
|
3979
|
-
'@next/eslint-plugin-next': 15.5.
|
|
3975
|
+
'@next/eslint-plugin-next': 15.5.25
|
|
3980
3976
|
'@rushstack/eslint-patch': 1.16.1
|
|
3981
3977
|
'@typescript-eslint/eslint-plugin': 8.62.1(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)
|
|
3982
3978
|
'@typescript-eslint/parser': 8.62.1(eslint@9.39.4)(typescript@5.9.3)
|
|
3983
3979
|
eslint: 9.39.4
|
|
3984
3980
|
eslint-import-resolver-node: 0.3.10
|
|
3985
|
-
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0
|
|
3986
|
-
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1
|
|
3981
|
+
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4)
|
|
3982
|
+
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4)
|
|
3987
3983
|
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4)
|
|
3988
3984
|
eslint-plugin-react: 7.37.5(eslint@9.39.4)
|
|
3989
3985
|
eslint-plugin-react-hooks: 5.2.0(eslint@9.39.4)
|
|
@@ -4002,7 +3998,7 @@ snapshots:
|
|
|
4002
3998
|
transitivePeerDependencies:
|
|
4003
3999
|
- supports-color
|
|
4004
4000
|
|
|
4005
|
-
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0
|
|
4001
|
+
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4):
|
|
4006
4002
|
dependencies:
|
|
4007
4003
|
'@nolyfill/is-core-module': 1.0.39
|
|
4008
4004
|
debug: 4.4.3
|
|
@@ -4013,22 +4009,22 @@ snapshots:
|
|
|
4013
4009
|
tinyglobby: 0.2.17
|
|
4014
4010
|
unrs-resolver: 1.12.2
|
|
4015
4011
|
optionalDependencies:
|
|
4016
|
-
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1
|
|
4012
|
+
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4)
|
|
4017
4013
|
transitivePeerDependencies:
|
|
4018
4014
|
- supports-color
|
|
4019
4015
|
|
|
4020
|
-
eslint-module-utils@2.14.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1
|
|
4016
|
+
eslint-module-utils@2.14.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4):
|
|
4021
4017
|
dependencies:
|
|
4022
4018
|
debug: 3.2.7
|
|
4023
4019
|
optionalDependencies:
|
|
4024
4020
|
'@typescript-eslint/parser': 8.62.1(eslint@9.39.4)(typescript@5.9.3)
|
|
4025
4021
|
eslint: 9.39.4
|
|
4026
4022
|
eslint-import-resolver-node: 0.3.10
|
|
4027
|
-
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0
|
|
4023
|
+
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4)
|
|
4028
4024
|
transitivePeerDependencies:
|
|
4029
4025
|
- supports-color
|
|
4030
4026
|
|
|
4031
|
-
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1
|
|
4027
|
+
eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4):
|
|
4032
4028
|
dependencies:
|
|
4033
4029
|
'@rtsao/scc': 1.1.0
|
|
4034
4030
|
array-includes: 3.1.9
|
|
@@ -4039,7 +4035,7 @@ snapshots:
|
|
|
4039
4035
|
doctrine: 2.1.0
|
|
4040
4036
|
eslint: 9.39.4
|
|
4041
4037
|
eslint-import-resolver-node: 0.3.10
|
|
4042
|
-
eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1
|
|
4038
|
+
eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.62.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4)
|
|
4043
4039
|
hasown: 2.0.4
|
|
4044
4040
|
is-core-module: 2.16.2
|
|
4045
4041
|
is-glob: 4.0.3
|
|
@@ -4607,24 +4603,24 @@ snapshots:
|
|
|
4607
4603
|
|
|
4608
4604
|
natural-compare@1.4.0: {}
|
|
4609
4605
|
|
|
4610
|
-
next@15.5.
|
|
4606
|
+
next@15.5.25(@babel/core@7.29.7)(@playwright/test@1.62.1)(@types/node@22.20.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
|
|
4611
4607
|
dependencies:
|
|
4612
|
-
'@next/env': 15.5.
|
|
4608
|
+
'@next/env': 15.5.25
|
|
4613
4609
|
'@swc/helpers': 0.5.15
|
|
4614
|
-
caniuse-lite: 1.0.
|
|
4610
|
+
caniuse-lite: 1.0.30001810
|
|
4615
4611
|
postcss: 8.5.23
|
|
4616
4612
|
react: 19.2.7
|
|
4617
4613
|
react-dom: 19.2.7(react@19.2.7)
|
|
4618
4614
|
styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.7)
|
|
4619
4615
|
optionalDependencies:
|
|
4620
|
-
'@next/swc-darwin-arm64': 15.5.
|
|
4621
|
-
'@next/swc-darwin-x64': 15.5.
|
|
4622
|
-
'@next/swc-linux-arm64-gnu': 15.5.
|
|
4623
|
-
'@next/swc-linux-arm64-musl': 15.5.
|
|
4624
|
-
'@next/swc-linux-x64-gnu': 15.5.
|
|
4625
|
-
'@next/swc-linux-x64-musl': 15.5.
|
|
4626
|
-
'@next/swc-win32-arm64-msvc': 15.5.
|
|
4627
|
-
'@next/swc-win32-x64-msvc': 15.5.
|
|
4616
|
+
'@next/swc-darwin-arm64': 15.5.25
|
|
4617
|
+
'@next/swc-darwin-x64': 15.5.25
|
|
4618
|
+
'@next/swc-linux-arm64-gnu': 15.5.25
|
|
4619
|
+
'@next/swc-linux-arm64-musl': 15.5.25
|
|
4620
|
+
'@next/swc-linux-x64-gnu': 15.5.25
|
|
4621
|
+
'@next/swc-linux-x64-musl': 15.5.25
|
|
4622
|
+
'@next/swc-win32-arm64-msvc': 15.5.25
|
|
4623
|
+
'@next/swc-win32-x64-msvc': 15.5.25
|
|
4628
4624
|
'@playwright/test': 1.62.1
|
|
4629
4625
|
sharp: 0.35.3(@types/node@22.20.0)
|
|
4630
4626
|
transitivePeerDependencies:
|