ddys-nextjs 0.1.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.
Files changed (66) hide show
  1. package/.env.example +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +196 -0
  4. package/README.zh-CN.md +196 -0
  5. package/examples/app-router/app/api/ddys/[route]/route.ts +1 -0
  6. package/examples/app-router/app/api/ddys/diagnostics/route.ts +1 -0
  7. package/examples/app-router/app/api/ddys/request/route.ts +1 -0
  8. package/examples/app-router/app/api/ddys/revalidate/route.ts +1 -0
  9. package/examples/app-router/app/ddys/calendar/page.tsx +5 -0
  10. package/examples/app-router/app/ddys/collections/page.tsx +5 -0
  11. package/examples/app-router/app/ddys/diagnostics/page.tsx +5 -0
  12. package/examples/app-router/app/ddys/genres/page.tsx +5 -0
  13. package/examples/app-router/app/ddys/hot/page.tsx +5 -0
  14. package/examples/app-router/app/ddys/latest/page.tsx +5 -0
  15. package/examples/app-router/app/ddys/layout.tsx +13 -0
  16. package/examples/app-router/app/ddys/movie/[slug]/page.tsx +15 -0
  17. package/examples/app-router/app/ddys/movie/[slug]/sources/page.tsx +12 -0
  18. package/examples/app-router/app/ddys/movies/page.tsx +5 -0
  19. package/examples/app-router/app/ddys/regions/page.tsx +5 -0
  20. package/examples/app-router/app/ddys/request/page.tsx +8 -0
  21. package/examples/app-router/app/ddys/search/page.tsx +5 -0
  22. package/examples/app-router/app/ddys/shares/page.tsx +5 -0
  23. package/examples/app-router/app/ddys/types/page.tsx +5 -0
  24. package/examples/app-router/app/manifest.ts +9 -0
  25. package/examples/app-router/app/robots.ts +5 -0
  26. package/examples/app-router/app/sitemap.ts +7 -0
  27. package/next.config.example.mjs +9 -0
  28. package/package.json +105 -0
  29. package/public/images/icon-16.png +0 -0
  30. package/public/images/icon-192.png +0 -0
  31. package/public/images/icon-32.png +0 -0
  32. package/public/images/icon-512.png +0 -0
  33. package/public/images/logo.png +0 -0
  34. package/src/actions/index.ts +2 -0
  35. package/src/actions/request.ts +26 -0
  36. package/src/actions/revalidate.ts +15 -0
  37. package/src/client/client.ts +194 -0
  38. package/src/client/config.ts +111 -0
  39. package/src/client/error.ts +15 -0
  40. package/src/client/index.ts +13 -0
  41. package/src/components/card.tsx +38 -0
  42. package/src/components/client.ts +3 -0
  43. package/src/components/diagnostics.tsx +35 -0
  44. package/src/components/grid.tsx +27 -0
  45. package/src/components/index.ts +8 -0
  46. package/src/components/movie-detail.tsx +40 -0
  47. package/src/components/request-form.tsx +50 -0
  48. package/src/components/search.tsx +41 -0
  49. package/src/components/sources.tsx +27 -0
  50. package/src/components/utils.ts +50 -0
  51. package/src/components/view.tsx +50 -0
  52. package/src/index.ts +2 -0
  53. package/src/metadata/index.ts +273 -0
  54. package/src/route-handlers/diagnostics.ts +61 -0
  55. package/src/route-handlers/index.ts +10 -0
  56. package/src/route-handlers/proxy.ts +42 -0
  57. package/src/route-handlers/request.ts +46 -0
  58. package/src/route-handlers/revalidate.ts +31 -0
  59. package/src/server/cache.ts +45 -0
  60. package/src/server/client.ts +15 -0
  61. package/src/server/config.ts +49 -0
  62. package/src/server/index.ts +11 -0
  63. package/src/server/request-service.ts +105 -0
  64. package/src/styles/ddys.css +228 -0
  65. package/src/types/ddys.ts +99 -0
  66. package/src/utils/security.ts +125 -0
