lightnet 3.11.0 → 3.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/__e2e__/admin.spec.ts +1 -365
  3. package/__e2e__/fixtures/basics/node_modules/.bin/astro +2 -2
  4. package/__e2e__/fixtures/basics/package.json +4 -4
  5. package/package.json +8 -15
  6. package/src/astro-integration/config.ts +1 -22
  7. package/src/astro-integration/integration.ts +4 -39
  8. package/src/components/VideoPlayer.astro +74 -10
  9. package/src/content/get-media-items.ts +1 -47
  10. package/src/i18n/translate.ts +1 -1
  11. package/src/i18n/translations/TRANSLATION-STATUS.md +37 -12
  12. package/src/i18n/translations/en.yml +8 -4
  13. package/src/i18n/translations.ts +0 -7
  14. package/src/layouts/Page.astro +2 -0
  15. package/src/layouts/global.css +3 -0
  16. package/src/pages/details-page/components/AudioPanel.astro +1 -12
  17. package/src/pages/details-page/components/AudioPlayer.astro +40 -8
  18. package/src/pages/details-page/components/main-details/EditButton.astro +2 -4
  19. package/src/pages/search-page/components/SearchFilter.tsx +1 -1
  20. package/src/admin/api/fs/write-file.ts +0 -53
  21. package/src/admin/components/form/DynamicArray.tsx +0 -129
  22. package/src/admin/components/form/Input.tsx +0 -68
  23. package/src/admin/components/form/LazyLoadedMarkdownEditor.tsx +0 -102
  24. package/src/admin/components/form/MarkdownEditor.tsx +0 -62
  25. package/src/admin/components/form/Select.tsx +0 -71
  26. package/src/admin/components/form/SubmitButton.tsx +0 -86
  27. package/src/admin/components/form/atoms/Button.tsx +0 -27
  28. package/src/admin/components/form/atoms/ErrorMessage.tsx +0 -13
  29. package/src/admin/components/form/atoms/FileUpload.tsx +0 -190
  30. package/src/admin/components/form/atoms/Hint.tsx +0 -19
  31. package/src/admin/components/form/atoms/Label.tsx +0 -37
  32. package/src/admin/components/form/hooks/use-field-dirty.tsx +0 -12
  33. package/src/admin/components/form/hooks/use-field-error.tsx +0 -34
  34. package/src/admin/components/form/utils/get-border-class.ts +0 -22
  35. package/src/admin/i18n/admin-i18n.ts +0 -21
  36. package/src/admin/i18n/translations/en.yml +0 -50
  37. package/src/admin/i18n/translations.ts +0 -5
  38. package/src/admin/pages/AdminRoute.astro +0 -14
  39. package/src/admin/pages/media/EditForm.tsx +0 -136
  40. package/src/admin/pages/media/EditRoute.astro +0 -100
  41. package/src/admin/pages/media/fields/Authors.tsx +0 -44
  42. package/src/admin/pages/media/fields/Categories.tsx +0 -49
  43. package/src/admin/pages/media/fields/Collections.tsx +0 -68
  44. package/src/admin/pages/media/fields/Content.tsx +0 -150
  45. package/src/admin/pages/media/fields/Image.tsx +0 -119
  46. package/src/admin/pages/media/file-system.ts +0 -41
  47. package/src/admin/pages/media/media-item-store.ts +0 -61
  48. package/src/admin/types/media-item.ts +0 -81
  49. package/src/api/media/[mediaId].ts +0 -16
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # lightnet
2
2
 
