gazetta 0.6.0 → 0.7.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/admin-dist/assets/index-BO9-CXmW.css +1 -0
- package/admin-dist/assets/index-Ufu8zZH_.js +668 -0
- package/admin-dist/index.html +2 -2
- package/dist/admin-api/error-response.d.ts +21 -0
- package/dist/admin-api/error-response.d.ts.map +1 -0
- package/dist/admin-api/error-response.js +12 -0
- package/dist/admin-api/error-response.js.map +1 -0
- package/dist/admin-api/index.d.ts +0 -2
- package/dist/admin-api/index.d.ts.map +1 -1
- package/dist/admin-api/index.js +4 -24
- package/dist/admin-api/index.js.map +1 -1
- package/dist/admin-api/routes/assets.d.ts +16 -0
- package/dist/admin-api/routes/assets.d.ts.map +1 -0
- package/dist/admin-api/routes/assets.js +433 -0
- package/dist/admin-api/routes/assets.js.map +1 -0
- package/dist/admin-api/routes/fragments.d.ts.map +1 -1
- package/dist/admin-api/routes/fragments.js +30 -4
- package/dist/admin-api/routes/fragments.js.map +1 -1
- package/dist/admin-api/routes/pages.d.ts.map +1 -1
- package/dist/admin-api/routes/pages.js +37 -4
- package/dist/admin-api/routes/pages.js.map +1 -1
- package/dist/admin-api/routes/publish.d.ts.map +1 -1
- package/dist/admin-api/routes/publish.js +68 -35
- package/dist/admin-api/routes/publish.js.map +1 -1
- package/dist/admin-api/schemas/assets.d.ts +48 -0
- package/dist/admin-api/schemas/assets.d.ts.map +1 -0
- package/dist/admin-api/schemas/assets.js +44 -0
- package/dist/admin-api/schemas/assets.js.map +1 -0
- package/dist/admin-api/schemas/index.d.ts +2 -0
- package/dist/admin-api/schemas/index.d.ts.map +1 -1
- package/dist/admin-api/schemas/index.js +2 -0
- package/dist/admin-api/schemas/index.js.map +1 -1
- package/dist/admin-api/source-context.d.ts +0 -7
- package/dist/admin-api/source-context.d.ts.map +1 -1
- package/dist/admin-api/source-context.js +0 -3
- package/dist/admin-api/source-context.js.map +1 -1
- package/dist/assets/analyze-audio.d.ts +3 -0
- package/dist/assets/analyze-audio.d.ts.map +1 -0
- package/dist/assets/analyze-audio.js +80 -0
- package/dist/assets/analyze-audio.js.map +1 -0
- package/dist/assets/analyze-image.d.ts +19 -0
- package/dist/assets/analyze-image.d.ts.map +1 -0
- package/dist/assets/analyze-image.js +123 -0
- package/dist/assets/analyze-image.js.map +1 -0
- package/dist/assets/analyze.d.ts +94 -0
- package/dist/assets/analyze.d.ts.map +1 -0
- package/dist/assets/analyze.js +45 -0
- package/dist/assets/analyze.js.map +1 -0
- package/dist/assets/asset-deps.d.ts +30 -0
- package/dist/assets/asset-deps.d.ts.map +1 -0
- package/dist/assets/asset-deps.js +42 -0
- package/dist/assets/asset-deps.js.map +1 -0
- package/dist/assets/asset-paths.d.ts +155 -0
- package/dist/assets/asset-paths.d.ts.map +1 -0
- package/dist/assets/asset-paths.js +197 -0
- package/dist/assets/asset-paths.js.map +1 -0
- package/dist/assets/delete.d.ts +75 -0
- package/dist/assets/delete.d.ts.map +1 -0
- package/dist/assets/delete.js +82 -0
- package/dist/assets/delete.js.map +1 -0
- package/dist/assets/errors.d.ts +241 -0
- package/dist/assets/errors.d.ts.map +1 -0
- package/dist/assets/errors.js +300 -0
- package/dist/assets/errors.js.map +1 -0
- package/dist/assets/find-refs.d.ts +37 -0
- package/dist/assets/find-refs.d.ts.map +1 -0
- package/dist/assets/find-refs.js +35 -0
- package/dist/assets/find-refs.js.map +1 -0
- package/dist/assets/hash.d.ts +13 -0
- package/dist/assets/hash.d.ts.map +1 -0
- package/dist/assets/hash.js +43 -0
- package/dist/assets/hash.js.map +1 -0
- package/dist/assets/image-metadata.d.ts +11 -0
- package/dist/assets/image-metadata.d.ts.map +1 -0
- package/dist/assets/image-metadata.js +31 -0
- package/dist/assets/image-metadata.js.map +1 -0
- package/dist/assets/ingest-locale.d.ts +86 -0
- package/dist/assets/ingest-locale.d.ts.map +1 -0
- package/dist/assets/ingest-locale.js +209 -0
- package/dist/assets/ingest-locale.js.map +1 -0
- package/dist/assets/ingest.d.ts +96 -0
- package/dist/assets/ingest.d.ts.map +1 -0
- package/dist/assets/ingest.js +308 -0
- package/dist/assets/ingest.js.map +1 -0
- package/dist/assets/kind-compat.d.ts +34 -0
- package/dist/assets/kind-compat.d.ts.map +1 -0
- package/dist/assets/kind-compat.js +33 -0
- package/dist/assets/kind-compat.js.map +1 -0
- package/dist/assets/list.d.ts +46 -0
- package/dist/assets/list.d.ts.map +1 -0
- package/dist/assets/list.js +102 -0
- package/dist/assets/list.js.map +1 -0
- package/dist/assets/manifest-default.d.ts +56 -0
- package/dist/assets/manifest-default.d.ts.map +1 -0
- package/dist/assets/manifest-default.js +120 -0
- package/dist/assets/manifest-default.js.map +1 -0
- package/dist/assets/manifest-filename.d.ts +52 -0
- package/dist/assets/manifest-filename.d.ts.map +1 -0
- package/dist/assets/manifest-filename.js +104 -0
- package/dist/assets/manifest-filename.js.map +1 -0
- package/dist/assets/manifest-locale.d.ts +60 -0
- package/dist/assets/manifest-locale.d.ts.map +1 -0
- package/dist/assets/manifest-locale.js +206 -0
- package/dist/assets/manifest-locale.js.map +1 -0
- package/dist/assets/manifest-merge.d.ts +66 -0
- package/dist/assets/manifest-merge.d.ts.map +1 -0
- package/dist/assets/manifest-merge.js +82 -0
- package/dist/assets/manifest-merge.js.map +1 -0
- package/dist/assets/manifest.d.ts +83 -0
- package/dist/assets/manifest.d.ts.map +1 -0
- package/dist/assets/manifest.js +93 -0
- package/dist/assets/manifest.js.map +1 -0
- package/dist/assets/mime-sniff.d.ts +18 -0
- package/dist/assets/mime-sniff.d.ts.map +1 -0
- package/dist/assets/mime-sniff.js +84 -0
- package/dist/assets/mime-sniff.js.map +1 -0
- package/dist/assets/preprocess-svg.d.ts +3 -0
- package/dist/assets/preprocess-svg.d.ts.map +1 -0
- package/dist/assets/preprocess-svg.js +49 -0
- package/dist/assets/preprocess-svg.js.map +1 -0
- package/dist/assets/preprocess.d.ts +62 -0
- package/dist/assets/preprocess.d.ts.map +1 -0
- package/dist/assets/preprocess.js +86 -0
- package/dist/assets/preprocess.js.map +1 -0
- package/dist/assets/publish-plan.d.ts +41 -0
- package/dist/assets/publish-plan.d.ts.map +1 -0
- package/dist/assets/publish-plan.js +49 -0
- package/dist/assets/publish-plan.js.map +1 -0
- package/dist/assets/publish.d.ts +33 -0
- package/dist/assets/publish.d.ts.map +1 -0
- package/dist/assets/publish.js +81 -0
- package/dist/assets/publish.js.map +1 -0
- package/dist/assets/refs.d.ts +37 -0
- package/dist/assets/refs.d.ts.map +1 -0
- package/dist/assets/refs.js +33 -0
- package/dist/assets/refs.js.map +1 -0
- package/dist/assets/remove-override.d.ts +42 -0
- package/dist/assets/remove-override.d.ts.map +1 -0
- package/dist/assets/remove-override.js +53 -0
- package/dist/assets/remove-override.js.map +1 -0
- package/dist/assets/rename.d.ts +43 -0
- package/dist/assets/rename.d.ts.map +1 -0
- package/dist/assets/rename.js +271 -0
- package/dist/assets/rename.js.map +1 -0
- package/dist/assets/replace.d.ts +37 -0
- package/dist/assets/replace.d.ts.map +1 -0
- package/dist/assets/replace.js +195 -0
- package/dist/assets/replace.js.map +1 -0
- package/dist/assets/resolve.d.ts +141 -0
- package/dist/assets/resolve.d.ts.map +1 -0
- package/dist/assets/resolve.js +381 -0
- package/dist/assets/resolve.js.map +1 -0
- package/dist/assets/rewrite-manifest-asset-ref.d.ts +44 -0
- package/dist/assets/rewrite-manifest-asset-ref.d.ts.map +1 -0
- package/dist/assets/rewrite-manifest-asset-ref.js +51 -0
- package/dist/assets/rewrite-manifest-asset-ref.js.map +1 -0
- package/dist/assets/scan-manifest-for-asset.d.ts +63 -0
- package/dist/assets/scan-manifest-for-asset.d.ts.map +1 -0
- package/dist/assets/scan-manifest-for-asset.js +105 -0
- package/dist/assets/scan-manifest-for-asset.js.map +1 -0
- package/dist/assets/serve-route.d.ts +45 -0
- package/dist/assets/serve-route.d.ts.map +1 -0
- package/dist/assets/serve-route.js +123 -0
- package/dist/assets/serve-route.js.map +1 -0
- package/dist/assets/svg-sanitize.d.ts +38 -0
- package/dist/assets/svg-sanitize.d.ts.map +1 -0
- package/dist/assets/svg-sanitize.js +209 -0
- package/dist/assets/svg-sanitize.js.map +1 -0
- package/dist/assets/update-metadata.d.ts +61 -0
- package/dist/assets/update-metadata.d.ts.map +1 -0
- package/dist/assets/update-metadata.js +82 -0
- package/dist/assets/update-metadata.js.map +1 -0
- package/dist/assets/url.d.ts +82 -0
- package/dist/assets/url.d.ts.map +1 -0
- package/dist/assets/url.js +103 -0
- package/dist/assets/url.js.map +1 -0
- package/dist/assets/validate.d.ts +74 -0
- package/dist/assets/validate.d.ts.map +1 -0
- package/dist/assets/validate.js +136 -0
- package/dist/assets/validate.js.map +1 -0
- package/dist/assets/variants.d.ts +23 -0
- package/dist/assets/variants.d.ts.map +1 -0
- package/dist/assets/variants.js +74 -0
- package/dist/assets/variants.js.map +1 -0
- package/dist/cli/assets-cli.d.ts +58 -0
- package/dist/cli/assets-cli.d.ts.map +1 -0
- package/dist/cli/assets-cli.js +233 -0
- package/dist/cli/assets-cli.js.map +1 -0
- package/dist/cli/assets-display.d.ts +112 -0
- package/dist/cli/assets-display.d.ts.map +1 -0
- package/dist/cli/assets-display.js +106 -0
- package/dist/cli/assets-display.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +0 -2
- package/dist/cli/bootstrap.d.ts.map +1 -1
- package/dist/cli/bootstrap.js +0 -1
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/index.js +64 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/compare.d.ts.map +1 -1
- package/dist/compare.js +15 -12
- package/dist/compare.js.map +1 -1
- package/dist/dep-sidecars.d.ts +127 -0
- package/dist/dep-sidecars.d.ts.map +1 -0
- package/dist/dep-sidecars.js +122 -0
- package/dist/dep-sidecars.js.map +1 -0
- package/dist/editor/AssetEmbeddedWidget.d.ts +3 -0
- package/dist/editor/AssetEmbeddedWidget.d.ts.map +1 -0
- package/dist/editor/AssetEmbeddedWidget.js +146 -0
- package/dist/editor/AssetEmbeddedWidget.js.map +1 -0
- package/dist/editor/mount.d.ts +12 -1
- package/dist/editor/mount.d.ts.map +1 -1
- package/dist/editor/mount.js +36 -5
- package/dist/editor/mount.js.map +1 -1
- package/dist/format.d.ts +44 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +65 -0
- package/dist/format.js.map +1 -0
- package/dist/fragment-deps.d.ts +24 -0
- package/dist/fragment-deps.d.ts.map +1 -0
- package/dist/fragment-deps.js +20 -0
- package/dist/fragment-deps.js.map +1 -0
- package/dist/hash.d.ts +0 -6
- package/dist/hash.d.ts.map +1 -1
- package/dist/hash.js +0 -18
- package/dist/hash.js.map +1 -1
- package/dist/history-provider.d.ts.map +1 -1
- package/dist/history-provider.js +30 -8
- package/dist/history-provider.js.map +1 -1
- package/dist/history-recorder.d.ts +7 -3
- package/dist/history-recorder.d.ts.map +1 -1
- package/dist/history-recorder.js +9 -1
- package/dist/history-recorder.js.map +1 -1
- package/dist/history-restorer.d.ts.map +1 -1
- package/dist/history-restorer.js +34 -2
- package/dist/history-restorer.js.map +1 -1
- package/dist/history.d.ts +26 -8
- package/dist/history.d.ts.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/locale.d.ts +20 -0
- package/dist/locale.d.ts.map +1 -1
- package/dist/locale.js +38 -0
- package/dist/locale.js.map +1 -1
- package/dist/providers/_atomic-write.d.ts +9 -0
- package/dist/providers/_atomic-write.d.ts.map +1 -0
- package/dist/providers/_atomic-write.js +72 -0
- package/dist/providers/_atomic-write.js.map +1 -0
- package/dist/providers/_rm-ignore-missing.d.ts +31 -0
- package/dist/providers/_rm-ignore-missing.d.ts.map +1 -0
- package/dist/providers/_rm-ignore-missing.js +12 -0
- package/dist/providers/_rm-ignore-missing.js.map +1 -0
- package/dist/providers/_stream-interop.d.ts +23 -0
- package/dist/providers/_stream-interop.d.ts.map +1 -0
- package/dist/providers/_stream-interop.js +21 -0
- package/dist/providers/_stream-interop.js.map +1 -0
- package/dist/providers/azure-blob.d.ts.map +1 -1
- package/dist/providers/azure-blob.js +60 -0
- package/dist/providers/azure-blob.js.map +1 -1
- package/dist/providers/filesystem.d.ts +4 -0
- package/dist/providers/filesystem.d.ts.map +1 -1
- package/dist/providers/filesystem.js +63 -2
- package/dist/providers/filesystem.js.map +1 -1
- package/dist/providers/s3.d.ts.map +1 -1
- package/dist/providers/s3.js +84 -1
- package/dist/providers/s3.js.map +1 -1
- package/dist/publish-rendered.d.ts +37 -17
- package/dist/publish-rendered.d.ts.map +1 -1
- package/dist/publish-rendered.js +71 -67
- package/dist/publish-rendered.js.map +1 -1
- package/dist/publish.d.ts +13 -12
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +23 -47
- package/dist/publish.js.map +1 -1
- package/dist/resolver.d.ts +12 -2
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +54 -9
- package/dist/resolver.js.map +1 -1
- package/dist/schema/dimensions.d.ts +78 -0
- package/dist/schema/dimensions.d.ts.map +1 -0
- package/dist/schema/dimensions.js +97 -0
- package/dist/schema/dimensions.js.map +1 -0
- package/dist/schema/helpers.d.ts +108 -0
- package/dist/schema/helpers.d.ts.map +1 -0
- package/dist/schema/helpers.js +133 -0
- package/dist/schema/helpers.js.map +1 -0
- package/dist/schema/index.d.ts +27 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +25 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/types.d.ts +390 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +25 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/selector-chain.d.ts +63 -0
- package/dist/selector-chain.d.ts.map +1 -0
- package/dist/selector-chain.js +58 -0
- package/dist/selector-chain.js.map +1 -0
- package/dist/sidecars.d.ts +19 -18
- package/dist/sidecars.d.ts.map +1 -1
- package/dist/sidecars.js +70 -62
- package/dist/sidecars.js.map +1 -1
- package/dist/targets.d.ts.map +1 -1
- package/dist/targets.js +15 -37
- package/dist/targets.js.map +1 -1
- package/dist/themes.d.ts +69 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +85 -0
- package/dist/themes.js.map +1 -0
- package/dist/transforms/adapter.d.ts +115 -0
- package/dist/transforms/adapter.d.ts.map +1 -0
- package/dist/transforms/adapter.js +2 -0
- package/dist/transforms/adapter.js.map +1 -0
- package/dist/transforms/cloudflare.d.ts +17 -0
- package/dist/transforms/cloudflare.d.ts.map +1 -0
- package/dist/transforms/cloudflare.js +110 -0
- package/dist/transforms/cloudflare.js.map +1 -0
- package/dist/transforms/index.d.ts +24 -0
- package/dist/transforms/index.d.ts.map +1 -0
- package/dist/transforms/index.js +30 -0
- package/dist/transforms/index.js.map +1 -0
- package/dist/transforms/sharp.d.ts +3 -0
- package/dist/transforms/sharp.d.ts.map +1 -0
- package/dist/transforms/sharp.js +43 -0
- package/dist/transforms/sharp.js.map +1 -0
- package/dist/types.d.ts +125 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +20 -1
- package/admin-dist/assets/index-B6pVot0Y.css +0 -1
- package/admin-dist/assets/index-DniLwxJA.js +0 -609
- package/dist/providers/r2.d.ts +0 -8
- package/dist/providers/r2.d.ts.map +0 -1
- package/dist/providers/r2.js +0 -86
- package/dist/providers/r2.js.map +0 -1
- package/dist/source-sidecars.d.ts +0 -32
- package/dist/source-sidecars.d.ts.map +0 -1
- package/dist/source-sidecars.js +0 -98
- package/dist/source-sidecars.js.map +0 -1
package/admin-dist/index.html
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
<title>Gazetta CMS</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%238b5cf6'/%3E%3Crect x='7' y='7' width='8' height='8' rx='2' fill='white'/%3E%3Crect x='17' y='7' width='8' height='8' rx='2' fill='white' opacity='.6'/%3E%3Crect x='7' y='17' width='8' height='8' rx='2' fill='white' opacity='.6'/%3E%3Crect x='17' y='17' width='8' height='8' rx='2' fill='white' opacity='.3'/%3E%3C/svg%3E">
|
|
8
8
|
<link rel="stylesheet" href="https://unpkg.com/primeicons/primeicons.css">
|
|
9
|
-
<script type="module" crossorigin src="/admin/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/admin/assets/index-Ufu8zZH_.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/admin/assets/rolldown-runtime-COnpUsM8.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/admin/assets/vendor-react-BipDVGow.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/admin/assets/vendor-tiptap-IyO99U4R.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="/admin/assets/vendor-primevue-C0Q_YTCb.js">
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/admin/assets/vendor-rjsf-HKBAjOmQ.js">
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/admin/assets/vendor-vue-D3wBSmDf.js">
|
|
16
|
-
<link rel="stylesheet" crossorigin href="/admin/assets/index-
|
|
16
|
+
<link rel="stylesheet" crossorigin href="/admin/assets/index-BO9-CXmW.css">
|
|
17
17
|
</head>
|
|
18
18
|
<body>
|
|
19
19
|
<div id="app"></div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset-error → HTTP response mapper.
|
|
3
|
+
*
|
|
4
|
+
* Every `AssetError` subclass owns two pieces of transport-boundary data:
|
|
5
|
+
* - `httpStatus` (the status code)
|
|
6
|
+
* - `toResponseBody()` (the JSON body — default `{ code, message }`,
|
|
7
|
+
* overridden by subclasses that carry structured data)
|
|
8
|
+
*
|
|
9
|
+
* The mapper is one line: delegate to the polymorphic method. No
|
|
10
|
+
* `instanceof` chains, no special-casing by subclass. Adding a new
|
|
11
|
+
* `AssetError` subclass with a new body shape means overriding
|
|
12
|
+
* `toResponseBody()` on that subclass — the mapper stays unchanged.
|
|
13
|
+
*/
|
|
14
|
+
import type { Context } from 'hono';
|
|
15
|
+
/**
|
|
16
|
+
* Serialize an `AssetError` into a Hono JSON response. Returns `null`
|
|
17
|
+
* when the error is not an `AssetError` — the caller should rethrow so
|
|
18
|
+
* the framework's default handler can produce a 500.
|
|
19
|
+
*/
|
|
20
|
+
export declare function respondWithAssetError(c: Context, err: unknown): Response | null;
|
|
21
|
+
//# sourceMappingURL=error-response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-response.d.ts","sourceRoot":"","sources":["../../src/admin-api/error-response.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGnC;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAG/E"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AssetError } from '../assets/errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Serialize an `AssetError` into a Hono JSON response. Returns `null`
|
|
4
|
+
* when the error is not an `AssetError` — the caller should rethrow so
|
|
5
|
+
* the framework's default handler can produce a 500.
|
|
6
|
+
*/
|
|
7
|
+
export function respondWithAssetError(c, err) {
|
|
8
|
+
if (!(err instanceof AssetError))
|
|
9
|
+
return null;
|
|
10
|
+
return c.json(err.toResponseBody(), err.httpStatus);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=error-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-response.js","sourceRoot":"","sources":["../../src/admin-api/error-response.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,CAAU,EAAE,GAAY;IAC5D,IAAI,CAAC,CAAC,GAAG,YAAY,UAAU,CAAC;QAAE,OAAO,IAAI,CAAA;IAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;AACrD,CAAC"}
|
|
@@ -24,8 +24,6 @@ export interface AdminAppOptions {
|
|
|
24
24
|
}
|
|
25
25
|
type AdminApp = Hono & {
|
|
26
26
|
invalidateTemplatesCache(): void;
|
|
27
|
-
invalidateSourceSidecars(): void;
|
|
28
|
-
writeSourceSidecar(kind: 'page' | 'fragment', name: string): Promise<void>;
|
|
29
27
|
};
|
|
30
28
|
/**
|
|
31
29
|
* Create an admin API Hono app. Accepts a single options object.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin-api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin-api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAMhE,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAA;AAa5B,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,wFAAwF;IACxF,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IACtC,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CAC7C;AAED,KAAK,QAAQ,GAAG,IAAI,GAAG;IACrB,wBAAwB,IAAI,IAAI,CAAA;CACjC,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,QAAQ,CA4G9D"}
|
package/dist/admin-api/index.js
CHANGED
|
@@ -3,8 +3,6 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { logger } from 'hono/logger';
|
|
4
4
|
import { scanTemplates } from '../templates-scan.js';
|
|
5
5
|
import { memoizeAsync } from '../concurrency.js';
|
|
6
|
-
import { createSourceSidecarWriter } from '../source-sidecars.js';
|
|
7
|
-
import { createContentRoot } from '../content-root.js';
|
|
8
6
|
import { createTargetRegistryView } from '../targets.js';
|
|
9
7
|
import { createHistoryProvider } from '../history-provider.js';
|
|
10
8
|
import { isHistoryEnabled, getHistoryRetention } from '../types.js';
|
|
@@ -19,6 +17,7 @@ import { publishRoutes } from './routes/publish.js';
|
|
|
19
17
|
import { compareRoutes } from './routes/compare.js';
|
|
20
18
|
import { fieldRoutes } from './routes/fields.js';
|
|
21
19
|
import { historyRoutes } from './routes/history.js';
|
|
20
|
+
import { assetRoutes } from './routes/assets.js';
|
|
22
21
|
/**
|
|
23
22
|
* Create an admin API Hono app. Accepts a single options object.
|
|
24
23
|
*
|
|
@@ -47,41 +46,24 @@ export function createAdminApp(opts) {
|
|
|
47
46
|
// Prefer an externally-provided SourceContext. Fall back to constructing
|
|
48
47
|
// one from opts.storage + opts.siteDir, which is the legacy shape.
|
|
49
48
|
let source;
|
|
50
|
-
let sidecarWriter;
|
|
51
49
|
if (opts.source) {
|
|
52
50
|
source = opts.source;
|
|
53
|
-
sidecarWriter =
|
|
54
|
-
opts.source.sidecarWriter ??
|
|
55
|
-
createSourceSidecarWriter({
|
|
56
|
-
contentRoot: opts.source.contentRoot,
|
|
57
|
-
scanTemplates: () => cachedScan.get(),
|
|
58
|
-
templatesDir,
|
|
59
|
-
manifest: opts.source.manifest,
|
|
60
|
-
});
|
|
61
51
|
// Backfill history on the source if the caller didn't supply one —
|
|
62
52
|
// dev bootstrap builds a bare SourceContext and relies on admin-api
|
|
63
53
|
// to wire history per the target's config. Skip when the target's
|
|
64
54
|
// site.yaml has `history.enabled: false`, or when there's no
|
|
65
55
|
// matching targetConfig (legacy single-storage path).
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
source = { ...opts.source, sidecarWriter, history: sourceHistory };
|
|
56
|
+
if (!opts.source.history) {
|
|
57
|
+
source = { ...opts.source, history: buildHistoryForSource(opts, opts.source) };
|
|
69
58
|
}
|
|
70
59
|
}
|
|
71
60
|
else {
|
|
72
61
|
if (!opts.storage) {
|
|
73
62
|
throw new Error('createAdminApp: either `source` or `storage` must be provided');
|
|
74
63
|
}
|
|
75
|
-
const bootstrapRoot = createContentRoot(opts.storage, opts.siteDir);
|
|
76
|
-
sidecarWriter = createSourceSidecarWriter({
|
|
77
|
-
contentRoot: bootstrapRoot,
|
|
78
|
-
scanTemplates: () => cachedScan.get(),
|
|
79
|
-
templatesDir,
|
|
80
|
-
});
|
|
81
64
|
source = createSourceContext({
|
|
82
65
|
storage: opts.storage,
|
|
83
66
|
siteDir: opts.siteDir,
|
|
84
|
-
sidecarWriter,
|
|
85
67
|
history: buildHistoryForLegacySource(opts),
|
|
86
68
|
});
|
|
87
69
|
}
|
|
@@ -103,7 +85,6 @@ export function createAdminApp(opts) {
|
|
|
103
85
|
resolveSource = registrySourceResolver({
|
|
104
86
|
registry,
|
|
105
87
|
projectSiteDir: source.projectSiteDir,
|
|
106
|
-
sidecarWriter,
|
|
107
88
|
manifest: source.manifest,
|
|
108
89
|
// The registry's filesystem targets are already content-rooted
|
|
109
90
|
// (path=./targets/<key>); siteDir on the resolved context is empty.
|
|
@@ -142,13 +123,12 @@ export function createAdminApp(opts) {
|
|
|
142
123
|
app.route('/', compareRoutes(resolveSource, opts.targets, opts.targetConfigs, templatesDir, scan));
|
|
143
124
|
app.route('/', fieldRoutes(resolveSource, adminDir));
|
|
144
125
|
app.route('/', historyRoutes(resolveSource, opts.targets, opts.targetConfigs));
|
|
126
|
+
app.route('/', assetRoutes(resolveSource));
|
|
145
127
|
// Exposed for the CLI's template file watcher: clears the memoized scan
|
|
146
128
|
// so the next publish/compare picks up template edits. Not part of the
|
|
147
129
|
// Hono Request interface — the CLI casts the return.
|
|
148
130
|
const appWithInvalidate = app;
|
|
149
131
|
appWithInvalidate.invalidateTemplatesCache = () => cachedScan.invalidate();
|
|
150
|
-
appWithInvalidate.invalidateSourceSidecars = () => sidecarWriter.invalidate();
|
|
151
|
-
appWithInvalidate.writeSourceSidecar = (kind, name) => sidecarWriter.writeFor(kind, name);
|
|
152
132
|
return appWithInvalidate;
|
|
153
133
|
}
|
|
154
134
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin-api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin-api/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP routes for `/api/assets*`.
|
|
3
|
+
*
|
|
4
|
+
* Thin adapters. Each handler:
|
|
5
|
+
* 1. resolves the active target's source context,
|
|
6
|
+
* 2. delegates to the appropriate asset-domain operation,
|
|
7
|
+
* 3. maps success to the HTTP response,
|
|
8
|
+
* 4. delegates error-to-response translation to `respondWithAssetError`.
|
|
9
|
+
*
|
|
10
|
+
* No validation, storage, or orchestration logic in here — the asset
|
|
11
|
+
* domain owns all of that (see `src/assets/`).
|
|
12
|
+
*/
|
|
13
|
+
import { Hono } from 'hono';
|
|
14
|
+
import type { SourceContextResolver } from '../source-context.js';
|
|
15
|
+
export declare function assetRoutes(resolve: SourceContextResolver): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
16
|
+
//# sourceMappingURL=assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../src/admin-api/routes/assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAe3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAoCjE,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,8EA+WzD"}
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP routes for `/api/assets*`.
|
|
3
|
+
*
|
|
4
|
+
* Thin adapters. Each handler:
|
|
5
|
+
* 1. resolves the active target's source context,
|
|
6
|
+
* 2. delegates to the appropriate asset-domain operation,
|
|
7
|
+
* 3. maps success to the HTTP response,
|
|
8
|
+
* 4. delegates error-to-response translation to `respondWithAssetError`.
|
|
9
|
+
*
|
|
10
|
+
* No validation, storage, or orchestration logic in here — the asset
|
|
11
|
+
* domain owns all of that (see `src/assets/`).
|
|
12
|
+
*/
|
|
13
|
+
import { Hono } from 'hono';
|
|
14
|
+
import { enumerateOverrideSlices } from '../../assets/asset-paths.js';
|
|
15
|
+
import { deleteAsset } from '../../assets/delete.js';
|
|
16
|
+
import { ingestAsset } from '../../assets/ingest.js';
|
|
17
|
+
import { ingestLocaleBytes } from '../../assets/ingest-locale.js';
|
|
18
|
+
import { listAssets, toSummary } from '../../assets/list.js';
|
|
19
|
+
import { readManifest } from '../../assets/manifest.js';
|
|
20
|
+
import { removeOverride } from '../../assets/remove-override.js';
|
|
21
|
+
import { renameAsset } from '../../assets/rename.js';
|
|
22
|
+
import { replaceAsset } from '../../assets/replace.js';
|
|
23
|
+
import { updateAssetMetadata } from '../../assets/update-metadata.js';
|
|
24
|
+
import { buildSelector } from '../../schema/dimensions.js';
|
|
25
|
+
import { isValidLocale } from '../../locale.js';
|
|
26
|
+
import { isValidTheme } from '../../themes.js';
|
|
27
|
+
import { respondWithAssetError } from '../error-response.js';
|
|
28
|
+
/**
|
|
29
|
+
* Pull a Selector out of the request's query params, validating each
|
|
30
|
+
* dimension's value as it reads. Returns `null` when no dimension is
|
|
31
|
+
* set; throws a Response with a 400 body when any value is malformed.
|
|
32
|
+
*
|
|
33
|
+
* Per design, locale codes are BCP 47 (lowercase) and theme codes are
|
|
34
|
+
* lowercase ASCII non-locale tokens. Reuses the same validators used
|
|
35
|
+
* for filename parsing.
|
|
36
|
+
*/
|
|
37
|
+
function selectorFromQuery(c) {
|
|
38
|
+
const locale = c.req.query('locale');
|
|
39
|
+
const theme = c.req.query('theme');
|
|
40
|
+
if (locale === undefined && theme === undefined)
|
|
41
|
+
return null;
|
|
42
|
+
if (locale !== undefined && !isValidLocale(locale)) {
|
|
43
|
+
return new Response(JSON.stringify({ code: 'BAD_REQUEST', message: `Invalid locale code: ${locale}` }), {
|
|
44
|
+
status: 400,
|
|
45
|
+
headers: { 'content-type': 'application/json' },
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (theme !== undefined && !isValidTheme(theme)) {
|
|
49
|
+
return new Response(JSON.stringify({ code: 'BAD_REQUEST', message: `Invalid theme code: ${theme}` }), {
|
|
50
|
+
status: 400,
|
|
51
|
+
headers: { 'content-type': 'application/json' },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return buildSelector({
|
|
55
|
+
...(locale !== undefined ? { locale } : {}),
|
|
56
|
+
...(theme !== undefined ? { theme } : {}),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Where assets live, relative to the target storage root. */
|
|
60
|
+
const ASSETS_ROOT = 'assets';
|
|
61
|
+
export function assetRoutes(resolve) {
|
|
62
|
+
const app = new Hono();
|
|
63
|
+
app.get('/api/assets', async (c) => {
|
|
64
|
+
const source = await resolve(c.req.query('target'));
|
|
65
|
+
try {
|
|
66
|
+
const summaries = await listAssets({
|
|
67
|
+
storage: source.storage,
|
|
68
|
+
assetsRoot: ASSETS_ROOT,
|
|
69
|
+
});
|
|
70
|
+
return c.json(summaries);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const res = respondWithAssetError(c, err);
|
|
74
|
+
if (res)
|
|
75
|
+
return res;
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
app.get('/api/assets/:name', async (c) => {
|
|
80
|
+
const name = c.req.param('name');
|
|
81
|
+
const source = await resolve(c.req.query('target'));
|
|
82
|
+
try {
|
|
83
|
+
const manifest = await readManifest(source.storage, ASSETS_ROOT, name);
|
|
84
|
+
// Single-asset GET — discover overrides via the targeted scan.
|
|
85
|
+
// Cheaper than the full list scan (one readDir of the asset's
|
|
86
|
+
// parent dir) and gives the detail pane its locale chips without
|
|
87
|
+
// a second round-trip.
|
|
88
|
+
const slices = await enumerateOverrideSlices(source.storage, ASSETS_ROOT, manifest);
|
|
89
|
+
const locales = [];
|
|
90
|
+
const themes = [];
|
|
91
|
+
for (const slice of slices) {
|
|
92
|
+
const locale = slice.selector.get('locale');
|
|
93
|
+
const theme = slice.selector.get('theme');
|
|
94
|
+
if (locale !== undefined && !locales.includes(locale))
|
|
95
|
+
locales.push(locale);
|
|
96
|
+
if (theme !== undefined && !themes.includes(theme))
|
|
97
|
+
themes.push(theme);
|
|
98
|
+
}
|
|
99
|
+
return c.json(toSummary(manifest, locales, themes));
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const res = respondWithAssetError(c, err);
|
|
103
|
+
if (res)
|
|
104
|
+
return res;
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
/**
|
|
109
|
+
* PATCH /api/assets/:name — update asset metadata.
|
|
110
|
+
*
|
|
111
|
+
* Today's surface: alt only (per design-media.md three-state model).
|
|
112
|
+
* Future: tags, title, description, focalPoint at the asset level.
|
|
113
|
+
*
|
|
114
|
+
* Wire shape preserves three-state alt:
|
|
115
|
+
* `{}` — no change to alt
|
|
116
|
+
* `{"alt": "text"}` — meaningful description
|
|
117
|
+
* `{"alt": ""}` — decorative
|
|
118
|
+
* `{"alt": null}` — explicitly cleared (resolver falls back to '')
|
|
119
|
+
*
|
|
120
|
+
* Responses:
|
|
121
|
+
* 200 OK — { manifest } (updated summary)
|
|
122
|
+
* 400 Bad Request — alt isn't string|null
|
|
123
|
+
* 404 Not Found — asset missing
|
|
124
|
+
* 500 Storage — underlying write failed
|
|
125
|
+
*/
|
|
126
|
+
app.patch('/api/assets/:name', async (c) => {
|
|
127
|
+
const name = c.req.param('name');
|
|
128
|
+
const source = await resolve(c.req.query('target'));
|
|
129
|
+
let body;
|
|
130
|
+
try {
|
|
131
|
+
body = await c.req.json();
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return c.json({ code: 'BAD_REQUEST', message: 'Invalid JSON body' }, 400);
|
|
135
|
+
}
|
|
136
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
137
|
+
return c.json({ code: 'BAD_REQUEST', message: 'Body must be an object' }, 400);
|
|
138
|
+
}
|
|
139
|
+
const patch = {};
|
|
140
|
+
const raw = body;
|
|
141
|
+
if ('alt' in raw) {
|
|
142
|
+
const v = raw.alt;
|
|
143
|
+
if (v !== null && typeof v !== 'string') {
|
|
144
|
+
return c.json({ code: 'BAD_REQUEST', message: 'alt must be string or null' }, 400);
|
|
145
|
+
}
|
|
146
|
+
patch.alt = v;
|
|
147
|
+
}
|
|
148
|
+
if ('focalPoint' in raw) {
|
|
149
|
+
const v = raw.focalPoint;
|
|
150
|
+
if (v === null) {
|
|
151
|
+
patch.focalPoint = null;
|
|
152
|
+
}
|
|
153
|
+
else if (v !== null &&
|
|
154
|
+
typeof v === 'object' &&
|
|
155
|
+
typeof v.x === 'number' &&
|
|
156
|
+
typeof v.y === 'number') {
|
|
157
|
+
const fp = v;
|
|
158
|
+
if (fp.x < 0 || fp.x > 1 || fp.y < 0 || fp.y > 1) {
|
|
159
|
+
return c.json({ code: 'BAD_REQUEST', message: 'focalPoint x and y must be in [0, 1]' }, 400);
|
|
160
|
+
}
|
|
161
|
+
patch.focalPoint = fp;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
return c.json({ code: 'BAD_REQUEST', message: 'focalPoint must be { x: number, y: number } or null' }, 400);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
const updated = await updateAssetMetadata({
|
|
169
|
+
storage: source.storage,
|
|
170
|
+
assetsRoot: ASSETS_ROOT,
|
|
171
|
+
assetName: name,
|
|
172
|
+
patch,
|
|
173
|
+
history: source.history,
|
|
174
|
+
contentRoot: source.contentRoot,
|
|
175
|
+
});
|
|
176
|
+
// Re-summarize with override locales so the client refresh shape
|
|
177
|
+
// matches GET. Single-asset case uses the same enumerator.
|
|
178
|
+
const slices = await enumerateOverrideSlices(source.storage, ASSETS_ROOT, updated);
|
|
179
|
+
const locales = [];
|
|
180
|
+
const themes = [];
|
|
181
|
+
for (const slice of slices) {
|
|
182
|
+
const locale = slice.selector.get('locale');
|
|
183
|
+
const theme = slice.selector.get('theme');
|
|
184
|
+
if (locale !== undefined && !locales.includes(locale))
|
|
185
|
+
locales.push(locale);
|
|
186
|
+
if (theme !== undefined && !themes.includes(theme))
|
|
187
|
+
themes.push(theme);
|
|
188
|
+
}
|
|
189
|
+
return c.json({ manifest: toSummary(updated, locales, themes) });
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
const res = respondWithAssetError(c, err);
|
|
193
|
+
if (res)
|
|
194
|
+
return res;
|
|
195
|
+
throw err;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
app.delete('/api/assets/:name', async (c) => {
|
|
199
|
+
const name = c.req.param('name');
|
|
200
|
+
const source = await resolve(c.req.query('target'));
|
|
201
|
+
try {
|
|
202
|
+
await deleteAsset({
|
|
203
|
+
storage: source.storage,
|
|
204
|
+
assetsRoot: ASSETS_ROOT,
|
|
205
|
+
siteDir: source.siteDir,
|
|
206
|
+
assetName: name,
|
|
207
|
+
manifest: source.manifest,
|
|
208
|
+
history: source.history,
|
|
209
|
+
contentRoot: source.contentRoot,
|
|
210
|
+
});
|
|
211
|
+
// 204 No Content — standard REST for successful delete with no body.
|
|
212
|
+
return c.body(null, 204);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
const res = respondWithAssetError(c, err);
|
|
216
|
+
if (res)
|
|
217
|
+
return res;
|
|
218
|
+
throw err;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
/**
|
|
222
|
+
* POST /api/assets/:name/replace-with/:newName — atomic replace.
|
|
223
|
+
*
|
|
224
|
+
* Rewrites every reference to `:name` across pages + fragments to
|
|
225
|
+
* point at `:newName`, then deletes the old asset. One history
|
|
226
|
+
* revision covers the whole operation.
|
|
227
|
+
*
|
|
228
|
+
* Responses:
|
|
229
|
+
* 204 No Content — success
|
|
230
|
+
* 404 Not Found — either asset missing
|
|
231
|
+
* 409 Kind Mismatch — kinds/MIME-categories differ
|
|
232
|
+
* 500 Storage Failure — underlying write/rm failed mid-operation
|
|
233
|
+
*/
|
|
234
|
+
/**
|
|
235
|
+
* POST /api/assets/:name/rename-to/:newName — atomic rename.
|
|
236
|
+
*
|
|
237
|
+
* Copies bytes + variants + manifest to `:newName`, rewrites every
|
|
238
|
+
* reference across pages + fragments, and deletes the old asset.
|
|
239
|
+
* One history revision covers the whole operation. URLs to the old
|
|
240
|
+
* asset stay valid until refs are rewritten — safe-order per design.
|
|
241
|
+
*
|
|
242
|
+
* Responses:
|
|
243
|
+
* 204 No Content — success
|
|
244
|
+
* 404 Not Found — old asset missing
|
|
245
|
+
* 409 Name Collision — new name already taken
|
|
246
|
+
* 500 Storage Failure — underlying read/write/rm failed mid-operation
|
|
247
|
+
*/
|
|
248
|
+
app.post('/api/assets/:name/rename-to/:newName', async (c) => {
|
|
249
|
+
const oldName = c.req.param('name');
|
|
250
|
+
const newName = c.req.param('newName');
|
|
251
|
+
const source = await resolve(c.req.query('target'));
|
|
252
|
+
try {
|
|
253
|
+
await renameAsset({
|
|
254
|
+
storage: source.storage,
|
|
255
|
+
assetsRoot: ASSETS_ROOT,
|
|
256
|
+
siteDir: source.siteDir,
|
|
257
|
+
oldName,
|
|
258
|
+
newName,
|
|
259
|
+
manifest: source.manifest,
|
|
260
|
+
history: source.history,
|
|
261
|
+
contentRoot: source.contentRoot,
|
|
262
|
+
});
|
|
263
|
+
return c.body(null, 204);
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
const res = respondWithAssetError(c, err);
|
|
267
|
+
if (res)
|
|
268
|
+
return res;
|
|
269
|
+
throw err;
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
app.post('/api/assets/:name/replace-with/:newName', async (c) => {
|
|
273
|
+
const oldName = c.req.param('name');
|
|
274
|
+
const newName = c.req.param('newName');
|
|
275
|
+
const source = await resolve(c.req.query('target'));
|
|
276
|
+
try {
|
|
277
|
+
await replaceAsset({
|
|
278
|
+
storage: source.storage,
|
|
279
|
+
assetsRoot: ASSETS_ROOT,
|
|
280
|
+
siteDir: source.siteDir,
|
|
281
|
+
oldName,
|
|
282
|
+
newName,
|
|
283
|
+
manifest: source.manifest,
|
|
284
|
+
history: source.history,
|
|
285
|
+
});
|
|
286
|
+
return c.body(null, 204);
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
const res = respondWithAssetError(c, err);
|
|
290
|
+
if (res)
|
|
291
|
+
return res;
|
|
292
|
+
throw err;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
/**
|
|
296
|
+
* POST /api/assets/:name/locale-bytes — upload a locale (or theme,
|
|
297
|
+
* or compound) bytes override for an existing asset.
|
|
298
|
+
*
|
|
299
|
+
* Selector encoded as query: `?locale=fr` or `?locale=fr&theme=dark`.
|
|
300
|
+
* Both absent is a 400 — this route exists to write a non-default
|
|
301
|
+
* selector. Default-bytes upload uses POST /api/assets.
|
|
302
|
+
*
|
|
303
|
+
* Responses:
|
|
304
|
+
* 201 Created — { manifest, bytesPath }
|
|
305
|
+
* 400 Bad Request — invalid selector or empty selector
|
|
306
|
+
* 404 Not Found — asset doesn't exist
|
|
307
|
+
* 409 Kind Mismatch — override MIME category differs from default
|
|
308
|
+
* 500 Storage Failure — underlying write failed
|
|
309
|
+
*/
|
|
310
|
+
app.post('/api/assets/:name/locale-bytes', async (c) => {
|
|
311
|
+
const name = c.req.param('name');
|
|
312
|
+
const selectorOrErr = selectorFromQuery(c);
|
|
313
|
+
if (selectorOrErr instanceof Response)
|
|
314
|
+
return selectorOrErr;
|
|
315
|
+
if (selectorOrErr === null) {
|
|
316
|
+
return c.json({ code: 'BAD_REQUEST', message: 'Selector required (locale and/or theme)' }, 400);
|
|
317
|
+
}
|
|
318
|
+
const source = await resolve(c.req.query('target'));
|
|
319
|
+
const body = await c.req.parseBody();
|
|
320
|
+
const file = body.file;
|
|
321
|
+
if (!(file instanceof File)) {
|
|
322
|
+
return c.json({ code: 'BAD_REQUEST', message: 'Missing or invalid "file" field' }, 400);
|
|
323
|
+
}
|
|
324
|
+
const targetConfig = source.targetName ? source.manifest?.targets?.[source.targetName] : undefined;
|
|
325
|
+
const policy = targetConfig?.assets;
|
|
326
|
+
try {
|
|
327
|
+
const result = await ingestLocaleBytes({
|
|
328
|
+
storage: source.storage,
|
|
329
|
+
assetsRoot: ASSETS_ROOT,
|
|
330
|
+
assetName: name,
|
|
331
|
+
selector: selectorOrErr,
|
|
332
|
+
bytes: file.stream(),
|
|
333
|
+
policy,
|
|
334
|
+
history: source.history,
|
|
335
|
+
contentRoot: source.contentRoot,
|
|
336
|
+
});
|
|
337
|
+
return c.json({ manifest: result.manifest, bytesPath: result.bytesPath }, 201);
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
const res = respondWithAssetError(c, err);
|
|
341
|
+
if (res)
|
|
342
|
+
return res;
|
|
343
|
+
throw err;
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
/**
|
|
347
|
+
* DELETE /api/assets/:name/locale-bytes — remove one locale (or
|
|
348
|
+
* theme, or compound) bytes override. The default asset is unaffected;
|
|
349
|
+
* the locale falls back to default bytes after removal.
|
|
350
|
+
*
|
|
351
|
+
* Selector encoded as query (same shape as POST). Both absent is a
|
|
352
|
+
* 400 — to delete the default asset, use DELETE /api/assets/:name.
|
|
353
|
+
*
|
|
354
|
+
* Responses:
|
|
355
|
+
* 204 No Content — success
|
|
356
|
+
* 400 Bad Request — invalid or empty selector
|
|
357
|
+
* 404 Not Found — asset or override doesn't exist
|
|
358
|
+
* 500 Storage Failure — underlying rm failed
|
|
359
|
+
*/
|
|
360
|
+
app.delete('/api/assets/:name/locale-bytes', async (c) => {
|
|
361
|
+
const name = c.req.param('name');
|
|
362
|
+
const selectorOrErr = selectorFromQuery(c);
|
|
363
|
+
if (selectorOrErr instanceof Response)
|
|
364
|
+
return selectorOrErr;
|
|
365
|
+
if (selectorOrErr === null) {
|
|
366
|
+
return c.json({ code: 'BAD_REQUEST', message: 'Selector required (locale and/or theme)' }, 400);
|
|
367
|
+
}
|
|
368
|
+
const source = await resolve(c.req.query('target'));
|
|
369
|
+
try {
|
|
370
|
+
await removeOverride({
|
|
371
|
+
storage: source.storage,
|
|
372
|
+
assetsRoot: ASSETS_ROOT,
|
|
373
|
+
siteDir: source.siteDir,
|
|
374
|
+
assetName: name,
|
|
375
|
+
selector: selectorOrErr,
|
|
376
|
+
history: source.history,
|
|
377
|
+
contentRoot: source.contentRoot,
|
|
378
|
+
author: '',
|
|
379
|
+
});
|
|
380
|
+
return c.body(null, 204);
|
|
381
|
+
}
|
|
382
|
+
catch (err) {
|
|
383
|
+
const res = respondWithAssetError(c, err);
|
|
384
|
+
if (res)
|
|
385
|
+
return res;
|
|
386
|
+
throw err;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
app.post('/api/assets', async (c) => {
|
|
390
|
+
const source = await resolve(c.req.query('target'));
|
|
391
|
+
// Hono's parseBody reads multipart into a { [field]: string | File } map.
|
|
392
|
+
const body = await c.req.parseBody();
|
|
393
|
+
const file = body.file;
|
|
394
|
+
const name = body.name;
|
|
395
|
+
const altRaw = body.alt;
|
|
396
|
+
if (!(file instanceof File)) {
|
|
397
|
+
return c.json({ code: 'BAD_REQUEST', message: 'Missing or invalid "file" field' }, 400);
|
|
398
|
+
}
|
|
399
|
+
if (typeof name !== 'string' || name.length === 0) {
|
|
400
|
+
return c.json({ code: 'BAD_REQUEST', message: 'Missing or invalid "name" field' }, 400);
|
|
401
|
+
}
|
|
402
|
+
// alt: absent → null, empty string → "" (decorative), string → the value
|
|
403
|
+
const alt = typeof altRaw === 'string' ? altRaw : null;
|
|
404
|
+
// Pull per-target upload policy from site.yaml. When the source
|
|
405
|
+
// didn't resolve a named target (legacy static-resolver path) or
|
|
406
|
+
// the site manifest isn't wired, ingest falls back to the default
|
|
407
|
+
// size cap.
|
|
408
|
+
const targetConfig = source.targetName ? source.manifest?.targets?.[source.targetName] : undefined;
|
|
409
|
+
const policy = targetConfig?.assets;
|
|
410
|
+
try {
|
|
411
|
+
const result = await ingestAsset({
|
|
412
|
+
storage: source.storage,
|
|
413
|
+
assetsRoot: ASSETS_ROOT,
|
|
414
|
+
bytes: file.stream(),
|
|
415
|
+
requestedName: name,
|
|
416
|
+
alt,
|
|
417
|
+
uploadedBy: '',
|
|
418
|
+
policy,
|
|
419
|
+
history: source.history,
|
|
420
|
+
contentRoot: source.contentRoot,
|
|
421
|
+
});
|
|
422
|
+
return c.json({ manifest: result.manifest, bytesPath: result.bytesPath }, 201);
|
|
423
|
+
}
|
|
424
|
+
catch (err) {
|
|
425
|
+
const res = respondWithAssetError(c, err);
|
|
426
|
+
if (res)
|
|
427
|
+
return res;
|
|
428
|
+
throw err;
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
return app;
|
|
432
|
+
}
|
|
433
|
+
//# sourceMappingURL=assets.js.map
|