nextly 0.0.1 → 0.0.2-alpha.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/LICENSE +22 -0
- package/README.md +122 -0
- package/dist/_dts-chunks/collections-handler.d-DjgO74Wt.d.ts +20540 -0
- package/dist/_dts-chunks/config.d-DNwsDnjs.d.ts +2589 -0
- package/dist/_dts-chunks/define-component.d-BUgTHmt3.d.ts +1149 -0
- package/dist/_dts-chunks/image-processor.d-OO1PmMrv.d.ts +335 -0
- package/dist/_dts-chunks/index.d-axCAzZ7m.d.ts +17842 -0
- package/dist/_dts-chunks/media.d-DjDOZo4B.d.ts +117 -0
- package/dist/_dts-chunks/on-error.d-CHIKWNxd.d.ts +38 -0
- package/dist/_dts-chunks/storage.d-BUhQ2we_.d.ts +404 -0
- package/dist/actions/index.d.ts +239 -0
- package/dist/actions/index.mjs +281 -0
- package/dist/api/auth-state.d.ts +5 -0
- package/dist/api/auth-state.mjs +131 -0
- package/dist/api/collections-schema-detail.d.ts +56 -0
- package/dist/api/collections-schema-detail.mjs +244 -0
- package/dist/api/collections-schema-export.d.ts +56 -0
- package/dist/api/collections-schema-export.mjs +129 -0
- package/dist/api/collections-schema.d.ts +59 -0
- package/dist/api/collections-schema.mjs +207 -0
- package/dist/api/components-detail.d.ts +50 -0
- package/dist/api/components-detail.mjs +132 -0
- package/dist/api/components.d.ts +69 -0
- package/dist/api/components.mjs +144 -0
- package/dist/api/email-providers-default.d.ts +40 -0
- package/dist/api/email-providers-default.mjs +75 -0
- package/dist/api/email-providers-detail.d.ts +81 -0
- package/dist/api/email-providers-detail.mjs +109 -0
- package/dist/api/email-providers-test.d.ts +43 -0
- package/dist/api/email-providers-test.mjs +114 -0
- package/dist/api/email-providers.d.ts +69 -0
- package/dist/api/email-providers.mjs +110 -0
- package/dist/api/email-send-template.d.ts +41 -0
- package/dist/api/email-send-template.mjs +58 -0
- package/dist/api/email-send.d.ts +42 -0
- package/dist/api/email-send.mjs +58 -0
- package/dist/api/email-templates-detail.d.ts +74 -0
- package/dist/api/email-templates-detail.mjs +112 -0
- package/dist/api/email-templates-layout.d.ts +55 -0
- package/dist/api/email-templates-layout.mjs +92 -0
- package/dist/api/email-templates-preview.d.ts +48 -0
- package/dist/api/email-templates-preview.mjs +93 -0
- package/dist/api/email-templates.d.ts +61 -0
- package/dist/api/email-templates.mjs +118 -0
- package/dist/api/health.d.ts +68 -0
- package/dist/api/health.mjs +67 -0
- package/dist/api/index.d.ts +54 -0
- package/dist/api/index.mjs +16 -0
- package/dist/api/media-bulk.d.ts +74 -0
- package/dist/api/media-bulk.mjs +196 -0
- package/dist/api/media-folders.d.ts +112 -0
- package/dist/api/media-folders.mjs +187 -0
- package/dist/api/media-handlers.d.ts +102 -0
- package/dist/api/media-handlers.mjs +437 -0
- package/dist/api/media.d.ts +117 -0
- package/dist/api/media.mjs +242 -0
- package/dist/api/singles-detail.d.ts +87 -0
- package/dist/api/singles-detail.mjs +170 -0
- package/dist/api/singles-schema-detail.d.ts +54 -0
- package/dist/api/singles-schema-detail.mjs +182 -0
- package/dist/api/singles.d.ts +34 -0
- package/dist/api/singles.mjs +94 -0
- package/dist/api/storage-upload-url.d.ts +48 -0
- package/dist/api/storage-upload-url.mjs +202 -0
- package/dist/api/uploads.d.ts +109 -0
- package/dist/api/uploads.mjs +359 -0
- package/dist/auth/index.d.ts +425 -0
- package/dist/auth/index.mjs +199 -0
- package/dist/boot-apply-PQSYLDIN.mjs +7 -0
- package/dist/chunk-2OALJTK6.mjs +489 -0
- package/dist/chunk-2Q2SX2CS.mjs +365 -0
- package/dist/chunk-2TFX4ND3.mjs +13 -0
- package/dist/chunk-2TWPDSYD.mjs +87 -0
- package/dist/chunk-2W3DVD7S.mjs +647 -0
- package/dist/chunk-2ZFKXPQM.mjs +88 -0
- package/dist/chunk-3FA7FKAV.mjs +832 -0
- package/dist/chunk-3NZ2KMBL.mjs +58 -0
- package/dist/chunk-4MJLT6PZ.mjs +0 -0
- package/dist/chunk-56WO4WX7.mjs +0 -0
- package/dist/chunk-5APFUGAD.mjs +89 -0
- package/dist/chunk-5HMZ644B.mjs +108 -0
- package/dist/chunk-67GXH6PR.mjs +32 -0
- package/dist/chunk-6JNEPWRW.mjs +14368 -0
- package/dist/chunk-6NFHQIJD.mjs +45 -0
- package/dist/chunk-7P6ASYW6.mjs +9 -0
- package/dist/chunk-A3WPLSDT.mjs +1364 -0
- package/dist/chunk-AGJ6F2T3.mjs +144 -0
- package/dist/chunk-AK6Z23OX.mjs +1464 -0
- package/dist/chunk-APKKRD2G.mjs +102 -0
- package/dist/chunk-B2GV2BWH.mjs +73 -0
- package/dist/chunk-D5HQBNUB.mjs +74 -0
- package/dist/chunk-DNNG377Z.mjs +204 -0
- package/dist/chunk-DP3G27G5.mjs +135 -0
- package/dist/chunk-DV6WVX2Q.mjs +0 -0
- package/dist/chunk-DXGGXIUZ.mjs +57 -0
- package/dist/chunk-EGXBZCGC.mjs +943 -0
- package/dist/chunk-ERCNLX3V.mjs +176 -0
- package/dist/chunk-FQULBZ53.mjs +850 -0
- package/dist/chunk-G2AA4QLC.mjs +262 -0
- package/dist/chunk-GDBJ5JCU.mjs +488 -0
- package/dist/chunk-GJNSJU4S.mjs +19 -0
- package/dist/chunk-GZ6DCQKC.mjs +69 -0
- package/dist/chunk-H26B4FYG.mjs +167 -0
- package/dist/chunk-I4JMR3UR.mjs +21 -0
- package/dist/chunk-INV7QKLG.mjs +508 -0
- package/dist/chunk-IUDOC7N7.mjs +46 -0
- package/dist/chunk-IZWPRDC3.mjs +206 -0
- package/dist/chunk-KIMNCZGV.mjs +15 -0
- package/dist/chunk-L6HW2DA7.mjs +15 -0
- package/dist/chunk-LAZXX4HR.mjs +100 -0
- package/dist/chunk-LDKCUMHK.mjs +95 -0
- package/dist/chunk-LRXMECUA.mjs +0 -0
- package/dist/chunk-M52VMPGA.mjs +119 -0
- package/dist/chunk-MGUWEEI6.mjs +160 -0
- package/dist/chunk-NRUWQ5Z7.mjs +419 -0
- package/dist/chunk-NSEFNNU4.mjs +25360 -0
- package/dist/chunk-NTHVDFGO.mjs +138 -0
- package/dist/chunk-O3QHXMOX.mjs +3166 -0
- package/dist/chunk-P7NH2OSC.mjs +2605 -0
- package/dist/chunk-PKMABBB5.mjs +184 -0
- package/dist/chunk-PWS6XGJK.mjs +76 -0
- package/dist/chunk-R6JJQHFC.mjs +20 -0
- package/dist/chunk-RJLLGGPG.mjs +0 -0
- package/dist/chunk-SBACDPNX.mjs +689 -0
- package/dist/chunk-TO5AFLVQ.mjs +124 -0
- package/dist/chunk-TS7GHTG2.mjs +5436 -0
- package/dist/chunk-UJ2IMJ4W.mjs +133 -0
- package/dist/chunk-UOP63Q54.mjs +102 -0
- package/dist/chunk-UUOFWCM6.mjs +78 -0
- package/dist/chunk-V4EQTOA4.mjs +893 -0
- package/dist/chunk-VJ66NCL4.mjs +193 -0
- package/dist/chunk-VQJQHVEV.mjs +29 -0
- package/dist/chunk-VTJADRO3.mjs +141 -0
- package/dist/chunk-VWF3JO32.mjs +0 -0
- package/dist/chunk-W4MGXIRR.mjs +27 -0
- package/dist/chunk-W5KKPZT5.mjs +1204 -0
- package/dist/chunk-WD34YQ6T.mjs +381 -0
- package/dist/chunk-WZBYMYVW.mjs +14 -0
- package/dist/chunk-X23WKS3Z.mjs +50 -0
- package/dist/chunk-X7TXCYYN.mjs +6496 -0
- package/dist/chunk-XGI4EMS3.mjs +140 -0
- package/dist/chunk-XZKLBMN6.mjs +1153 -0
- package/dist/chunk-YB7INWPY.mjs +0 -0
- package/dist/chunk-YV4Y7SDL.mjs +83 -0
- package/dist/chunk-YZNBLFIW.mjs +1688 -0
- package/dist/chunk-YZZCTONM.mjs +263 -0
- package/dist/chunk-ZE6A3FYH.mjs +289 -0
- package/dist/cli/nextly.mjs +68 -0
- package/dist/cli/utils/index.d.ts +449 -0
- package/dist/cli/utils/index.mjs +49 -0
- package/dist/component-schema-service-5577KVW6.mjs +11 -0
- package/dist/config-loader-23YEMC3Z.mjs +23 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.mjs +109 -0
- package/dist/container-ORGFGYSZ.mjs +9 -0
- package/dist/database/index.d.ts +12 -0
- package/dist/database/index.mjs +40 -0
- package/dist/database/seeders/index.d.ts +93 -0
- package/dist/database/seeders/index.mjs +47 -0
- package/dist/db-sync-demote-LJGKLB3S.mjs +117 -0
- package/dist/db-sync-promote-B26VSYQF.mjs +113 -0
- package/dist/dev-reload-broadcaster-B73IQ53V.mjs +25 -0
- package/dist/dist-M2NOU37V.mjs +19 -0
- package/dist/drizzle-kit-lazy-D2M2PXR2.mjs +13 -0
- package/dist/dynamic-collection-schema-service-IEXTPIZ7.mjs +8 -0
- package/dist/errors/index.d.ts +159 -0
- package/dist/errors/index.mjs +10 -0
- package/dist/factory-IWMBKUJM.mjs +15 -0
- package/dist/first-run-QIVKWJIF.mjs +63 -0
- package/dist/fresh-push-NR67DC3R.mjs +8 -0
- package/dist/index.d.ts +4175 -0
- package/dist/index.mjs +1336 -0
- package/dist/local-plugin-PTET4NAT.mjs +7 -0
- package/dist/logger-NU46DXNY.mjs +15 -0
- package/dist/logger-YE4TC7ZN.mjs +9 -0
- package/dist/migration-journal-EP532Y4L.mjs +139 -0
- package/dist/migrations/mysql/0000_eager_sentry.sql +174 -0
- package/dist/migrations/mysql/0001_soft_giant_girl.sql +27 -0
- package/dist/migrations/mysql/0002_media_table.sql +24 -0
- package/dist/migrations/mysql/0003_dynamic_singles.sql +37 -0
- package/dist/migrations/mysql/0004_dynamic_components.sql +35 -0
- package/dist/migrations/mysql/0005_user_management_tables.sql +92 -0
- package/dist/migrations/mysql/0006_api_keys.sql +36 -0
- package/dist/migrations/mysql/0007_general_settings.sql +20 -0
- package/dist/migrations/mysql/0008_site_settings_logo_url.sql +9 -0
- package/dist/migrations/mysql/0009_activity_log.sql +30 -0
- package/dist/migrations/mysql/0010_site_settings_sidebar.sql +13 -0
- package/dist/migrations/mysql/0011_missing_tables_and_columns.sql +54 -0
- package/dist/migrations/mysql/0012_image_sizes_and_focal_point.sql +30 -0
- package/dist/migrations/mysql/0012_media_folders.sql +43 -0
- package/dist/migrations/mysql/0013_user_brute_force_protection.sql +31 -0
- package/dist/migrations/mysql/0014_email_template_attachments.sql +12 -0
- package/dist/migrations/mysql/0015_media_uploaded_by_nullable.sql +15 -0
- package/dist/migrations/mysql/20260429_000000_000_initial_journal.sql +22 -0
- package/dist/migrations/mysql/20260501_000000_journal_batch.sql +17 -0
- package/dist/migrations/mysql/20260501_000001_audit_log.sql +24 -0
- package/dist/migrations/mysql/20260504_000000_nextly_meta.sql +21 -0
- package/dist/migrations/mysql/meta/0000_snapshot.json +1005 -0
- package/dist/migrations/mysql/meta/0001_snapshot.json +1099 -0
- package/dist/migrations/mysql/meta/_journal.json +41 -0
- package/dist/migrations/postgresql/0000_misty_king_bedlam.sql +169 -0
- package/dist/migrations/postgresql/0001_perpetual_captain_marvel.sql +8 -0
- package/dist/migrations/postgresql/0002_sad_spectrum.sql +16 -0
- package/dist/migrations/postgresql/0003_hesitant_ultron.sql +17 -0
- package/dist/migrations/postgresql/0004_media_table.sql +24 -0
- package/dist/migrations/postgresql/0005_media_folders.sql +36 -0
- package/dist/migrations/postgresql/0006_dynamic_collections_update.sql +50 -0
- package/dist/migrations/postgresql/0007_dynamic_singles.sql +38 -0
- package/dist/migrations/postgresql/0008_dynamic_components.sql +37 -0
- package/dist/migrations/postgresql/0009_user_management_tables.sql +95 -0
- package/dist/migrations/postgresql/0010_api_keys.sql +34 -0
- package/dist/migrations/postgresql/0011_general_settings.sql +20 -0
- package/dist/migrations/postgresql/0012_site_settings_logo_url.sql +9 -0
- package/dist/migrations/postgresql/0013_activity_log.sql +29 -0
- package/dist/migrations/postgresql/0014_image_sizes_and_focal_point.sql +33 -0
- package/dist/migrations/postgresql/0014_site_settings_sidebar.sql +13 -0
- package/dist/migrations/postgresql/0015_user_brute_force_protection.sql +29 -0
- package/dist/migrations/postgresql/0016_email_template_attachments.sql +12 -0
- package/dist/migrations/postgresql/0017_media_uploaded_by_nullable.sql +15 -0
- package/dist/migrations/postgresql/20260429_000000_000_initial_journal.sql +24 -0
- package/dist/migrations/postgresql/20260501_000000_journal_batch.sql +17 -0
- package/dist/migrations/postgresql/20260501_000001_audit_log.sql +24 -0
- package/dist/migrations/postgresql/20260504_000000_nextly_meta.sql +22 -0
- package/dist/migrations/postgresql/meta/0000_snapshot.json +1286 -0
- package/dist/migrations/postgresql/meta/0001_snapshot.json +1407 -0
- package/dist/migrations/postgresql/meta/0002_snapshot.json +1552 -0
- package/dist/migrations/postgresql/meta/0003_snapshot.json +1695 -0
- package/dist/migrations/postgresql/meta/0010_snapshot.json +2345 -0
- package/dist/migrations/postgresql/meta/_journal.json +90 -0
- package/dist/migrations/sqlite/0000_api_keys.sql +34 -0
- package/dist/migrations/sqlite/0001_general_settings.sql +20 -0
- package/dist/migrations/sqlite/0002_site_settings_logo_url.sql +9 -0
- package/dist/migrations/sqlite/0003_activity_log.sql +29 -0
- package/dist/migrations/sqlite/0004_image_sizes_and_focal_point.sql +29 -0
- package/dist/migrations/sqlite/0004_site_settings_sidebar.sql +11 -0
- package/dist/migrations/sqlite/0005_user_brute_force_protection.sql +29 -0
- package/dist/migrations/sqlite/0006_email_template_attachments.sql +12 -0
- package/dist/migrations/sqlite/0007_media_uploaded_by_nullable.sql +111 -0
- package/dist/migrations/sqlite/20260429_000000_000_initial_journal.sql +24 -0
- package/dist/migrations/sqlite/20260501_000000_journal_batch.sql +19 -0
- package/dist/migrations/sqlite/20260501_000001_audit_log.sql +24 -0
- package/dist/migrations/sqlite/20260504_000000_nextly_meta.sql +21 -0
- package/dist/migrations/sqlite/20260505_000000_user_management_tables.sql +77 -0
- package/dist/next.d.ts +57 -0
- package/dist/next.mjs +55 -0
- package/dist/observability/index.d.ts +87 -0
- package/dist/observability/index.mjs +57 -0
- package/dist/permissions-3DZZQZMI.mjs +39 -0
- package/dist/pipeline-YOML7SWF.mjs +29 -0
- package/dist/preview-ZZTR3QGS.mjs +9 -0
- package/dist/program-PW6UB2ZC.mjs +5934 -0
- package/dist/reconcile-single-tables-7ENVXJGB.mjs +7 -0
- package/dist/register-SF6E6FVU.mjs +49 -0
- package/dist/reload-config-HWQ4G5MM.mjs +23 -0
- package/dist/resolve-single-table-name-JSOMUB3R.mjs +7 -0
- package/dist/routeHandler-UNMMJIBM.mjs +77 -0
- package/dist/runtime-schema-generator-NRA6A6Z6.mjs +8 -0
- package/dist/runtime.d.ts +120 -0
- package/dist/runtime.mjs +73 -0
- package/dist/schema-hash-FMMG6VPJ.mjs +13 -0
- package/dist/schema-registry-EQ36FZDP.mjs +7 -0
- package/dist/scripts/load-env.mjs +42 -0
- package/dist/storage/index.d.ts +566 -0
- package/dist/storage/index.mjs +45 -0
- package/dist/super-admin-G5ZK5F4T.mjs +39 -0
- package/dist/system-table-service-WGSRVEGT.mjs +17 -0
- package/dist/users-7KELGRYJ.mjs +38 -0
- package/package.json +308 -9
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health Check Route Handlers for Next.js
|
|
3
|
+
*
|
|
4
|
+
* These route handlers can be re-exported in your Next.js application to provide
|
|
5
|
+
* a production-ready health check endpoint at /api/health.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // In your Next.js app: app/api/health/route.ts
|
|
10
|
+
* export { GET, HEAD } from 'nextly/api/health';
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @module api/health
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* GET handler for health check endpoint.
|
|
17
|
+
*
|
|
18
|
+
* Returns the current database/runtime health as a bare object body via
|
|
19
|
+
* `respondData`. The body merges the database probe with the package
|
|
20
|
+
* version and process uptime so monitoring dashboards have a
|
|
21
|
+
* non-Boolean-only payload to assert against (spec §5.1 rule 3 / §7.7).
|
|
22
|
+
* When the underlying check reports `ok: false`, the handler throws a 503
|
|
23
|
+
* `SERVICE_UNAVAILABLE` `NextlyError` so the route boundary serializes it
|
|
24
|
+
* as `application/problem+json`. The unhealthy detail (latency, dialect,
|
|
25
|
+
* error string) is logged via `logContext` rather than echoed to the
|
|
26
|
+
* public response; anonymous monitoring scrapers should not learn
|
|
27
|
+
* implementation specifics.
|
|
28
|
+
*
|
|
29
|
+
* Response Codes:
|
|
30
|
+
* - 200 OK: Database is healthy. Body:
|
|
31
|
+
* `{ ok, version, uptime, timestamp, database }`.
|
|
32
|
+
* - 503 Service Unavailable: Database is unreachable or unhealthy. Body:
|
|
33
|
+
* `{ error: { code: "SERVICE_UNAVAILABLE", message, requestId } }`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```bash
|
|
37
|
+
* curl http://localhost:3000/api/health
|
|
38
|
+
* # => {"ok":true,"version":"0.0.142","uptime":123,"timestamp":"...","database":{...}}
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
declare const GET: (_request: Request) => Promise<Response>;
|
|
42
|
+
/**
|
|
43
|
+
* HEAD handler for lightweight health check.
|
|
44
|
+
*
|
|
45
|
+
* Returns only the HTTP status code and headers without body content. Useful
|
|
46
|
+
* for monitoring systems that only need to verify the endpoint is responding.
|
|
47
|
+
* HEAD is intentionally not wrapped in `withErrorHandler` because the wrapper
|
|
48
|
+
* always emits a JSON body on the error path, which violates HEAD semantics
|
|
49
|
+
* (per RFC 9110 HEAD responses must not include a body). Unexpected throws
|
|
50
|
+
* propagate to Next.js's runtime; in production this surfaces as a 500 with
|
|
51
|
+
* no body, matching the pre-migration behavior.
|
|
52
|
+
*
|
|
53
|
+
* `X-Request-Id` is set so log lines emitted by `healthCheck()` can be
|
|
54
|
+
* correlated to a probe even though HEAD bypasses the route boundary.
|
|
55
|
+
*
|
|
56
|
+
* Response Codes:
|
|
57
|
+
* - 200 OK: Database is healthy
|
|
58
|
+
* - 503 Service Unavailable: Database is unhealthy
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```bash
|
|
62
|
+
* curl -I http://localhost:3000/api/health
|
|
63
|
+
* # => HTTP/1.1 200 OK
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
declare function HEAD(request: Request): Promise<Response>;
|
|
67
|
+
|
|
68
|
+
export { GET, HEAD };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withErrorHandler
|
|
3
|
+
} from "../chunk-TO5AFLVQ.mjs";
|
|
4
|
+
import {
|
|
5
|
+
readOrGenerateRequestId
|
|
6
|
+
} from "../chunk-67GXH6PR.mjs";
|
|
7
|
+
import "../chunk-2TFX4ND3.mjs";
|
|
8
|
+
import "../chunk-W4MGXIRR.mjs";
|
|
9
|
+
import {
|
|
10
|
+
respondData
|
|
11
|
+
} from "../chunk-IUDOC7N7.mjs";
|
|
12
|
+
import {
|
|
13
|
+
healthCheck
|
|
14
|
+
} from "../chunk-LAZXX4HR.mjs";
|
|
15
|
+
import "../chunk-D5HQBNUB.mjs";
|
|
16
|
+
import {
|
|
17
|
+
NextlyError
|
|
18
|
+
} from "../chunk-NRUWQ5Z7.mjs";
|
|
19
|
+
import "../chunk-7P6ASYW6.mjs";
|
|
20
|
+
|
|
21
|
+
// src/api/health.ts
|
|
22
|
+
var PACKAGE_VERSION = (
|
|
23
|
+
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
24
|
+
typeof process !== "undefined" && process.env?.npm_package_version || "unknown"
|
|
25
|
+
);
|
|
26
|
+
function readUptimeSeconds() {
|
|
27
|
+
if (typeof process === "undefined" || typeof process.uptime !== "function") {
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
return Math.floor(process.uptime());
|
|
31
|
+
}
|
|
32
|
+
var HEALTH_CHECK_CACHE_SECONDS = typeof process !== "undefined" && process.env?.HEALTH_CHECK_CACHE_SECONDS ? Number(process.env.HEALTH_CHECK_CACHE_SECONDS) : 60;
|
|
33
|
+
var HEALTH_CACHE_CONTROL = `public, max-age=${HEALTH_CHECK_CACHE_SECONDS}, stale-while-revalidate=30`;
|
|
34
|
+
var GET = withErrorHandler(async (_request) => {
|
|
35
|
+
const health = await healthCheck();
|
|
36
|
+
if (!health.ok) {
|
|
37
|
+
throw NextlyError.serviceUnavailable({
|
|
38
|
+
logMessage: "Health check failed",
|
|
39
|
+
logContext: { health }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return respondData(
|
|
43
|
+
{
|
|
44
|
+
...health,
|
|
45
|
+
version: PACKAGE_VERSION,
|
|
46
|
+
uptime: readUptimeSeconds()
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
headers: { "Cache-Control": HEALTH_CACHE_CONTROL }
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
async function HEAD(request) {
|
|
54
|
+
const requestId = readOrGenerateRequestId(request);
|
|
55
|
+
const health = await healthCheck();
|
|
56
|
+
return new Response(null, {
|
|
57
|
+
status: health.ok ? 200 : 503,
|
|
58
|
+
headers: {
|
|
59
|
+
"Cache-Control": HEALTH_CACHE_CONTROL,
|
|
60
|
+
"X-Request-Id": requestId
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
GET,
|
|
66
|
+
HEAD
|
|
67
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { O as OnErrorHook } from '../_dts-chunks/on-error.d-CHIKWNxd.d.ts';
|
|
2
|
+
import '../errors/index.d.ts';
|
|
3
|
+
|
|
4
|
+
type WithErrorHandlerOptions = {
|
|
5
|
+
/** Per-call observability hook. Fired before the global hook. */
|
|
6
|
+
onError?: OnErrorHook;
|
|
7
|
+
/** Public message used when wrapping unknown errors. Default: generic. */
|
|
8
|
+
internalErrorMessage?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* HTTP boundary wrapper for Next.js App Router Route Handlers.
|
|
12
|
+
*
|
|
13
|
+
* Responsibilities (in order, per spec §11.2):
|
|
14
|
+
* 1. Read or generate a Stripe-style `requestId` for this request.
|
|
15
|
+
* 2. Run the handler.
|
|
16
|
+
* 3. On thrown values: pass Next.js sentinel errors (`redirect`, `notFound`,
|
|
17
|
+
* dynamic-API bailouts) through `unstable_rethrow` first.
|
|
18
|
+
* 4. Otherwise classify: `NextlyError` directly, `DbError` via the safety
|
|
19
|
+
* net, anything else wrapped as `NextlyError.internal`.
|
|
20
|
+
* 5. Log the classified error.
|
|
21
|
+
* 6. Fire the per-call `onError` hook, then the global one. Hook failures
|
|
22
|
+
* are logged but never poison the response.
|
|
23
|
+
* 7. Serialize via `toResponseJSON(requestId)` with `application/problem+json`
|
|
24
|
+
* content type, the response status, and `X-Request-Id`. `Retry-After`
|
|
25
|
+
* is set for `RATE_LIMITED`.
|
|
26
|
+
*
|
|
27
|
+
* Generic over `TArgs` so it transparently supports both static handlers
|
|
28
|
+
* (`(req)`) and dynamic-segment handlers (`(req, { params })`).
|
|
29
|
+
*/
|
|
30
|
+
declare function withErrorHandler<TArgs extends unknown[]>(handler: (...args: TArgs) => Promise<Response>, options?: WithErrorHandlerOptions): (...args: TArgs) => Promise<Response>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Stripe-style request IDs (`req_<16 base32 chars>`) for the unified error
|
|
34
|
+
* system. Generated at the boundary by withErrorHandler / withAction unless
|
|
35
|
+
* an upstream proxy already set `x-request-id` (or one of the cloud-provider
|
|
36
|
+
* variants Vercel and Cloudflare emit), in which case we honor it so a
|
|
37
|
+
* single user request shares one id across all hops.
|
|
38
|
+
*
|
|
39
|
+
* Format: `req_` prefix + 16 chars of RFC 4648 base32-lowercase. 10 random
|
|
40
|
+
* bytes provide 80 bits of entropy — uniquely identifying every request at
|
|
41
|
+
* any reasonable scale.
|
|
42
|
+
*
|
|
43
|
+
* Works in both Node and Edge runtimes (uses Web Crypto's
|
|
44
|
+
* `crypto.getRandomValues`).
|
|
45
|
+
*/
|
|
46
|
+
declare function generateRequestId(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Read an upstream-set request id, falling back to a freshly generated one.
|
|
49
|
+
* Header precedence (most-specific first): `x-request-id` (our convention) >
|
|
50
|
+
* `x-vercel-id` (Vercel) > `cf-ray` (Cloudflare).
|
|
51
|
+
*/
|
|
52
|
+
declare function readOrGenerateRequestId(req: Request): string;
|
|
53
|
+
|
|
54
|
+
export { generateRequestId, readOrGenerateRequestId, withErrorHandler };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withErrorHandler
|
|
3
|
+
} from "../chunk-TO5AFLVQ.mjs";
|
|
4
|
+
import {
|
|
5
|
+
generateRequestId,
|
|
6
|
+
readOrGenerateRequestId
|
|
7
|
+
} from "../chunk-67GXH6PR.mjs";
|
|
8
|
+
import "../chunk-2TFX4ND3.mjs";
|
|
9
|
+
import "../chunk-W4MGXIRR.mjs";
|
|
10
|
+
import "../chunk-NRUWQ5Z7.mjs";
|
|
11
|
+
import "../chunk-7P6ASYW6.mjs";
|
|
12
|
+
export {
|
|
13
|
+
generateRequestId,
|
|
14
|
+
readOrGenerateRequestId,
|
|
15
|
+
withErrorHandler
|
|
16
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bulk Media API Route Handlers for Next.js
|
|
3
|
+
*
|
|
4
|
+
* These route handlers provide bulk operations for media management.
|
|
5
|
+
* Supports bulk upload and bulk delete with parallel processing.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: Before using these routes, you must initialize the service layer by calling
|
|
8
|
+
* `registerServices()` during your application startup.
|
|
9
|
+
*
|
|
10
|
+
* Wire shape:
|
|
11
|
+
* - DELETE returns the canonical respondBulk envelope:
|
|
12
|
+
* `{ message, items, errors }` where items are minimal `{id}` records
|
|
13
|
+
* for deleted files and errors are id-keyed PerItemError entries.
|
|
14
|
+
* - POST returns the canonical respondBulkUpload envelope:
|
|
15
|
+
* `{ message, items, errors }` where items are full MediaFile records
|
|
16
|
+
* for newly-uploaded files and errors are positional BulkUploadError
|
|
17
|
+
* entries (`{ index, filename, code, message }`).
|
|
18
|
+
*
|
|
19
|
+
* Per-item failures are first-class data in the body's `errors` array
|
|
20
|
+
* (HTTP 200). 4xx is reserved for malformed requests (e.g. empty input,
|
|
21
|
+
* all entries failed input validation before the service was reached).
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // In your Next.js app: app/api/media/bulk/route.ts
|
|
26
|
+
* export { POST, DELETE } from 'nextly/api/media-bulk';
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @module api/media-bulk
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* POST handler for bulk media upload.
|
|
33
|
+
*
|
|
34
|
+
* Uploads multiple files. Provides detailed per-file results, positional
|
|
35
|
+
* (index + filename) for failures since uploads have no client-supplied id.
|
|
36
|
+
*
|
|
37
|
+
* Request Body (JSON):
|
|
38
|
+
* {
|
|
39
|
+
* files: Array<{
|
|
40
|
+
* file: string (base64),
|
|
41
|
+
* filename: string,
|
|
42
|
+
* mimeType: string,
|
|
43
|
+
* size: number,
|
|
44
|
+
* uploadedBy: string
|
|
45
|
+
* }>,
|
|
46
|
+
* uploadedBy?: string,
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* Response: canonical respondBulkUpload envelope `{ message, items, errors }`.
|
|
50
|
+
* Items are full MediaFile records for newly-uploaded files; errors are
|
|
51
|
+
* positional BulkUploadError entries. Pre-upload validation failures fold
|
|
52
|
+
* into the same `errors` array (no parallel `validationErrors` field;
|
|
53
|
+
* unified failure list). Status 200 for partial-success.
|
|
54
|
+
*
|
|
55
|
+
* 4xx applies only to fully-malformed requests: empty `files` array, or
|
|
56
|
+
* every entry failed input validation (no useful service work to do).
|
|
57
|
+
*/
|
|
58
|
+
declare const POST: (request: Request) => Promise<Response>;
|
|
59
|
+
/**
|
|
60
|
+
* DELETE handler for bulk media deletion.
|
|
61
|
+
*
|
|
62
|
+
* Response: canonical respondBulk envelope `{ message, items, errors }`.
|
|
63
|
+
* Items are minimal `{id}` records (the files are gone); errors are
|
|
64
|
+
* id-keyed PerItemError entries. Status 200 for partial-success; 400
|
|
65
|
+
* only for an empty/malformed `mediaIds` array.
|
|
66
|
+
*
|
|
67
|
+
* Request Body (JSON):
|
|
68
|
+
* {
|
|
69
|
+
* mediaIds: string[]
|
|
70
|
+
* }
|
|
71
|
+
*/
|
|
72
|
+
declare const DELETE: (request: Request) => Promise<Response>;
|
|
73
|
+
|
|
74
|
+
export { DELETE, POST };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readJsonBody
|
|
3
|
+
} from "../chunk-VQJQHVEV.mjs";
|
|
4
|
+
import "../chunk-VWF3JO32.mjs";
|
|
5
|
+
import {
|
|
6
|
+
withErrorHandler
|
|
7
|
+
} from "../chunk-TO5AFLVQ.mjs";
|
|
8
|
+
import {
|
|
9
|
+
getService,
|
|
10
|
+
isServicesRegistered
|
|
11
|
+
} from "../chunk-X7TXCYYN.mjs";
|
|
12
|
+
import "../chunk-YZNBLFIW.mjs";
|
|
13
|
+
import "../chunk-FQULBZ53.mjs";
|
|
14
|
+
import "../chunk-67GXH6PR.mjs";
|
|
15
|
+
import "../chunk-2TFX4ND3.mjs";
|
|
16
|
+
import "../chunk-W4MGXIRR.mjs";
|
|
17
|
+
import {
|
|
18
|
+
UploadMediaInputSchema
|
|
19
|
+
} from "../chunk-NSEFNNU4.mjs";
|
|
20
|
+
import "../chunk-3FA7FKAV.mjs";
|
|
21
|
+
import "../chunk-AGJ6F2T3.mjs";
|
|
22
|
+
import "../chunk-KIMNCZGV.mjs";
|
|
23
|
+
import "../chunk-AK6Z23OX.mjs";
|
|
24
|
+
import "../chunk-INV7QKLG.mjs";
|
|
25
|
+
import "../chunk-GZ6DCQKC.mjs";
|
|
26
|
+
import "../chunk-SBACDPNX.mjs";
|
|
27
|
+
import "../chunk-RJLLGGPG.mjs";
|
|
28
|
+
import "../chunk-V4EQTOA4.mjs";
|
|
29
|
+
import "../chunk-I4JMR3UR.mjs";
|
|
30
|
+
import "../chunk-XZKLBMN6.mjs";
|
|
31
|
+
import "../chunk-IZWPRDC3.mjs";
|
|
32
|
+
import "../chunk-DNNG377Z.mjs";
|
|
33
|
+
import "../chunk-5HMZ644B.mjs";
|
|
34
|
+
import "../chunk-W5KKPZT5.mjs";
|
|
35
|
+
import "../chunk-56WO4WX7.mjs";
|
|
36
|
+
import "../chunk-2W3DVD7S.mjs";
|
|
37
|
+
import "../chunk-TS7GHTG2.mjs";
|
|
38
|
+
import "../chunk-H26B4FYG.mjs";
|
|
39
|
+
import "../chunk-DP3G27G5.mjs";
|
|
40
|
+
import "../chunk-DV6WVX2Q.mjs";
|
|
41
|
+
import "../chunk-UJ2IMJ4W.mjs";
|
|
42
|
+
import "../chunk-EGXBZCGC.mjs";
|
|
43
|
+
import "../chunk-G2AA4QLC.mjs";
|
|
44
|
+
import "../chunk-4MJLT6PZ.mjs";
|
|
45
|
+
import {
|
|
46
|
+
respondBulk,
|
|
47
|
+
respondBulkUpload
|
|
48
|
+
} from "../chunk-IUDOC7N7.mjs";
|
|
49
|
+
import "../chunk-LAZXX4HR.mjs";
|
|
50
|
+
import "../chunk-D5HQBNUB.mjs";
|
|
51
|
+
import {
|
|
52
|
+
NextlyError
|
|
53
|
+
} from "../chunk-NRUWQ5Z7.mjs";
|
|
54
|
+
import "../chunk-VTJADRO3.mjs";
|
|
55
|
+
import "../chunk-5APFUGAD.mjs";
|
|
56
|
+
import "../chunk-7P6ASYW6.mjs";
|
|
57
|
+
|
|
58
|
+
// src/api/media-bulk.ts
|
|
59
|
+
function getMediaService() {
|
|
60
|
+
if (!isServicesRegistered()) {
|
|
61
|
+
throw NextlyError.serviceUnavailable({
|
|
62
|
+
logMessage: "Media bulk handler called before registerServices()",
|
|
63
|
+
logContext: {
|
|
64
|
+
hint: "Call registerServices() before mounting media-bulk routes. See https://nextlyhq.com/docs/initialization"
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return getService("mediaService");
|
|
69
|
+
}
|
|
70
|
+
function createAuthenticatedContext(userId) {
|
|
71
|
+
if (!userId) return {};
|
|
72
|
+
return {
|
|
73
|
+
user: {
|
|
74
|
+
id: userId,
|
|
75
|
+
email: `${userId}@api.local`,
|
|
76
|
+
role: "user",
|
|
77
|
+
permissions: []
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
var POST = withErrorHandler(
|
|
82
|
+
async (request) => {
|
|
83
|
+
const mediaService = getMediaService();
|
|
84
|
+
const body = await readJsonBody(request);
|
|
85
|
+
const filesInput = body.files;
|
|
86
|
+
const uploadedBy = typeof body.uploadedBy === "string" ? body.uploadedBy : void 0;
|
|
87
|
+
if (!Array.isArray(filesInput) || filesInput.length === 0) {
|
|
88
|
+
throw NextlyError.validation({
|
|
89
|
+
errors: [
|
|
90
|
+
{
|
|
91
|
+
path: "files",
|
|
92
|
+
code: "required_array",
|
|
93
|
+
message: "files must be a non-empty array."
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const validatedFiles = [];
|
|
99
|
+
const failures = [];
|
|
100
|
+
for (let i = 0; i < filesInput.length; i++) {
|
|
101
|
+
const file = filesInput[i];
|
|
102
|
+
const filename = file.filename || `file-${i}`;
|
|
103
|
+
let buffer;
|
|
104
|
+
if (typeof file.file === "string") {
|
|
105
|
+
buffer = Buffer.from(file.file, "base64");
|
|
106
|
+
} else if (Buffer.isBuffer(file.file)) {
|
|
107
|
+
buffer = file.file;
|
|
108
|
+
} else {
|
|
109
|
+
failures.push({
|
|
110
|
+
index: i,
|
|
111
|
+
filename,
|
|
112
|
+
code: "VALIDATION_ERROR",
|
|
113
|
+
message: "Invalid file format."
|
|
114
|
+
});
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const parseResult = UploadMediaInputSchema.safeParse({
|
|
118
|
+
file: buffer,
|
|
119
|
+
filename: file.filename,
|
|
120
|
+
mimeType: file.mimeType,
|
|
121
|
+
size: file.size || buffer.length,
|
|
122
|
+
uploadedBy: file.uploadedBy || uploadedBy
|
|
123
|
+
});
|
|
124
|
+
if (!parseResult.success) {
|
|
125
|
+
failures.push({
|
|
126
|
+
index: i,
|
|
127
|
+
filename,
|
|
128
|
+
code: "VALIDATION_ERROR",
|
|
129
|
+
message: "Validation failed."
|
|
130
|
+
});
|
|
131
|
+
} else {
|
|
132
|
+
validatedFiles.push({
|
|
133
|
+
buffer,
|
|
134
|
+
filename: file.filename,
|
|
135
|
+
mimeType: file.mimeType,
|
|
136
|
+
size: file.size || buffer.length,
|
|
137
|
+
originalIndex: i
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (validatedFiles.length === 0) {
|
|
142
|
+
throw NextlyError.validation({
|
|
143
|
+
errors: failures.map((f) => ({
|
|
144
|
+
path: `files[${f.index}]`,
|
|
145
|
+
code: "INVALID_FILE",
|
|
146
|
+
message: f.message
|
|
147
|
+
})),
|
|
148
|
+
logContext: { totalFiles: filesInput.length }
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
const firstFile = filesInput[0];
|
|
152
|
+
const userId = firstFile.uploadedBy || uploadedBy || null;
|
|
153
|
+
const context = createAuthenticatedContext(userId);
|
|
154
|
+
const serviceInputs = validatedFiles.map(({ originalIndex: _, ...rest }) => rest);
|
|
155
|
+
const result = await mediaService.bulkUpload(serviceInputs, context);
|
|
156
|
+
for (const f of result.failures) {
|
|
157
|
+
const original = validatedFiles[f.index];
|
|
158
|
+
failures.push({
|
|
159
|
+
index: original?.originalIndex ?? f.index,
|
|
160
|
+
filename: f.filename,
|
|
161
|
+
code: f.code,
|
|
162
|
+
message: f.message
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
const totalRequested = filesInput.length;
|
|
166
|
+
const successCount = result.successCount;
|
|
167
|
+
const message = failures.length === 0 ? `Uploaded ${successCount} ${successCount === 1 ? "file" : "files"}.` : `Uploaded ${successCount} of ${totalRequested} files.`;
|
|
168
|
+
return respondBulkUpload(message, result.successes, failures);
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
var DELETE = withErrorHandler(
|
|
172
|
+
async (request) => {
|
|
173
|
+
const mediaService = getMediaService();
|
|
174
|
+
const body = await readJsonBody(request);
|
|
175
|
+
const mediaIds = body.mediaIds;
|
|
176
|
+
if (!Array.isArray(mediaIds) || mediaIds.length === 0) {
|
|
177
|
+
throw NextlyError.validation({
|
|
178
|
+
errors: [
|
|
179
|
+
{
|
|
180
|
+
path: "mediaIds",
|
|
181
|
+
code: "required_array",
|
|
182
|
+
message: "mediaIds must be a non-empty array."
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const context = {};
|
|
188
|
+
const result = await mediaService.bulkDelete(mediaIds, context);
|
|
189
|
+
const message = result.failures.length === 0 ? `Deleted ${result.successCount} ${result.successCount === 1 ? "file" : "files"}.` : `Deleted ${result.successCount} of ${result.total} files.`;
|
|
190
|
+
return respondBulk(message, result.successes, result.failures);
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
export {
|
|
194
|
+
DELETE,
|
|
195
|
+
POST
|
|
196
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { NextRequest } from 'next/server';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Media Folders API Route Handlers
|
|
5
|
+
*
|
|
6
|
+
* Next.js App Router compatible handlers for folder management operations.
|
|
7
|
+
* Re-export these handlers in your app's API routes.
|
|
8
|
+
*
|
|
9
|
+
* **IMPORTANT:** For storage plugins to work, initialize Nextly with your config
|
|
10
|
+
* via instrumentation.ts before these routes are called.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // app/api/media/folders/route.ts
|
|
15
|
+
* export { GET, POST } from 'nextly/api/media-folders';
|
|
16
|
+
*
|
|
17
|
+
* // app/api/media/folders/[id]/route.ts
|
|
18
|
+
* export { getFolderById as GET, updateFolder as PATCH, deleteFolder as DELETE } from 'nextly/api/media-folders';
|
|
19
|
+
*
|
|
20
|
+
* // app/api/media/folders/[id]/contents/route.ts
|
|
21
|
+
* export { getFolderContents as GET } from 'nextly/api/media-folders';
|
|
22
|
+
*
|
|
23
|
+
* // app/api/media/folders/root/contents/route.ts
|
|
24
|
+
* export { getRootFolderContents as GET } from 'nextly/api/media-folders';
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* GET /api/media/folders
|
|
30
|
+
*
|
|
31
|
+
* List folders with optional filtering:
|
|
32
|
+
* - ?root=true - List only root folders (no parent)
|
|
33
|
+
* - ?parentId=xxx - List subfolders of a specific parent
|
|
34
|
+
*
|
|
35
|
+
* Response: `{ "folders": Folder[] }` (non-paginated; respondData with a
|
|
36
|
+
* named field).
|
|
37
|
+
*/
|
|
38
|
+
declare const GET: (request: NextRequest) => Promise<Response>;
|
|
39
|
+
/**
|
|
40
|
+
* POST /api/media/folders
|
|
41
|
+
*
|
|
42
|
+
* Create a new folder
|
|
43
|
+
*
|
|
44
|
+
* Request Body:
|
|
45
|
+
* - name: string (required)
|
|
46
|
+
* - description?: string
|
|
47
|
+
* - color?: string
|
|
48
|
+
* - icon?: string
|
|
49
|
+
* - parentId?: string | null
|
|
50
|
+
* - createdBy: string (required)
|
|
51
|
+
*
|
|
52
|
+
* Response: `{ "message", "item": Folder }` (status 201).
|
|
53
|
+
*/
|
|
54
|
+
declare const POST: (request: NextRequest) => Promise<Response>;
|
|
55
|
+
/**
|
|
56
|
+
* GET /api/media/folders/[id]
|
|
57
|
+
*
|
|
58
|
+
* Get folder by ID
|
|
59
|
+
*/
|
|
60
|
+
declare function getFolderById(request: NextRequest, routeContext: {
|
|
61
|
+
params: Promise<{
|
|
62
|
+
id: string;
|
|
63
|
+
}>;
|
|
64
|
+
}): Promise<Response>;
|
|
65
|
+
/**
|
|
66
|
+
* PATCH /api/media/folders/[id]
|
|
67
|
+
*
|
|
68
|
+
* Update folder metadata
|
|
69
|
+
*
|
|
70
|
+
* Request Body:
|
|
71
|
+
* - name?: string
|
|
72
|
+
* - description?: string
|
|
73
|
+
* - color?: string
|
|
74
|
+
* - icon?: string
|
|
75
|
+
* - parentId?: string | null
|
|
76
|
+
*/
|
|
77
|
+
declare function updateFolder(request: NextRequest, routeContext: {
|
|
78
|
+
params: Promise<{
|
|
79
|
+
id: string;
|
|
80
|
+
}>;
|
|
81
|
+
}): Promise<Response>;
|
|
82
|
+
/**
|
|
83
|
+
* DELETE /api/media/folders/[id]
|
|
84
|
+
*
|
|
85
|
+
* Delete folder
|
|
86
|
+
* Query params: ?deleteContents=true/false
|
|
87
|
+
*
|
|
88
|
+
* Response: `{ "message", "id" }` (respondAction; service returns void).
|
|
89
|
+
*/
|
|
90
|
+
declare function deleteFolder(request: NextRequest, routeContext: {
|
|
91
|
+
params: Promise<{
|
|
92
|
+
id: string;
|
|
93
|
+
}>;
|
|
94
|
+
}): Promise<Response>;
|
|
95
|
+
/**
|
|
96
|
+
* GET /api/media/folders/[id]/contents
|
|
97
|
+
*
|
|
98
|
+
* Get folder contents (subfolders + media files)
|
|
99
|
+
*/
|
|
100
|
+
declare function getFolderContents(request: NextRequest, routeContext: {
|
|
101
|
+
params: Promise<{
|
|
102
|
+
id: string;
|
|
103
|
+
}>;
|
|
104
|
+
}): Promise<Response>;
|
|
105
|
+
/**
|
|
106
|
+
* GET /api/media/folders/root/contents
|
|
107
|
+
*
|
|
108
|
+
* Get root folder contents (folders + media without a folder)
|
|
109
|
+
*/
|
|
110
|
+
declare const getRootFolderContents: (_request: NextRequest) => Promise<Response>;
|
|
111
|
+
|
|
112
|
+
export { GET, POST, deleteFolder, getFolderById, getFolderContents, getRootFolderContents, updateFolder };
|