3
+ ## 3.12.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#356](https://github.com/LightNetDev/LightNet/pull/356) [`81e5749`](https://github.com/LightNetDev/LightNet/commit/81e57498caa24c480bab43b1f368c9028637dad6) Thanks [@smn-cds](https://github.com/smn-cds)! - **Remove code for experimental Admin UI.**
8
+
9
+ We are exploring a different way to implement it. Yet we consider reusing this code later.
10
+
11
+ - [#358](https://github.com/LightNetDev/LightNet/pull/358) [`ca9f983`](https://github.com/LightNetDev/LightNet/commit/ca9f98337e35878761d353916b189ce7364ddbf2) Thanks [@smn-cds](https://github.com/smn-cds)! - Update dependencies, disable i18next support notice
12
+
13
+ - [#356](https://github.com/LightNetDev/LightNet/pull/356) [`81e5749`](https://github.com/LightNetDev/LightNet/commit/81e57498caa24c480bab43b1f368c9028637dad6) Thanks [@smn-cds](https://github.com/smn-cds)! - Remove unused internal `getRawMediaItems` function.
14
+
15
+ - [#354](https://github.com/LightNetDev/LightNet/pull/354) [`1c3c7ea`](https://github.com/LightNetDev/LightNet/commit/1c3c7eac0384f9c57da89c2abddabd91c20dcfa2) Thanks [@smn-cds](https://github.com/smn-cds)! - Fix search input background on IOS safari
16
+
17
+ - [#354](https://github.com/LightNetDev/LightNet/pull/354) [`1c3c7ea`](https://github.com/LightNetDev/LightNet/commit/1c3c7eac0384f9c57da89c2abddabd91c20dcfa2) Thanks [@smn-cds](https://github.com/smn-cds)! - Do not apply TailwindCSS base styles to every page by default.
18
+
19
+ ## 3.12.0
20
+
21
+ ### Minor Changes
22
+
23
+ - [#351](https://github.com/LightNetDev/LightNet/pull/351) [`a1f63bf`](https://github.com/LightNetDev/LightNet/commit/a1f63bfa30448fdf58bfb1ff24007caa750349e0) Thanks [@smn-cds](https://github.com/smn-cds)! - Add an external fallback UI for audio content so non-mp3 URLs show a player-style link that opens in a new tab.
24
+
25
+ - [#351](https://github.com/LightNetDev/LightNet/pull/351) [`a1f63bf`](https://github.com/LightNetDev/LightNet/commit/a1f63bfa30448fdf58bfb1ff24007caa750349e0) Thanks [@smn-cds](https://github.com/smn-cds)! - Add a fallback in the video player so any video URL can be used on the "video" details page. Unsupported providers now render a poster-style link that opens the video on the external site.
26
+
3
27
  ## 3.11.0
4
28
 
5
29
  ### Minor Changes
@@ -1,14 +1,7 @@
1
- import { readFile } from "node:fs/promises"
2
-
3
- import { expect, type Page } from "@playwright/test"
1
+ import { expect } from "@playwright/test"
4
2
 
5
3
  import { test } from "./basics-fixture"
6
4
 
7
- const faithfulFreestyleMediaUrl = new URL(
8
- "./fixtures/basics/src/content/media/faithful-freestyle--en.json",
9
- import.meta.url,
10
- )
11
-
12
5
  test.describe("Edit button on details page", () => {
13
6
  test("Should not show `Edit` button on details page by default.", async ({
14
7
  page,
@@ -24,361 +17,4 @@ test.describe("Edit button on details page", () => {
24
17
  const editButton = page.locator("#edit-btn")
25
18
  await expect(editButton).toBeHidden()
26
19
  })
27
-
28
- test("Should show `Edit` button on book details page after visiting `/admin/` path.", async ({
29
- page,
30
- lightnet,
31
- }) => {
32
- const ln = await lightnet()
33
-
34
- await page.goto(ln.resolveURL("/admin/"))
35
- await expect(
36
- page.getByText("Admin features are enabled now.", { exact: true }),
37
- ).toBeVisible()
38
-
39
- await page.goto(ln.resolveURL("/en/media/faithful-freestyle--en"))
40
- await expect(
41
- page.getByRole("heading", { name: "Faithful Freestyle" }),
42
- ).toBeVisible()
43
-
44
- const editButton = page.locator("#edit-btn")
45
- await expect(editButton).toBeVisible()
46
- await expect(editButton).toHaveAttribute(
47
- "href",
48
- "/admin/media/faithful-freestyle--en",
49
- )
50
- })
51
-
52
- test("Should show `Edit` button on video details page after visiting `/admin/` path.", async ({
53
- page,
54
- lightnet,
55
- }) => {
56
- const ln = await lightnet("/admin/")
57
-
58
- await expect(
59
- page.getByText("Admin features are enabled now.", { exact: true }),
60
- ).toBeVisible()
61
-
62
- await page.goto(ln.resolveURL("/en/media/how-to-kickflip--de"))
63
- await expect(
64
- page.getByRole("heading", { name: "Kickflip Anleitung" }),
65
- ).toBeVisible()
66
-
67
- const editButton = page.locator("#edit-btn")
68
- await expect(editButton).toBeVisible()
69
- await expect(editButton).toHaveAttribute(
70
- "href",
71
- "/admin/media/how-to-kickflip--de",
72
- )
73
- })
74
-
75
- test("Should show `Edit` button on audio details page after visiting `/admin/` path.", async ({
76
- page,
77
- lightnet,
78
- }) => {
79
- const ln = await lightnet("/admin/")
80
-
81
- await expect(
82
- page.getByText("Admin features are enabled now.", { exact: true }),
83
- ).toBeVisible()
84
-
85
- await page.goto(ln.resolveURL("/en/media/skate-sounds--en"))
86
- await expect(
87
- page.getByRole("heading", { name: "Skate Sounds" }),
88
- ).toBeVisible()
89
-
90
- const editButton = page.locator("#edit-btn")
91
- await expect(editButton).toBeVisible()
92
- await expect(editButton).toHaveAttribute(
93
- "href",
94
- "/admin/media/skate-sounds--en",
95
- )
96
- })
97
-
98
- test("Edit button on details page should navigate to media item edit page", async ({
99
- page,
100
- lightnet,
101
- }) => {
102
- const ln = await lightnet("/admin/")
103
- await ln.goto("/en/media/faithful-freestyle--en")
104
-
105
- const editButton = page.locator("#edit-btn")
106
- await expect(editButton).toBeVisible()
107
-
108
- await editButton.click()
109
- await expect(page).toHaveURL(
110
- ln.resolveURL("/admin/media/faithful-freestyle--en"),
111
- )
112
- await expect(
113
- page.getByText("Edit media item", { exact: false }),
114
- ).toBeVisible()
115
- })
116
- })
117
-
118
- test.describe("Media item edit page", () => {
119
- const recordWriteFile = async (page: Page) => {
120
- type WriteFileRequest = { url: string; body: unknown }
121
- let resolveWriteFileRequest: ((value: WriteFileRequest) => void) | null =
122
- null
123
- const writeFileRequestPromise = new Promise<WriteFileRequest>((resolve) => {
124
- resolveWriteFileRequest = resolve
125
- })
126
- await page.route("**/api/internal/fs/write-file?*", async (route) => {
127
- const request = route.request()
128
- resolveWriteFileRequest?.({
129
- url: request.url(),
130
- body: JSON.parse(request.postData() ?? ""),
131
- })
132
- await route.fulfill({
133
- status: 200,
134
- contentType: "application/json",
135
- body: JSON.stringify({ status: "ok" }),
136
- })
137
- })
138
- return () => writeFileRequestPromise
139
- }
140
-
141
- const getPublishButton = (page: Page) =>
142
- page.getByRole("button", { name: "Publish changes" }).first()
143
-
144
- const expectPublishedMessage = (page: Page) =>
145
- expect(
146
- page.getByRole("button", { name: "Published" }).first(),
147
- ).toBeVisible()
148
-
149
- test("should edit title", async ({ page, lightnet }) => {
150
- await lightnet("/admin/media/faithful-freestyle--en")
151
- const writeFileRequest = await recordWriteFile(page)
152
-
153
- const updatedTitle = "Faithful Freestyle (Edited)"
154
- const titleInput = page.getByLabel("Title")
155
- await expect(titleInput).toHaveValue("Faithful Freestyle")
156
- await titleInput.fill(updatedTitle)
157
-
158
- const saveButton = getPublishButton(page)
159
- await expect(saveButton).toBeEnabled()
160
- await saveButton.click()
161
-
162
- const { url, body } = await writeFileRequest()
163
- expect(url).toContain(
164
- "/api/internal/fs/write-file?path=src%2Fcontent%2Fmedia%2Ffaithful-freestyle--en.json",
165
- )
166
-
167
- const expectedMediaItem = JSON.parse(
168
- await readFile(faithfulFreestyleMediaUrl, "utf-8"),
169
- )
170
- expect(body).toEqual({
171
- ...expectedMediaItem,
172
- title: updatedTitle,
173
- })
174
- await expectPublishedMessage(page)
175
- })
176
-
177
- test("Should update media type", async ({ page, lightnet }) => {
178
- await lightnet("/admin/media/faithful-freestyle--en")
179
- const writeFileRequest = await recordWriteFile(page)
180
-
181
- const typeSelect = page.getByLabel("Type").first()
182
- await expect(typeSelect).toHaveValue("book")
183
- await typeSelect.selectOption("video")
184
-
185
- const saveButton = getPublishButton(page)
186
- await expect(saveButton).toBeEnabled()
187
- await saveButton.click()
188
-
189
- const { body } = await writeFileRequest()
190
- const expectedMediaItem = JSON.parse(
191
- await readFile(faithfulFreestyleMediaUrl, "utf-8"),
192
- )
193
- expect(body).toEqual({
194
- ...expectedMediaItem,
195
- type: "video",
196
- })
197
- await expectPublishedMessage(page)
198
- })
199
-
200
- test("Should update author name", async ({ page, lightnet }) => {
201
- await lightnet("/admin/media/faithful-freestyle--en")
202
- const writeFileRequest = await recordWriteFile(page)
203
-
204
- const authorsFieldset = page.getByRole("group", { name: "Authors" })
205
- const firstAuthorInput = authorsFieldset.getByRole("textbox").first()
206
- const updatedAuthor = "Sk8 Ministries International"
207
- await expect(firstAuthorInput).toHaveValue("Sk8 Ministries")
208
- await firstAuthorInput.fill(updatedAuthor)
209
-
210
- const saveButton = getPublishButton(page)
211
- await expect(saveButton).toBeEnabled()
212
- await saveButton.click()
213
-
214
- const { body } = await writeFileRequest()
215
- const expectedMediaItem = JSON.parse(
216
- await readFile(faithfulFreestyleMediaUrl, "utf-8"),
217
- )
218
- expect(body).toEqual({
219
- ...expectedMediaItem,
220
- authors: [updatedAuthor],
221
- })
222
- await expectPublishedMessage(page)
223
- })
224
-
225
- test("Should add author", async ({ page, lightnet }) => {
226
- await lightnet("/admin/media/faithful-freestyle--en")
227
- const writeFileRequest = await recordWriteFile(page)
228
-
229
- const authorsFieldset = page.getByRole("group", { name: "Authors" })
230
- const addAuthorButton = page.getByRole("button", { name: "Add Author" })
231
- await addAuthorButton.click()
232
- const newAuthorInput = authorsFieldset.getByRole("textbox").last()
233
- const additionalAuthor = "Tony Hawk"
234
- await newAuthorInput.fill(additionalAuthor)
235
-
236
- const saveButton = getPublishButton(page)
237
- await expect(saveButton).toBeEnabled()
238
- await saveButton.click()
239
-
240
- const { body } = await writeFileRequest()
241
- const expectedMediaItem = JSON.parse(
242
- await readFile(faithfulFreestyleMediaUrl, "utf-8"),
243
- )
244
- expect(body).toEqual({
245
- ...expectedMediaItem,
246
- authors: ["Sk8 Ministries", additionalAuthor],
247
- })
248
- await expectPublishedMessage(page)
249
- })
250
-
251
- test("Should remove author", async ({ page, lightnet }) => {
252
- await lightnet("/admin/media/faithful-freestyle--en")
253
- const writeFileRequest = await recordWriteFile(page)
254
-
255
- const authorsFieldset = page.getByRole("group", { name: "Authors" })
256
- const addAuthorButton = page.getByRole("button", { name: "Add Author" })
257
- const replacementAuthor = "Skate Evangelists"
258
- await addAuthorButton.click()
259
- const addedAuthorInput = authorsFieldset.getByRole("textbox").last()
260
- await addedAuthorInput.fill(replacementAuthor)
261
-
262
- const removeButtons = authorsFieldset.getByRole("button", {
263
- name: "Remove",
264
- })
265
- await removeButtons.first().click()
266
-
267
- const saveButton = getPublishButton(page)
268
- await expect(saveButton).toBeEnabled()
269
- await saveButton.click()
270
-
271
- const { body } = await writeFileRequest()
272
- const expectedMediaItem = JSON.parse(
273
- await readFile(faithfulFreestyleMediaUrl, "utf-8"),
274
- )
275
- expect(body).toEqual({
276
- ...expectedMediaItem,
277
- authors: [replacementAuthor],
278
- })
279
- await expectPublishedMessage(page)
280
- })
281
-
282
- test("should show error message if common id is set empty", async ({
283
- page,
284
- lightnet,
285
- }) => {
286
- await lightnet("/admin/media/faithful-freestyle--en")
287
-
288
- const commonIdInput = page.getByLabel("Common ID")
289
- await expect(commonIdInput).toHaveValue("faithful-freestyle")
290
-
291
- await commonIdInput.fill("")
292
- await commonIdInput.blur()
293
-
294
- await expect(
295
- page
296
- .getByRole("alert")
297
- .filter({ hasText: "Please enter at least one character." }),
298
- ).toBeVisible()
299
- })
300
-
301
- test("should focus invalid field when submitting invalid form data", async ({
302
- page,
303
- lightnet,
304
- }) => {
305
- await lightnet("/admin/media/faithful-freestyle--en")
306
-
307
- const categoriesFieldset = page.getByRole("group", { name: "Categories" })
308
- await page.getByRole("button", { name: "Add Category" }).click()
309
- const newCategorySelect = categoriesFieldset.getByRole("combobox").last()
310
- await expect(newCategorySelect).toHaveValue("")
311
-
312
- // move focus away so the submission handler needs to return focus
313
- await page.getByLabel("Title").click()
314
-
315
- const saveButton = getPublishButton(page)
316
- await saveButton.click()
317
-
318
- await expect(
319
- page.getByRole("alert").filter({ hasText: "This field is required." }),
320
- ).toBeVisible()
321
- await expect(newCategorySelect).toBeFocused()
322
- })
323
-
324
- test("should not allow assigning duplicate categories", async ({
325
- page,
326
- lightnet,
327
- }) => {
328
- await lightnet("/admin/media/faithful-freestyle--en")
329
-
330
- const categoriesFieldset = page.getByRole("group", { name: "Categories" })
331
- await page.getByRole("button", { name: "Add Category" }).click()
332
-
333
- const categorySelects = categoriesFieldset.getByRole("combobox")
334
- const firstCategoryValue = await categorySelects.first().inputValue()
335
- const duplicateCategorySelect = categorySelects.last()
336
- await duplicateCategorySelect.selectOption(firstCategoryValue)
337
-
338
- const publishButton = getPublishButton(page)
339
- await publishButton.click()
340
-
341
- const duplicateCategoryError = categoriesFieldset
342
- .getByRole("alert")
343
- .filter({ hasText: "Please choose a different value for each entry." })
344
- await expect(duplicateCategoryError).toBeVisible()
345
- await expect(duplicateCategorySelect).toHaveAttribute(
346
- "aria-invalid",
347
- "true",
348
- )
349
- })
350
-
351
- test("should not submit the form on enter", async ({ page, lightnet }) => {
352
- await lightnet("/admin/media/faithful-freestyle--en")
353
- const writeFileRequest = await recordWriteFile(page)
354
- const writePromise = writeFileRequest()
355
-
356
- const updatedTitle = "Faithful Freestyle (Enter key)"
357
- const titleInput = page.getByLabel("Title")
358
- await titleInput.fill(updatedTitle)
359
-
360
- const publishButton = getPublishButton(page)
361
- await expect(publishButton).toBeEnabled()
362
-
363
- await titleInput.press("Enter")
364
-
365
- const enterResult = await Promise.race([
366
- writePromise.then(() => "submitted"),
367
- page.waitForTimeout(500).then(() => "timeout"),
368
- ])
369
- expect(enterResult).toBe("timeout")
370
- await expect(publishButton).toBeEnabled()
371
-
372
- await publishButton.click()
373
-
374
- const expectedMediaItem = JSON.parse(
375
- await readFile(faithfulFreestyleMediaUrl, "utf-8"),
376
- )
377
- const { body } = await writePromise
378
- expect(body).toEqual({
379
- ...expectedMediaItem,
380
- title: updatedTitle,
381
- })
382
- await expectPublishedMessage(page)
383
- })
384
20
  })
@@ -10,9 +10,9 @@ case `uname` in
10
10
  esac
11
11
 
12
12
  if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.16.6_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.54.0_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.16.6_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.54.0_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules"
13
+ export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.17.2_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.57.1_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.17.2_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.57.1_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules"
14
14
  else
15
- export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.16.6_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.54.0_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.16.6_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.54.0_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules:$NODE_PATH"
15
+ export NODE_PATH="/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.17.2_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.57.1_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules/astro/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/astro@5.17.2_@types+node@25.0.3_jiti@2.4.2_lightningcss@1.29.1_rollup@4.57.1_terser@5.39.0_typescript@5.9.3_yaml@2.8.2/node_modules:/home/runner/work/LightNet/LightNet/node_modules/.pnpm/node_modules:$NODE_PATH"
16
16
  fi
17
17
  if [ -x "$basedir/node" ]; then
18
18
  exec "$basedir/node" "$basedir/../astro/astro.js" "$@"
@@ -7,10 +7,10 @@
7
7
  "@astrojs/react": "^4.4.2",
8
8
  "@astrojs/tailwind": "^6.0.2",
9
9
  "@lightnet/decap-admin": "^3.1.4",
10
- "astro": "^5.16.6",
11
- "lightnet": "^3.11.0",
12
- "react": "^19.2.3",
13
- "react-dom": "^19.2.3",
10
+ "astro": "^5.17.2",
11
+ "lightnet": "^3.12.0",
12
+ "react": "^19.2.4",
13
+ "react-dom": "^19.2.4",
14
14
  "sharp": "^0.34.5",
15
15
  "tailwindcss": "^3.4.19",
16
16
  "typescript": "^5.9.3"
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "LightNet makes it easy to run your own digital media library.",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
- "version": "3.11.0",
6
+ "version": "3.12.1",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "https://github.com/LightNetDev/lightnet",
@@ -32,11 +32,7 @@
32
32
  "./pages/SearchPageRoute.astro": "./src/pages/search-page/SearchPageRoute.astro",
33
33
  "./pages/DetailsPageRoute.astro": "./src/pages/details-page/DetailsPageRoute.astro",
34
34
  "./api/internal/search.ts": "./src/pages/search-page/api/search.ts",
35
- "./api/versions.ts": "./src/api/versions.ts",
36
- "./api/media/[mediaId].ts": "./src/api/media/[mediaId].ts",
37
- "./api/internal/fs/write-file.ts": "./src/admin/api/fs/write-file.ts",
38
- "./admin/pages/AdminRoute.astro": "./src/admin/pages/AdminRoute.astro",
39
- "./admin/pages/media/EditRoute.astro": "./src/admin/pages/media/EditRoute.astro"
35
+ "./api/versions.ts": "./src/api/versions.ts"
40
36
  },
41
37
  "peerDependencies": {
42
38
  "astro": "^5.1.0",
@@ -47,27 +43,24 @@
47
43
  "dependencies": {
48
44
  "@astrojs/react": "^4.4.2",
49
45
  "@astrojs/tailwind": "^6.0.2",
50
- "@hookform/resolvers": "^5.2.2",
51
46
  "@iconify-json/mdi": "^1.2.3",
52
47
  "@iconify/tailwind": "^1.2.0",
53
- "@mdxeditor/editor": "^3.52.1",
54
48
  "@tailwindcss/typography": "^0.5.19",
55
- "@tanstack/react-virtual": "^3.13.13",
49
+ "@tanstack/react-virtual": "^3.13.18",
56
50
  "daisyui": "^4.12.24",
57
51
  "embla-carousel": "^8.6.0",
58
52
  "embla-carousel-wheel-gestures": "^8.1.0",
59
53
  "fuse.js": "^7.1.0",
60
- "i18next": "^25.7.3",
54
+ "i18next": "^25.8.5",
61
55
  "marked": "^16.4.2",
62
- "react-hook-form": "^7.69.0",
63
56
  "yaml": "^2.8.2"
64
57
  },
65
58
  "devDependencies": {
66
- "@playwright/test": "^1.57.0",
67
- "@types/node": "^22.19.3",
68
- "@types/react": "^19.2.7",
59
+ "@playwright/test": "^1.58.2",
60
+ "@types/node": "^22.19.11",
61
+ "@types/react": "^19.2.14",
69
62
  "typescript": "^5.9.3",
70
- "vitest": "^4.0.16"
63
+ "vitest": "^4.0.18"
71
64
  },
72
65
  "engines": {
73
66
  "node": ">=22"
@@ -220,28 +220,7 @@ export const configSchema = z.object({
220
220
  /**
221
221
  * Experimental features. Subject to change with any release.
222
222
  */
223
- experimental: z
224
- .object({
225
- /**
226
- * Configure administration interface.
227
- */
228
- admin: z
229
- .object({
230
- enabled: z.boolean().default(false),
231
- /**
232
- * Currently we only support english as Admin UI language.
233
- */
234
- languageCode: z.literal("en").default("en"),
235
- /**
236
- * Max file size to upload in mega bytes.
237
- *
238
- * Default is 25 (this aligns with Cloudflare's max file size).
239
- */
240
- maxFileSize: z.number().default(25),
241
- })
242
- .optional(),
243
- })
244
- .optional(),
223
+ experimental: z.object({}).optional(),
245
224
  })
246
225
 
247
226
  export type Language = z.input<typeof languageSchema>
@@ -19,7 +19,6 @@ export function lightnet(lightnetConfig: LightnetConfig): AstroIntegration {
19
19
  updateConfig,
20
20
  logger,
21
21
  addMiddleware,
22
- command,
23
22
  }) => {
24
23
  const config = verifySchema(
25
24
  configSchema,
@@ -64,46 +63,12 @@ export function lightnet(lightnetConfig: LightnetConfig): AstroIntegration {
64
63
  prerender: true,
65
64
  })
66
65
 
67
- if (config.experimental?.admin?.enabled) {
68
- injectRoute({
69
- pattern: "/api/media/[mediaId].json",
70
- entrypoint: "lightnet/api/media/[mediaId].ts",
71
- prerender: true,
72
- })
73
-
74
- injectRoute({
75
- pattern: "/admin",
76
- entrypoint: "lightnet/admin/pages/AdminRoute.astro",
77
- prerender: true,
78
- })
79
- injectRoute({
80
- pattern: "/admin/media/[mediaId]",
81
- entrypoint: "lightnet/admin/pages/media/EditRoute.astro",
82
- prerender: true,
83
- })
84
- }
85
-
86
- // During local development admin ui can use
87
- // this endpoints to write files.
88
- if (config.experimental?.admin?.enabled && command === "dev") {
89
- injectRoute({
90
- pattern: "/api/internal/fs/write-file",
91
- entrypoint: "lightnet/api/internal/fs/write-file.ts",
92
- prerender: false,
93
- })
94
- // Add empty adapter to avoid warning
95
- // about missing adapter.
96
- // This hack might break in the future :(
97
- // We could also set the "node" adapter if no
98
- // adapter has been set by user.
99
- if (!astroConfig.adapter) {
100
- updateConfig({ adapter: {} })
101
- }
102
- }
103
-
104
66
  addMiddleware({ entrypoint: "lightnet/locals", order: "pre" })
105
67
 
106
- astroConfig.integrations.push(tailwind(), react())
68
+ astroConfig.integrations.push(
69
+ tailwind({ applyBaseStyles: false }),
70
+ react(),
71
+ )
107
72
 
108
73
  updateConfig({
109
74
  vite: {