package/.env.example ADDED
@@ -0,0 +1,7 @@
1
+ DDYS_API_BASE_URL=https://ddys.io/api/v1
2
+ DDYS_SITE_BASE_URL=https://ddys.io
3
+ DDYS_API_KEY=
4
+ DDYS_FORM_SECRET=
5
+ DDYS_REQUEST_FORM_ENABLED=false
6
+ DDYS_DIAGNOSTICS_ENABLED=false
7
+ DDYS_REVALIDATE_TOKEN=
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DDYS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # DDYS API Next.js Integration
2
+
3
+ [中文](README.zh-CN.md)
4
+
5
+ `ddys-nextjs` is the official Next.js App Router integration for the DDYS API. It provides a TypeScript API client, Server Components, Client Components, Route Handler factories, Server Actions, Metadata helpers, cache helpers, diagnostics, secure request-form handling, and ready-to-copy App Router examples.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install ddys-nextjs
11
+ ```
12
+
13
+ For source-package consumption, add `transpilePackages`:
14
+
15
+ ```js
16
+ // next.config.mjs
17
+ const nextConfig = {
18
+ transpilePackages: ['ddys-nextjs'],
19
+ experimental: {
20
+ cacheComponents: true
21
+ }
22
+ };
23
+
24
+ export default nextConfig;
25
+ ```
26
+
27
+ Import the stylesheet once:
28
+
29
+ ```tsx
30
+ import 'ddys-nextjs/styles.css';
31
+ ```
32
+
33
+ ## Environment
34
+
35
+ ```env
36
+ DDYS_API_BASE_URL=https://ddys.io/api/v1
37
+ DDYS_SITE_BASE_URL=https://ddys.io
38
+ DDYS_API_KEY=
39
+ DDYS_FORM_SECRET=
40
+ DDYS_REQUEST_FORM_ENABLED=false
41
+ DDYS_DIAGNOSTICS_ENABLED=false
42
+ DDYS_REVALIDATE_TOKEN=
43
+ ```
44
+
45
+ `DDYS_API_KEY`, `DDYS_FORM_SECRET`, and `DDYS_REVALIDATE_TOKEN` are server-only. Do not prefix them with `NEXT_PUBLIC_`.
46
+
47
+ ## Server Client
48
+
49
+ ```tsx
50
+ import { createDdysServerClient } from 'ddys-nextjs/server';
51
+
52
+ export default async function Page() {
53
+ const client = createDdysServerClient();
54
+ const latest = await client.latest({ limit: 12 });
55
+ return <pre>{JSON.stringify(latest, null, 2)}</pre>;
56
+ }
57
+ ```
58
+
59
+ The client supports:
60
+
61
+ `movies`, `latest`, `hot`, `search`, `suggest`, `calendar`, `movie`, `sources`, `related`, `comments`, `collections`, `collection`, `shares`, `share`, `requests`, `activities`, `user`, `types`, `genres`, `regions`, `me`, `createRequest`, `createComment`, `deleteComment`, `reportInvalidResource`, `follow`, and `unfollow`.
62
+
63
+ ## Components
64
+
65
+ ```tsx
66
+ import { DdysView } from 'ddys-nextjs/components';
67
+ import { DdysSearch, DdysRequestForm } from 'ddys-nextjs/components/client';
68
+ import { createRequestFormToken, getDdysConfigFromEnv } from 'ddys-nextjs/server';
69
+
70
+ export default async function Page() {
71
+ const config = getDdysConfigFromEnv();
72
+ const token = await createRequestFormToken(config, 'anonymous');
73
+ return (
74
+ <>
75
+ <DdysView view="latest" params={{ limit: 12 }} />
76
+ <DdysSearch />
77
+ <DdysRequestForm token={token} />
78
+ </>
79
+ );
80
+ }
81
+ ```
82
+
83
+ Available components:
84
+
85
+ - `DdysView`
86
+ - `DdysGrid`
87
+ - `DdysCard`
88
+ - `DdysMovieDetail`
89
+ - `DdysSources`
90
+ - `DdysSearch`
91
+ - `DdysRequestForm`
92
+ - `DdysDiagnostics`
93
+
94
+ Client Component files should import interactive widgets from `ddys-nextjs/components/client` so that server-only helpers never enter a browser bundle.
95
+
96
+ ## Metadata And SEO
97
+
98
+ `ddys-nextjs/metadata` is server-only and covers App Router metadata conventions:
99
+
100
+ ```tsx
101
+ import { createDdysMetadata, createDdysMovieMetadata } from 'ddys-nextjs/metadata';
102
+ import type { Metadata } from 'next';
103
+
104
+ export const metadata: Metadata = createDdysMetadata({
105
+ title: 'DDYS',
106
+ path: '/ddys'
107
+ });
108
+
109
+ export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }) {
110
+ const { slug } = await params;
111
+ return createDdysMovieMetadata(slug, {
112
+ path: `/ddys/movie/${slug}`
113
+ });
114
+ }
115
+ ```
116
+
117
+ Helpers include `createDdysMetadata`, `createDdysMovieMetadata`, `createDdysSitemap`, `createDdysRobots`, `createDdysManifest`, and `createDdysMovieJsonLd`.
118
+
119
+ ## App Router Pages
120
+
121
+ The `examples/app-router` folder includes ready-to-copy routes:
122
+
123
+ - `/ddys/latest`
124
+ - `/ddys/hot`
125
+ - `/ddys/movies`
126
+ - `/ddys/search`
127
+ - `/ddys/calendar`
128
+ - `/ddys/movie/[slug]`
129
+ - `/ddys/movie/[slug]/sources`
130
+ - `/ddys/collections`
131
+ - `/ddys/shares`
132
+ - `/ddys/types`
133
+ - `/ddys/genres`
134
+ - `/ddys/regions`
135
+ - `/ddys/request`
136
+ - `/ddys/diagnostics`
137
+ - `/sitemap.xml`
138
+ - `/robots.txt`
139
+ - `/manifest.webmanifest`
140
+
141
+ ## Route Handlers
142
+
143
+ ```ts
144
+ // app/api/ddys/[route]/route.ts
145
+ export { ddysProxyGET as GET } from 'ddys-nextjs/route-handlers';
146
+
147
+ // app/api/ddys/request/route.ts
148
+ export { ddysRequestPOST as POST } from 'ddys-nextjs/route-handlers';
149
+
150
+ // app/api/ddys/diagnostics/route.ts
151
+ export { ddysDiagnosticsGET as GET, ddysDiagnosticsTestPOST as POST } from 'ddys-nextjs/route-handlers';
152
+
153
+ // app/api/ddys/revalidate/route.ts
154
+ export { ddysRevalidatePOST as POST } from 'ddys-nextjs/route-handlers';
155
+ ```
156
+
157
+ The proxy uses an allow-list and validates route parameters before building DDYS API paths.
158
+
159
+ ## Request Form
160
+
161
+ Enable it only with an API key:
162
+
163
+ ```env
164
+ DDYS_API_KEY=...
165
+ DDYS_FORM_SECRET=...
166
+ DDYS_REQUEST_FORM_ENABLED=true
167
+ ```
168
+
169
+ The request service validates title, year, type, Douban ID, IMDb ID, honeypot, form token, and per-identity rate limit before using the authenticated DDYS API. The form token is created server-side and should be rendered into `DdysRequestForm`.
170
+
171
+ ## Cache And Revalidation
172
+
173
+ The server helper maps DDYS paths to TTL and tags:
174
+
175
+ - `ddys:latest`
176
+ - `ddys:hot`
177
+ - `ddys:movies`
178
+ - `ddys:movie:{slug}`
179
+ - `ddys:dictionary`
180
+ - `ddys:community`
181
+
182
+ Use `revalidateDdysAction()` or `/api/ddys/revalidate` with `DDYS_REVALIDATE_TOKEN` to revalidate by tag or path.
183
+
184
+ ## Diagnostics
185
+
186
+ Set `DDYS_DIAGNOSTICS_ENABLED=true`, then call `/api/ddys/diagnostics`. It returns safe config, supported views, route handlers, version, runtime, and App Router status without exposing secrets.
187
+
188
+ ## Development Checks
189
+
190
+ ```bash
191
+ node tools/check.mjs
192
+ node --test tests/structure.test.mjs
193
+ powershell -ExecutionPolicy Bypass -File tools/build-package.ps1 -Version 0.1.0
194
+ ```
195
+
196
+ The release ZIP is written to `dist/ddys-nextjs-v0.1.0.zip`.
@@ -0,0 +1,196 @@
1
+ # DDYS API Next.js 集成包
2
+
3
+ [English](README.md)
4
+
5
+ `ddys-nextjs` 是低端影视 API 的官方 Next.js App Router 集成包,提供 TypeScript API Client、Server Components、Client Components、Route Handler 工厂、Server Actions、Metadata 辅助、缓存辅助、诊断接口、安全求片表单和可直接复制的 App Router 示例。
6
+
7
+ ## 安装
8
+
9
+ ```bash
10
+ npm install ddys-nextjs
11
+ ```
12
+
13
+ 如果以源码包方式使用,请在 Next.js 配置中加入 `transpilePackages`:
14
+
15
+ ```js
16
+ // next.config.mjs
17
+ const nextConfig = {
18
+ transpilePackages: ['ddys-nextjs'],
19
+ experimental: {
20
+ cacheComponents: true
21
+ }
22
+ };
23
+
24
+ export default nextConfig;
25
+ ```
26
+
27
+ 全局引入样式:
28
+
29
+ ```tsx
30
+ import 'ddys-nextjs/styles.css';
31
+ ```
32
+
33
+ ## 环境变量
34
+
35
+ ```env
36
+ DDYS_API_BASE_URL=https://ddys.io/api/v1
37
+ DDYS_SITE_BASE_URL=https://ddys.io
38
+ DDYS_API_KEY=
39
+ DDYS_FORM_SECRET=
40
+ DDYS_REQUEST_FORM_ENABLED=false
41
+ DDYS_DIAGNOSTICS_ENABLED=false
42
+ DDYS_REVALIDATE_TOKEN=
43
+ ```
44
+
45
+ `DDYS_API_KEY`、`DDYS_FORM_SECRET`、`DDYS_REVALIDATE_TOKEN` 必须只在服务端使用,不要加 `NEXT_PUBLIC_` 前缀。
46
+
47
+ ## 服务端 Client
48
+
49
+ ```tsx
50
+ import { createDdysServerClient } from 'ddys-nextjs/server';
51
+
52
+ export default async function Page() {
53
+ const client = createDdysServerClient();
54
+ const latest = await client.latest({ limit: 12 });
55
+ return <pre>{JSON.stringify(latest, null, 2)}</pre>;
56
+ }
57
+ ```
58
+
59
+ Client 覆盖:
60
+
61
+ `movies`、`latest`、`hot`、`search`、`suggest`、`calendar`、`movie`、`sources`、`related`、`comments`、`collections`、`collection`、`shares`、`share`、`requests`、`activities`、`user`、`types`、`genres`、`regions`、`me`、`createRequest`、`createComment`、`deleteComment`、`reportInvalidResource`、`follow`、`unfollow`。
62
+
63
+ ## 组件
64
+
65
+ ```tsx
66
+ import { DdysView } from 'ddys-nextjs/components';
67
+ import { DdysSearch, DdysRequestForm } from 'ddys-nextjs/components/client';
68
+ import { createRequestFormToken, getDdysConfigFromEnv } from 'ddys-nextjs/server';
69
+
70
+ export default async function Page() {
71
+ const config = getDdysConfigFromEnv();
72
+ const token = await createRequestFormToken(config, 'anonymous');
73
+ return (
74
+ <>
75
+ <DdysView view="latest" params={{ limit: 12 }} />
76
+ <DdysSearch />
77
+ <DdysRequestForm token={token} />
78
+ </>
79
+ );
80
+ }
81
+ ```
82
+
83
+ 组件包括:
84
+
85
+ - `DdysView`
86
+ - `DdysGrid`
87
+ - `DdysCard`
88
+ - `DdysMovieDetail`
89
+ - `DdysSources`
90
+ - `DdysSearch`
91
+ - `DdysRequestForm`
92
+ - `DdysDiagnostics`
93
+
94
+ Client Component 文件应从 `ddys-nextjs/components/client` 导入交互组件,避免 server-only 辅助逻辑进入浏览器 bundle。
95
+
96
+ ## Metadata 与 SEO
97
+
98
+ `ddys-nextjs/metadata` 是服务端专用入口,覆盖 App Router 的 metadata 约定:
99
+
100
+ ```tsx
101
+ import { createDdysMetadata, createDdysMovieMetadata } from 'ddys-nextjs/metadata';
102
+ import type { Metadata } from 'next';
103
+
104
+ export const metadata: Metadata = createDdysMetadata({
105
+ title: 'DDYS',
106
+ path: '/ddys'
107
+ });
108
+
109
+ export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }) {
110
+ const { slug } = await params;
111
+ return createDdysMovieMetadata(slug, {
112
+ path: `/ddys/movie/${slug}`
113
+ });
114
+ }
115
+ ```
116
+
117
+ 辅助函数包括 `createDdysMetadata`、`createDdysMovieMetadata`、`createDdysSitemap`、`createDdysRobots`、`createDdysManifest`、`createDdysMovieJsonLd`。
118
+
119
+ ## App Router 页面
120
+
121
+ `examples/app-router` 目录提供可复制路由:
122
+
123
+ - `/ddys/latest`
124
+ - `/ddys/hot`
125
+ - `/ddys/movies`
126
+ - `/ddys/search`
127
+ - `/ddys/calendar`
128
+ - `/ddys/movie/[slug]`
129
+ - `/ddys/movie/[slug]/sources`
130
+ - `/ddys/collections`
131
+ - `/ddys/shares`
132
+ - `/ddys/types`
133
+ - `/ddys/genres`
134
+ - `/ddys/regions`
135
+ - `/ddys/request`
136
+ - `/ddys/diagnostics`
137
+ - `/sitemap.xml`
138
+ - `/robots.txt`
139
+ - `/manifest.webmanifest`
140
+
141
+ ## Route Handlers
142
+
143
+ ```ts
144
+ // app/api/ddys/[route]/route.ts
145
+ export { ddysProxyGET as GET } from 'ddys-nextjs/route-handlers';
146
+
147
+ // app/api/ddys/request/route.ts
148
+ export { ddysRequestPOST as POST } from 'ddys-nextjs/route-handlers';
149
+
150
+ // app/api/ddys/diagnostics/route.ts
151
+ export { ddysDiagnosticsGET as GET, ddysDiagnosticsTestPOST as POST } from 'ddys-nextjs/route-handlers';
152
+
153
+ // app/api/ddys/revalidate/route.ts
154
+ export { ddysRevalidatePOST as POST } from 'ddys-nextjs/route-handlers';
155
+ ```
156
+
157
+ 代理入口使用 allow-list,并在拼接 DDYS API 路径前校验 route 参数。
158
+
159
+ ## 求片表单
160
+
161
+ 只有配置 API Key 后才建议开启:
162
+
163
+ ```env
164
+ DDYS_API_KEY=...
165
+ DDYS_FORM_SECRET=...
166
+ DDYS_REQUEST_FORM_ENABLED=true
167
+ ```
168
+
169
+ 求片服务会在调用低端影视认证 API 前校验标题、年份、类型、豆瓣 ID、IMDb ID、蜜罐字段、表单 token 和单身份提交频率。表单 token 在服务端生成后传给 `DdysRequestForm`。
170
+
171
+ ## 缓存与刷新
172
+
173
+ 服务端辅助会把 DDYS 路径映射到 TTL 和 tag:
174
+
175
+ - `ddys:latest`
176
+ - `ddys:hot`
177
+ - `ddys:movies`
178
+ - `ddys:movie:{slug}`
179
+ - `ddys:dictionary`
180
+ - `ddys:community`
181
+
182
+ 使用 `revalidateDdysAction()` 或 `/api/ddys/revalidate`,配合 `DDYS_REVALIDATE_TOKEN` 按 tag 或 path 刷新缓存。
183
+
184
+ ## 诊断
185
+
186
+ 设置 `DDYS_DIAGNOSTICS_ENABLED=true` 后访问 `/api/ddys/diagnostics`。它会返回脱敏配置、支持的视图、Route Handlers、版本、运行时和 App Router 状态,不暴露密钥。
187
+
188
+ ## 开发检查
189
+
190
+ ```bash
191
+ node tools/check.mjs
192
+ node --test tests/structure.test.mjs
193
+ powershell -ExecutionPolicy Bypass -File tools/build-package.ps1 -Version 0.1.0
194
+ ```
195
+
196
+ 发布 ZIP 会生成到 `dist/ddys-nextjs-v0.1.0.zip`。
@@ -0,0 +1 @@
1
+ export { ddysProxyGET as GET } from 'ddys-nextjs/route-handlers';
@@ -0,0 +1 @@
1
+ export { ddysDiagnosticsGET as GET, ddysDiagnosticsTestPOST as POST } from 'ddys-nextjs/route-handlers';
@@ -0,0 +1 @@
1
+ export { ddysRequestPOST as POST } from 'ddys-nextjs/route-handlers';
@@ -0,0 +1 @@
1
+ export { ddysRevalidatePOST as POST } from 'ddys-nextjs/route-handlers';
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default async function Page({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) {
4
+ return <DdysView view="calendar" params={await searchParams} />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default async function Page({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) {
4
+ return <DdysView view="collections" params={await searchParams} />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysDiagnostics } from 'ddys-nextjs/components/client';
2
+
3
+ export default function Page() {
4
+ return <DdysDiagnostics />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default function Page() {
4
+ return <DdysView view="genres" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default function Page() {
4
+ return <DdysView view="hot" params={{ limit: 12 }} />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default function Page() {
4
+ return <DdysView view="latest" params={{ limit: 12 }} />;
5
+ }
@@ -0,0 +1,13 @@
1
+ import 'ddys-nextjs/styles.css';
2
+ import { createDdysMetadata } from 'ddys-nextjs/metadata';
3
+ import type { Metadata } from 'next';
4
+ import type { ReactNode } from 'react';
5
+
6
+ export const metadata: Metadata = createDdysMetadata({
7
+ title: 'DDYS',
8
+ path: '/ddys'
9
+ });
10
+
11
+ export default function DdysLayout({ children }: { children: ReactNode }) {
12
+ return <main style={{ margin: '0 auto', maxWidth: 1180, padding: '24px 18px' }}>{children}</main>;
13
+ }
@@ -0,0 +1,15 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+ import { createDdysMovieMetadata } from 'ddys-nextjs/metadata';
3
+ import type { Metadata } from 'next';
4
+
5
+ export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
6
+ const { slug } = await params;
7
+ return createDdysMovieMetadata(slug, {
8
+ path: `/ddys/movie/${encodeURIComponent(slug)}`
9
+ });
10
+ }
11
+
12
+ export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
13
+ const { slug } = await params;
14
+ return <DdysView view="movie" params={{ slug }} />;
15
+ }
@@ -0,0 +1,12 @@
1
+ import { createDdysServerClient } from 'ddys-nextjs/server';
2
+ import { DdysSources } from 'ddys-nextjs/components';
3
+ import type { DdysResource } from 'ddys-nextjs';
4
+
5
+ export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
6
+ const { slug } = await params;
7
+ const sources = await createDdysServerClient().sources(slug) as Record<string, unknown>;
8
+ const groups = {
9
+ Resources: (Array.isArray(sources) ? sources : Array.isArray(sources.resources) ? sources.resources : []) as DdysResource[]
10
+ };
11
+ return <DdysSources groups={groups} />;
12
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default async function Page({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) {
4
+ return <DdysView view="movies" params={await searchParams} />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default function Page() {
4
+ return <DdysView view="regions" />;
5
+ }
@@ -0,0 +1,8 @@
1
+ import { DdysRequestForm } from 'ddys-nextjs/components/client';
2
+ import { createRequestFormToken, getDdysConfigFromEnv } from 'ddys-nextjs/server';
3
+
4
+ export default async function Page() {
5
+ const config = getDdysConfigFromEnv();
6
+ const token = await createRequestFormToken(config, 'anonymous');
7
+ return <DdysRequestForm token={token} honeypotField={config.requestForm.honeypotField} />;
8
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysSearch } from 'ddys-nextjs/components';
2
+
3
+ export default function Page() {
4
+ return <DdysSearch />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default async function Page({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) {
4
+ return <DdysView view="shares" params={await searchParams} />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { DdysView } from 'ddys-nextjs/components';
2
+
3
+ export default function Page() {
4
+ return <DdysView view="types" />;
5
+ }
@@ -0,0 +1,9 @@
1
+ import { createDdysManifest } from 'ddys-nextjs/metadata';
2
+
3
+ export default function manifest() {
4
+ return createDdysManifest({
5
+ name: 'DDYS',
6
+ shortName: 'DDYS',
7
+ startUrl: '/ddys'
8
+ });
9
+ }
@@ -0,0 +1,5 @@
1
+ import { createDdysRobots } from 'ddys-nextjs/metadata';
2
+
3
+ export default function robots() {
4
+ return createDdysRobots();
5
+ }
@@ -0,0 +1,7 @@
1
+ import { createDdysSitemap } from 'ddys-nextjs/metadata';
2
+
3
+ export default function sitemap() {
4
+ return createDdysSitemap({
5
+ basePath: '/ddys'
6
+ });
7
+ }
@@ -0,0 +1,9 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ transpilePackages: ['ddys-nextjs'],
4
+ experimental: {
5
+ cacheComponents: true
6
+ }
7
+ };
8
+
9
+ export default nextConfig;