emdash 0.6.0 → 1.0.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/dist/{adapters-Di31kZ28.d.mts → adapters-BKSf3T9R.d.mts} +1 -1
- package/dist/{adapters-Di31kZ28.d.mts.map → adapters-BKSf3T9R.d.mts.map} +1 -1
- package/dist/{apply-B4MsLM-w.mjs → apply-x0eMK1lX.mjs} +186 -28
- package/dist/apply-x0eMK1lX.mjs.map +1 -0
- package/dist/astro/index.d.mts +6 -6
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +92 -17
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +5 -5
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +22 -2
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +2 -2
- package/dist/astro/middleware/request-context.mjs +7 -2
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +263 -74
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +25 -8
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{byline-C4OVd8b3.mjs → byline-Chbr2GoP.mjs} +3 -3
- package/dist/byline-Chbr2GoP.mjs.map +1 -0
- package/dist/{bylines-hPTW79hw.mjs → bylines-CRNsVG88.mjs} +4 -4
- package/dist/{bylines-hPTW79hw.mjs.map → bylines-CRNsVG88.mjs.map} +1 -1
- package/dist/cli/index.mjs +17 -13
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/{content-BsBoyj8G.mjs → content-BcQPYxdV.mjs} +39 -15
- package/dist/content-BcQPYxdV.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-D0UT85nC.mjs → db-errors-l1Qh2RPR.mjs} +1 -1
- package/dist/{db-errors-D0UT85nC.mjs.map → db-errors-l1Qh2RPR.mjs.map} +1 -1
- package/dist/{default-CME5YdZ3.mjs → default-DCVqE5ib.mjs} +1 -1
- package/dist/{default-CME5YdZ3.mjs.map → default-DCVqE5ib.mjs.map} +1 -1
- package/dist/{error-CiYn9yDu.mjs → error-zG5T1UGA.mjs} +1 -1
- package/dist/error-zG5T1UGA.mjs.map +1 -0
- package/dist/{index-BYv0mB9g.d.mts → index-DIb-CzNx.d.mts} +232 -15
- package/dist/index-DIb-CzNx.d.mts.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +23 -21
- package/dist/{load-CBcmDIot.mjs → load-CyEoextb.mjs} +1 -1
- package/dist/{load-CBcmDIot.mjs.map → load-CyEoextb.mjs.map} +1 -1
- package/dist/{loader-DeiBJEMe.mjs → loader-CndGj8kM.mjs} +8 -6
- package/dist/loader-CndGj8kM.mjs.map +1 -0
- package/dist/{manifest-schema-V30qsMft.mjs → manifest-schema-DH9xhc6t.mjs} +13 -1
- package/dist/manifest-schema-DH9xhc6t.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +7 -7
- package/dist/media/local-runtime.mjs +2 -2
- package/dist/{media-DqHVh136.mjs → media-D8FbNsl0.mjs} +4 -7
- package/dist/media-D8FbNsl0.mjs.map +1 -0
- package/dist/{mode-CpNnGkPz.mjs → mode-BnAOqItE.mjs} +1 -1
- package/dist/mode-BnAOqItE.mjs.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/placeholder-C-fk5hYI.mjs.map +1 -1
- package/dist/{placeholder-tzpqGWII.d.mts → placeholder-D29tWZ7o.d.mts} +1 -1
- package/dist/{placeholder-tzpqGWII.d.mts.map → placeholder-D29tWZ7o.d.mts.map} +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
- package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
- package/dist/{query-Bk_3vKvU.mjs → query-fqEdLFms.mjs} +9 -9
- package/dist/{query-Bk_3vKvU.mjs.map → query-fqEdLFms.mjs.map} +1 -1
- package/dist/{redirect-7lGhLBNZ.mjs → redirect-D_pshWdf.mjs} +69 -13
- package/dist/redirect-D_pshWdf.mjs.map +1 -0
- package/dist/{registry-Ci3WxVAr.mjs → registry-C3Mr0ODu.mjs} +33 -9
- package/dist/registry-C3Mr0ODu.mjs.map +1 -0
- package/dist/{request-cache-DiR961CV.mjs → request-cache-Ci7f5pBb.mjs} +1 -1
- package/dist/request-cache-Ci7f5pBb.mjs.map +1 -0
- package/dist/{runner-Fl2NcUUz.d.mts → runner-OURCaApa.d.mts} +2 -2
- package/dist/{runner-Fl2NcUUz.d.mts.map → runner-OURCaApa.d.mts.map} +1 -1
- package/dist/{runner-Cd-_WyDo.mjs → runner-tQ7BJ4T7.mjs} +211 -134
- package/dist/runner-tQ7BJ4T7.mjs.map +1 -0
- package/dist/runtime.d.mts +6 -6
- package/dist/runtime.mjs +2 -2
- package/dist/{search-DI4bM2w9.mjs → search-BoZYFuUk.mjs} +339 -102
- package/dist/search-BoZYFuUk.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +12 -12
- package/dist/seo/index.d.mts +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.d.mts.map +1 -1
- package/dist/storage/s3.mjs +4 -4
- package/dist/storage/s3.mjs.map +1 -1
- package/dist/{taxonomies-DbrKzDju.mjs → taxonomies-B4IAshV8.mjs} +5 -5
- package/dist/{taxonomies-DbrKzDju.mjs.map → taxonomies-B4IAshV8.mjs.map} +1 -1
- package/dist/{tokens-BFPFx3CA.mjs → tokens-D9vnZqYS.mjs} +1 -1
- package/dist/{tokens-BFPFx3CA.mjs.map → tokens-D9vnZqYS.mjs.map} +1 -1
- package/dist/{transport-BykRfpyy.mjs → transport-C9ugt2Nr.mjs} +1 -1
- package/dist/{transport-BykRfpyy.mjs.map → transport-C9ugt2Nr.mjs.map} +1 -1
- package/dist/{transport-H4Iwx7tC.d.mts → transport-CUnEL3Vs.d.mts} +1 -1
- package/dist/{transport-H4Iwx7tC.d.mts.map → transport-CUnEL3Vs.d.mts.map} +1 -1
- package/dist/types-BIgulNsW.mjs +68 -0
- package/dist/types-BIgulNsW.mjs.map +1 -0
- package/dist/{types-DDS4MxsT.mjs → types-Bm1dn-q3.mjs} +1 -1
- package/dist/{types-DDS4MxsT.mjs.map → types-Bm1dn-q3.mjs.map} +1 -1
- package/dist/{types-CnZYHyLW.d.mts → types-BmPPSUEx.d.mts} +1 -1
- package/dist/{types-CnZYHyLW.d.mts.map → types-BmPPSUEx.d.mts.map} +1 -1
- package/dist/{types-6CUZRrZP.d.mts → types-BrA0xf5I.d.mts} +24 -2
- package/dist/{types-6CUZRrZP.d.mts.map → types-BrA0xf5I.d.mts.map} +1 -1
- package/dist/{types-8xrvl_68.d.mts → types-CS8FIX7L.d.mts} +10 -1
- package/dist/{types-8xrvl_68.d.mts.map → types-CS8FIX7L.d.mts.map} +1 -1
- package/dist/{types-BH2L167P.mjs → types-CgqmmMJB.mjs} +1 -1
- package/dist/{types-BH2L167P.mjs.map → types-CgqmmMJB.mjs.map} +1 -1
- package/dist/{types-CFWjXmus.d.mts → types-DIMwPFub.d.mts} +1 -1
- package/dist/{types-CFWjXmus.d.mts.map → types-DIMwPFub.d.mts.map} +1 -1
- package/dist/{types-DgrIP0tF.d.mts → types-i36XcA_X.d.mts} +49 -6
- package/dist/types-i36XcA_X.d.mts.map +1 -0
- package/dist/{validate-CqsNItbt.mjs → validate-CxVsLehf.mjs} +2 -2
- package/dist/{validate-CqsNItbt.mjs.map → validate-CxVsLehf.mjs.map} +1 -1
- package/dist/{validate-CaLH1Ia2.d.mts → validate-DHxmpFJt.d.mts} +4 -4
- package/dist/{validate-CaLH1Ia2.d.mts.map → validate-DHxmpFJt.d.mts.map} +1 -1
- package/dist/validation-C-ZpN2GI.mjs +144 -0
- package/dist/validation-C-ZpN2GI.mjs.map +1 -0
- package/dist/version-DJrV1K0M.mjs +7 -0
- package/dist/{version-Uaf2ynPX.mjs.map → version-DJrV1K0M.mjs.map} +1 -1
- package/dist/zod-generator-CpwccCIv.mjs +132 -0
- package/dist/zod-generator-CpwccCIv.mjs.map +1 -0
- package/package.json +19 -6
- package/src/api/auth-storage.ts +37 -0
- package/src/api/error.ts +6 -0
- package/src/api/errors.ts +8 -0
- package/src/api/handlers/comments.ts +13 -0
- package/src/api/handlers/content.ts +124 -3
- package/src/api/handlers/index.ts +2 -0
- package/src/api/handlers/media.ts +8 -1
- package/src/api/handlers/menus.ts +160 -21
- package/src/api/handlers/redirects.ts +16 -3
- package/src/api/handlers/sections.ts +8 -1
- package/src/api/handlers/taxonomies.ts +128 -16
- package/src/api/handlers/validation.ts +212 -0
- package/src/api/openapi/document.ts +4 -1
- package/src/api/public-url.ts +6 -3
- package/src/api/route-utils.ts +14 -0
- package/src/api/schemas/common.ts +1 -1
- package/src/api/schemas/content.ts +8 -0
- package/src/api/schemas/setup.ts +8 -0
- package/src/api/schemas/widgets.ts +12 -10
- package/src/api/setup-complete.ts +40 -0
- package/src/astro/integration/font-provider.ts +3 -1
- package/src/astro/integration/index.ts +15 -2
- package/src/astro/integration/routes.ts +28 -0
- package/src/astro/integration/runtime.ts +74 -2
- package/src/astro/integration/virtual-modules.ts +41 -0
- package/src/astro/integration/vite-config.ts +43 -12
- package/src/astro/middleware/auth.ts +21 -0
- package/src/astro/middleware.ts +18 -1
- package/src/astro/routes/PluginRegistry.tsx +10 -1
- package/src/astro/routes/admin.astro +14 -7
- package/src/astro/routes/api/auth/magic-link/send.ts +2 -1
- package/src/astro/routes/api/auth/mode.ts +57 -0
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +23 -3
- package/src/astro/routes/api/auth/oauth/[provider].ts +10 -4
- package/src/astro/routes/api/auth/passkey/options.ts +2 -1
- package/src/astro/routes/api/auth/signup/request.ts +26 -8
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +10 -6
- package/src/astro/routes/api/content/[collection]/[id]/compare.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +26 -0
- package/src/astro/routes/api/content/[collection]/[id].ts +30 -2
- package/src/astro/routes/api/content/[collection]/index.ts +20 -10
- package/src/astro/routes/api/content/[collection]/trash.ts +1 -1
- package/src/astro/routes/api/import/wordpress/media.ts +2 -7
- package/src/astro/routes/api/import/wordpress/prepare.ts +10 -0
- package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +4 -3
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +4 -3
- package/src/astro/routes/api/manifest.ts +7 -0
- package/src/astro/routes/api/oauth/device/code.ts +2 -1
- package/src/astro/routes/api/oauth/device/token.ts +2 -1
- package/src/astro/routes/api/settings/email.ts +4 -9
- package/src/astro/routes/api/setup/admin-verify.ts +30 -5
- package/src/astro/routes/api/setup/admin.ts +38 -8
- package/src/astro/routes/api/setup/index.ts +7 -4
- package/src/astro/routes/api/setup/status.ts +3 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +4 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets.ts +4 -1
- package/src/astro/routes/api/widget-areas/[name].ts +4 -1
- package/src/astro/routes/api/widget-areas/index.ts +4 -1
- package/src/astro/types.ts +18 -0
- package/src/auth/mode.ts +15 -3
- package/src/auth/providers/github-admin.tsx +29 -0
- package/src/auth/providers/github.ts +31 -0
- package/src/auth/providers/google-admin.tsx +44 -0
- package/src/auth/providers/google.ts +31 -0
- package/src/auth/rate-limit.ts +50 -22
- package/src/auth/setup-nonce.ts +22 -0
- package/src/auth/trusted-proxy.ts +92 -0
- package/src/auth/types.ts +114 -4
- package/src/cli/commands/bundle.ts +3 -1
- package/src/components/EmDashImage.astro +7 -6
- package/src/components/Gallery.astro +5 -3
- package/src/components/Image.astro +8 -3
- package/src/components/InlinePortableTextEditor.tsx +2 -1
- package/src/components/LiveSearch.astro +5 -14
- package/src/database/migrations/035_bounded_404_log.ts +112 -0
- package/src/database/migrations/runner.ts +2 -0
- package/src/database/repositories/audit.ts +6 -8
- package/src/database/repositories/byline.ts +6 -8
- package/src/database/repositories/comment.ts +12 -16
- package/src/database/repositories/content.ts +79 -40
- package/src/database/repositories/index.ts +1 -1
- package/src/database/repositories/media.ts +10 -13
- package/src/database/repositories/options.ts +25 -0
- package/src/database/repositories/plugin-storage.ts +4 -6
- package/src/database/repositories/redirect.ts +123 -24
- package/src/database/repositories/taxonomy.ts +14 -3
- package/src/database/repositories/types.ts +57 -8
- package/src/database/repositories/user.ts +6 -8
- package/src/database/types.ts +9 -0
- package/src/emdash-runtime.ts +309 -91
- package/src/import/registry.ts +4 -3
- package/src/import/ssrf.ts +253 -12
- package/src/index.ts +5 -1
- package/src/loader.ts +6 -5
- package/src/mcp/server.ts +753 -107
- package/src/media/normalize.ts +1 -1
- package/src/media/url.ts +78 -0
- package/src/plugins/context.ts +15 -3
- package/src/plugins/email-console.ts +10 -3
- package/src/plugins/hooks.ts +11 -0
- package/src/plugins/manager.ts +6 -0
- package/src/plugins/manifest-schema.ts +12 -0
- package/src/plugins/request-meta.ts +66 -15
- package/src/plugins/routes.ts +3 -1
- package/src/plugins/types.ts +23 -2
- package/src/query.ts +1 -1
- package/src/request-cache.ts +3 -0
- package/src/schema/registry.ts +41 -5
- package/src/search/fts-manager.ts +0 -2
- package/src/search/query.ts +111 -26
- package/src/search/types.ts +8 -1
- package/src/sections/index.ts +7 -9
- package/src/seed/apply.ts +26 -0
- package/src/storage/s3.ts +12 -6
- package/src/virtual-modules.d.ts +21 -1
- package/src/visual-editing/toolbar.ts +6 -1
- package/src/widgets/index.ts +1 -1
- package/dist/apply-B4MsLM-w.mjs.map +0 -1
- package/dist/byline-C4OVd8b3.mjs.map +0 -1
- package/dist/content-BsBoyj8G.mjs.map +0 -1
- package/dist/error-CiYn9yDu.mjs.map +0 -1
- package/dist/index-BYv0mB9g.d.mts.map +0 -1
- package/dist/loader-DeiBJEMe.mjs.map +0 -1
- package/dist/manifest-schema-V30qsMft.mjs.map +0 -1
- package/dist/media-DqHVh136.mjs.map +0 -1
- package/dist/mode-CpNnGkPz.mjs.map +0 -1
- package/dist/redirect-7lGhLBNZ.mjs.map +0 -1
- package/dist/registry-Ci3WxVAr.mjs.map +0 -1
- package/dist/request-cache-DiR961CV.mjs.map +0 -1
- package/dist/runner-Cd-_WyDo.mjs.map +0 -1
- package/dist/search-DI4bM2w9.mjs.map +0 -1
- package/dist/types-CMMN0pNg.mjs +0 -31
- package/dist/types-CMMN0pNg.mjs.map +0 -1
- package/dist/types-DgrIP0tF.d.mts.map +0 -1
- package/dist/version-Uaf2ynPX.mjs +0 -7
package/dist/astro/types.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { f as MediaProvider, p as MediaProviderCapabilities } from "../placeholder-
|
|
2
|
-
import { t as Database } from "../types-
|
|
3
|
-
import {
|
|
4
|
-
import "../runner-
|
|
5
|
-
import { r as ContentItem } from "../types-
|
|
6
|
-
import { A as PageMetadataContribution, D as PageFragmentContribution, X as ResolvedPlugin, q as PublicPageContext, st as Element } from "../types-
|
|
7
|
-
import { d as Storage } from "../types-
|
|
8
|
-
import "../validate-
|
|
1
|
+
import { f as MediaProvider, p as MediaProviderCapabilities } from "../placeholder-D29tWZ7o.mjs";
|
|
2
|
+
import { t as Database } from "../types-CS8FIX7L.mjs";
|
|
3
|
+
import { Di as ContentListResponse, Jr as MediaListResponse, Oi as ContentResponse, Pr as SandboxRunner, Vi as MediaItem, Yr as MediaResponse, cn as HookPipeline, pn as EmDashConfig, sn as EmailPipeline } from "../index-DIb-CzNx.mjs";
|
|
4
|
+
import "../runner-OURCaApa.mjs";
|
|
5
|
+
import { r as ContentItem } from "../types-BrA0xf5I.mjs";
|
|
6
|
+
import { A as PageMetadataContribution, D as PageFragmentContribution, X as ResolvedPlugin, q as PublicPageContext, st as Element } from "../types-i36XcA_X.mjs";
|
|
7
|
+
import { d as Storage } from "../types-DIMwPFub.mjs";
|
|
8
|
+
import "../validate-DHxmpFJt.mjs";
|
|
9
9
|
import "../index.mjs";
|
|
10
10
|
import { Kysely } from "kysely";
|
|
11
11
|
|
|
@@ -129,6 +129,15 @@ interface EmDashManifest {
|
|
|
129
129
|
* When true, the admin UI can show marketplace browse/install features.
|
|
130
130
|
*/
|
|
131
131
|
marketplace?: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Admin branding overrides for white-labeling.
|
|
134
|
+
* Set via the `admin` config in `astro.config.mjs`.
|
|
135
|
+
*/
|
|
136
|
+
admin?: {
|
|
137
|
+
logo?: string;
|
|
138
|
+
siteName?: string;
|
|
139
|
+
favicon?: string;
|
|
140
|
+
};
|
|
132
141
|
}
|
|
133
142
|
/**
|
|
134
143
|
* Standard handler response shape used by all EmDashHandlers methods.
|
|
@@ -256,6 +265,7 @@ interface EmDashHandlers {
|
|
|
256
265
|
}>;
|
|
257
266
|
storage: Storage | null;
|
|
258
267
|
db: Kysely<Database>;
|
|
268
|
+
getPublicMediaUrl?: (storageKey: string) => string;
|
|
259
269
|
hooks: HookPipeline;
|
|
260
270
|
email: EmailPipeline | null;
|
|
261
271
|
configuredPlugins: ResolvedPlugin[];
|
|
@@ -266,6 +276,13 @@ interface EmDashHandlers {
|
|
|
266
276
|
setPluginStatus: (pluginId: string, status: "active" | "inactive") => Promise<void>;
|
|
267
277
|
collectPageMetadata: (page: PublicPageContext) => Promise<PageMetadataContribution[]>;
|
|
268
278
|
collectPageFragments: (page: PublicPageContext) => Promise<PageFragmentContribution[]>;
|
|
279
|
+
/**
|
|
280
|
+
* Lazy search index health check. Search routes call this before
|
|
281
|
+
* querying so a crash-corrupted index gets repaired on first use
|
|
282
|
+
* rather than stalling cold start. Optional because it's only
|
|
283
|
+
* meaningful when an FTS5-capable runtime is wired in.
|
|
284
|
+
*/
|
|
285
|
+
ensureSearchHealthy?: () => Promise<void>;
|
|
269
286
|
}
|
|
270
287
|
//#endregion
|
|
271
288
|
export { type ContentItem, type ContentListResponse, type ContentResponse, type Database, EmDashHandlers, EmDashManifest, HandlerResponse, ManifestAuthMode, ManifestCollection, ManifestPlugin, type MediaItem, type MediaListResponse, type MediaResponse, type Storage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/astro/types.ts"],"mappings":";;;;;;;;;;;;;;;UAyBiB,kBAAA;EAChB,KAAA;EACA,aAAA;EACA,QAAA;EACA,MAAA;EACA,UAAA;EACA,MAAA,EAAQ,MAAA;IAGN,IAAA;IACA,KAAA;IACA,QAAA;IACA,MAAA;IARF;;;;;;IAeE,OAAA,GAAU,KAAA;MAAQ,KAAA;MAAe,KAAA;IAAA,KAAmB,MAAA;EAAA;AAAA;;;;UAQtC,cAAA;EAChB,OAAA;;EAEA,OAAA;EAemB;EAbnB,OAAA;EAkBe;;;;;;EAXf,SAAA;EACA,UAAA,GAAa,KAAA;IACZ,IAAA;IACA,KAAA;IACA,IAAA;EAAA;EAED,gBAAA,GAAmB,KAAA;IAClB,EAAA;IACA,KAAA;IACA,IAAA;EAAA;EAED,YAAA,GAAe,KAAA;IACd,IAAA;IACA,KAAA;IACA,UAAA;IACA,QAAA,GAAW,OAAA;EAAA;EADX;EAID,kBAAA,GAAqB,KAAA;IACpB,IAAA;IACA,KAAA;IACA,IAAA;IACA,WAAA;IACA,WAAA;IACA,MAAA,GAAS,OAAA;EAAA;AAAA;;;;;AASX;KAAY,gBAAA;;;;UAKK,cAAA;EAChB,OAAA;EACA,MAAA;EACA,IAAA;EACA,WAAA,EAAa,MAAA,SAAe,kBAAA;EAC5B,OAAA,EAAS,MAAA,SAAe,cAAA;EAAf;;;;;;EAOT,QAAA,EAAU,gBAAA;EATV;;;;EAcA,aAAA;EAZS;;;;EAiBT,IAAA;IACC,aAAA;IACA,OAAA;IACA,mBAAA;EAAA;EAKD;;;EAAA,UAAA,EAAY,KAAA;IACX,IAAA;IACA,KAAA;IACA,aAAA;IACA,YAAA;IACA,WAAA;EAAA;
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/astro/types.ts"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as validateIdentifier } from "./validate-VPnKoIzW.mjs";
|
|
2
2
|
import { s as listTablesLike } from "./dialect-helpers-DhTzaUxP.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { i as encodeCursor, r as decodeCursor } from "./types-BIgulNsW.mjs";
|
|
4
4
|
import { t as withTransaction } from "./transaction-Cn2rjY78.mjs";
|
|
5
5
|
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-HGz06Soa.mjs";
|
|
6
6
|
import { sql } from "kysely";
|
|
@@ -48,7 +48,7 @@ var BylineRepository = class {
|
|
|
48
48
|
if (options?.userId !== void 0) query = query.where("user_id", "=", options.userId);
|
|
49
49
|
if (options?.cursor) {
|
|
50
50
|
const decoded = decodeCursor(options.cursor);
|
|
51
|
-
|
|
51
|
+
query = query.where((eb) => eb.or([eb("created_at", "<", decoded.orderValue), eb.and([eb("created_at", "=", decoded.orderValue), eb("id", "<", decoded.id)])]));
|
|
52
52
|
}
|
|
53
53
|
const rows = await query.execute();
|
|
54
54
|
const items = rows.slice(0, limit).map(rowToByline);
|
|
@@ -217,4 +217,4 @@ var BylineRepository = class {
|
|
|
217
217
|
|
|
218
218
|
//#endregion
|
|
219
219
|
export { BylineRepository as t };
|
|
220
|
-
//# sourceMappingURL=byline-
|
|
220
|
+
//# sourceMappingURL=byline-Chbr2GoP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byline-Chbr2GoP.mjs","names":[],"sources":["../src/database/repositories/byline.ts"],"sourcesContent":["import { sql, type Kysely, type Selectable } from \"kysely\";\nimport { ulid } from \"ulidx\";\n\nimport { chunks, SQL_BATCH_SIZE } from \"../../utils/chunks.js\";\nimport { listTablesLike } from \"../dialect-helpers.js\";\nimport { withTransaction } from \"../transaction.js\";\nimport type { BylineTable, Database } from \"../types.js\";\nimport { validateIdentifier } from \"../validate.js\";\nimport {\n\tdecodeCursor,\n\tencodeCursor,\n\ttype BylineSummary,\n\ttype ContentBylineCredit,\n\ttype FindManyResult,\n} from \"./types.js\";\n\ntype BylineRow = Selectable<BylineTable>;\n\nexport interface CreateBylineInput {\n\tslug: string;\n\tdisplayName: string;\n\tbio?: string | null;\n\tavatarMediaId?: string | null;\n\twebsiteUrl?: string | null;\n\tuserId?: string | null;\n\tisGuest?: boolean;\n}\n\nexport interface UpdateBylineInput {\n\tslug?: string;\n\tdisplayName?: string;\n\tbio?: string | null;\n\tavatarMediaId?: string | null;\n\twebsiteUrl?: string | null;\n\tuserId?: string | null;\n\tisGuest?: boolean;\n}\n\nexport interface ContentBylineInput {\n\tbylineId: string;\n\troleLabel?: string | null;\n}\n\nfunction rowToByline(row: BylineRow): BylineSummary {\n\treturn {\n\t\tid: row.id,\n\t\tslug: row.slug,\n\t\tdisplayName: row.display_name,\n\t\tbio: row.bio,\n\t\tavatarMediaId: row.avatar_media_id,\n\t\twebsiteUrl: row.website_url,\n\t\tuserId: row.user_id,\n\t\tisGuest: row.is_guest === 1,\n\t\tcreatedAt: row.created_at,\n\t\tupdatedAt: row.updated_at,\n\t};\n}\n\nexport class BylineRepository {\n\tconstructor(private db: Kysely<Database>) {}\n\n\tasync findById(id: string): Promise<BylineSummary | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t.selectAll()\n\t\t\t.where(\"id\", \"=\", id)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? rowToByline(row) : null;\n\t}\n\n\tasync findBySlug(slug: string): Promise<BylineSummary | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t.selectAll()\n\t\t\t.where(\"slug\", \"=\", slug)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? rowToByline(row) : null;\n\t}\n\n\tasync findByUserId(userId: string): Promise<BylineSummary | null> {\n\t\tconst row = await this.db\n\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t.selectAll()\n\t\t\t.where(\"user_id\", \"=\", userId)\n\t\t\t.executeTakeFirst();\n\t\treturn row ? rowToByline(row) : null;\n\t}\n\n\tasync findMany(options?: {\n\t\tsearch?: string;\n\t\tisGuest?: boolean;\n\t\tuserId?: string;\n\t\tcursor?: string;\n\t\tlimit?: number;\n\t}): Promise<FindManyResult<BylineSummary>> {\n\t\tconst limit = Math.min(Math.max(options?.limit ?? 50, 1), 100);\n\n\t\tlet query = this.db\n\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t.selectAll()\n\t\t\t.orderBy(\"created_at\", \"desc\")\n\t\t\t.orderBy(\"id\", \"desc\")\n\t\t\t.limit(limit + 1);\n\n\t\tif (options?.search) {\n\t\t\tconst escaped = options.search\n\t\t\t\t.replaceAll(\"\\\\\", \"\\\\\\\\\")\n\t\t\t\t.replaceAll(\"%\", \"\\\\%\")\n\t\t\t\t.replaceAll(\"_\", \"\\\\_\");\n\t\t\tconst term = `%${escaped}%`;\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([eb(\"display_name\", \"like\", term), eb(\"slug\", \"like\", term)]),\n\t\t\t);\n\t\t}\n\n\t\tif (options?.isGuest !== undefined) {\n\t\t\tquery = query.where(\"is_guest\", \"=\", options.isGuest ? 1 : 0);\n\t\t}\n\n\t\tif (options?.userId !== undefined) {\n\t\t\tquery = query.where(\"user_id\", \"=\", options.userId);\n\t\t}\n\n\t\tif (options?.cursor) {\n\t\t\tconst decoded = decodeCursor(options.cursor);\n\t\t\tquery = query.where((eb) =>\n\t\t\t\teb.or([\n\t\t\t\t\teb(\"created_at\", \"<\", decoded.orderValue),\n\t\t\t\t\teb.and([eb(\"created_at\", \"=\", decoded.orderValue), eb(\"id\", \"<\", decoded.id)]),\n\t\t\t\t]),\n\t\t\t);\n\t\t}\n\n\t\tconst rows = await query.execute();\n\t\tconst items = rows.slice(0, limit).map(rowToByline);\n\t\tconst result: FindManyResult<BylineSummary> = { items };\n\n\t\tif (rows.length > limit) {\n\t\t\tconst last = items.at(-1);\n\t\t\tif (last) {\n\t\t\t\tresult.nextCursor = encodeCursor(last.createdAt, last.id);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tasync create(input: CreateBylineInput): Promise<BylineSummary> {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\tawait this.db\n\t\t\t.insertInto(\"_emdash_bylines\")\n\t\t\t.values({\n\t\t\t\tid,\n\t\t\t\tslug: input.slug,\n\t\t\t\tdisplay_name: input.displayName,\n\t\t\t\tbio: input.bio ?? null,\n\t\t\t\tavatar_media_id: input.avatarMediaId ?? null,\n\t\t\t\twebsite_url: input.websiteUrl ?? null,\n\t\t\t\tuser_id: input.userId ?? null,\n\t\t\t\tis_guest: input.isGuest ? 1 : 0,\n\t\t\t\tcreated_at: now,\n\t\t\t\tupdated_at: now,\n\t\t\t})\n\t\t\t.execute();\n\n\t\tconst byline = await this.findById(id);\n\t\tif (!byline) {\n\t\t\tthrow new Error(\"Failed to create byline\");\n\t\t}\n\t\treturn byline;\n\t}\n\n\tasync update(id: string, input: UpdateBylineInput): Promise<BylineSummary | null> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) return null;\n\n\t\tconst updates: Record<string, unknown> = {\n\t\t\tupdated_at: new Date().toISOString(),\n\t\t};\n\n\t\tif (input.slug !== undefined) updates.slug = input.slug;\n\t\tif (input.displayName !== undefined) updates.display_name = input.displayName;\n\t\tif (input.bio !== undefined) updates.bio = input.bio;\n\t\tif (input.avatarMediaId !== undefined) updates.avatar_media_id = input.avatarMediaId;\n\t\tif (input.websiteUrl !== undefined) updates.website_url = input.websiteUrl;\n\t\tif (input.userId !== undefined) updates.user_id = input.userId;\n\t\tif (input.isGuest !== undefined) updates.is_guest = input.isGuest ? 1 : 0;\n\n\t\tawait this.db.updateTable(\"_emdash_bylines\").set(updates).where(\"id\", \"=\", id).execute();\n\t\treturn await this.findById(id);\n\t}\n\n\tasync delete(id: string): Promise<boolean> {\n\t\tconst existing = await this.findById(id);\n\t\tif (!existing) return false;\n\n\t\tawait withTransaction(this.db, async (trx) => {\n\t\t\tawait trx.deleteFrom(\"_emdash_content_bylines\").where(\"byline_id\", \"=\", id).execute();\n\n\t\t\tawait trx.deleteFrom(\"_emdash_bylines\").where(\"id\", \"=\", id).execute();\n\n\t\t\tconst tableNames = await listTablesLike(trx, \"ec_%\");\n\t\t\tfor (const tableName of tableNames) {\n\t\t\t\tvalidateIdentifier(tableName, \"content table\");\n\t\t\t\tawait sql`\n\t\t\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\t\t\tSET primary_byline_id = NULL\n\t\t\t\t\tWHERE primary_byline_id = ${id}\n\t\t\t\t`.execute(trx);\n\t\t\t}\n\t\t});\n\n\t\treturn true;\n\t}\n\n\tasync getContentBylines(\n\t\tcollectionSlug: string,\n\t\tcontentId: string,\n\t): Promise<ContentBylineCredit[]> {\n\t\tconst rows = await this.db\n\t\t\t.selectFrom(\"_emdash_content_bylines as cb\")\n\t\t\t.innerJoin(\"_emdash_bylines as b\", \"b.id\", \"cb.byline_id\")\n\t\t\t.select([\n\t\t\t\t\"cb.sort_order as sort_order\",\n\t\t\t\t\"cb.role_label as role_label\",\n\t\t\t\t\"b.id as id\",\n\t\t\t\t\"b.slug as slug\",\n\t\t\t\t\"b.display_name as display_name\",\n\t\t\t\t\"b.bio as bio\",\n\t\t\t\t\"b.avatar_media_id as avatar_media_id\",\n\t\t\t\t\"b.website_url as website_url\",\n\t\t\t\t\"b.user_id as user_id\",\n\t\t\t\t\"b.is_guest as is_guest\",\n\t\t\t\t\"b.created_at as created_at\",\n\t\t\t\t\"b.updated_at as updated_at\",\n\t\t\t])\n\t\t\t.where(\"cb.collection_slug\", \"=\", collectionSlug)\n\t\t\t.where(\"cb.content_id\", \"=\", contentId)\n\t\t\t.orderBy(\"cb.sort_order\", \"asc\")\n\t\t\t.execute();\n\n\t\treturn rows.map((row) => ({\n\t\t\tbyline: rowToByline(row),\n\t\t\tsortOrder: row.sort_order,\n\t\t\troleLabel: row.role_label,\n\t\t}));\n\t}\n\n\t/**\n\t * Batch-fetch byline credits for multiple content items in a single query.\n\t * Returns a Map keyed by contentId.\n\t */\n\tasync getContentBylinesMany(\n\t\tcollectionSlug: string,\n\t\tcontentIds: string[],\n\t): Promise<Map<string, ContentBylineCredit[]>> {\n\t\tconst result = new Map<string, ContentBylineCredit[]>();\n\t\tif (contentIds.length === 0) return result;\n\n\t\tconst uniqueContentIds = [...new Set(contentIds)];\n\t\tfor (const chunk of chunks(uniqueContentIds, SQL_BATCH_SIZE)) {\n\t\t\tconst rows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_content_bylines as cb\")\n\t\t\t\t.innerJoin(\"_emdash_bylines as b\", \"b.id\", \"cb.byline_id\")\n\t\t\t\t.select([\n\t\t\t\t\t\"cb.content_id as content_id\",\n\t\t\t\t\t\"cb.sort_order as sort_order\",\n\t\t\t\t\t\"cb.role_label as role_label\",\n\t\t\t\t\t\"b.id as id\",\n\t\t\t\t\t\"b.slug as slug\",\n\t\t\t\t\t\"b.display_name as display_name\",\n\t\t\t\t\t\"b.bio as bio\",\n\t\t\t\t\t\"b.avatar_media_id as avatar_media_id\",\n\t\t\t\t\t\"b.website_url as website_url\",\n\t\t\t\t\t\"b.user_id as user_id\",\n\t\t\t\t\t\"b.is_guest as is_guest\",\n\t\t\t\t\t\"b.created_at as created_at\",\n\t\t\t\t\t\"b.updated_at as updated_at\",\n\t\t\t\t])\n\t\t\t\t.where(\"cb.collection_slug\", \"=\", collectionSlug)\n\t\t\t\t.where(\"cb.content_id\", \"in\", chunk)\n\t\t\t\t.orderBy(\"cb.sort_order\", \"asc\")\n\t\t\t\t.execute();\n\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst contentId = row.content_id;\n\t\t\t\tconst credit: ContentBylineCredit = {\n\t\t\t\t\tbyline: rowToByline(row),\n\t\t\t\t\tsortOrder: row.sort_order,\n\t\t\t\t\troleLabel: row.role_label,\n\t\t\t\t};\n\t\t\t\tconst existing = result.get(contentId);\n\t\t\t\tif (existing) {\n\t\t\t\t\texisting.push(credit);\n\t\t\t\t} else {\n\t\t\t\t\tresult.set(contentId, [credit]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Batch-fetch byline profiles linked to user IDs in a single query.\n\t * Returns a Map keyed by userId.\n\t */\n\tasync findByUserIds(userIds: string[]): Promise<Map<string, BylineSummary>> {\n\t\tconst result = new Map<string, BylineSummary>();\n\t\tif (userIds.length === 0) return result;\n\n\t\tfor (const chunk of chunks(userIds, SQL_BATCH_SIZE)) {\n\t\t\tconst rows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t\t.selectAll()\n\t\t\t\t.where(\"user_id\", \"in\", chunk)\n\t\t\t\t.execute();\n\n\t\t\tfor (const row of rows) {\n\t\t\t\tif (row.user_id) {\n\t\t\t\t\tresult.set(row.user_id, rowToByline(row));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tasync setContentBylines(\n\t\tcollectionSlug: string,\n\t\tcontentId: string,\n\t\tinputBylines: ContentBylineInput[],\n\t): Promise<ContentBylineCredit[]> {\n\t\tvalidateIdentifier(collectionSlug, \"collection slug\");\n\t\tconst tableName = `ec_${collectionSlug}`;\n\t\tvalidateIdentifier(tableName, \"content table\");\n\n\t\tconst seen = new Set<string>();\n\t\tconst bylines = inputBylines.filter((item) => {\n\t\t\tif (seen.has(item.bylineId)) return false;\n\t\t\tseen.add(item.bylineId);\n\t\t\treturn true;\n\t\t});\n\n\t\t// This method is expected to be called within a transaction context\n\t\t// (content handlers wrap in withTransaction, seed applies sequentially).\n\t\t// All operations use this.db directly -- callers are responsible for\n\t\t// wrapping in a transaction when atomicity is required.\n\t\tif (bylines.length > 0) {\n\t\t\tconst ids = bylines.map((item) => item.bylineId);\n\t\t\tconst rows = await this.db\n\t\t\t\t.selectFrom(\"_emdash_bylines\")\n\t\t\t\t.select(\"id\")\n\t\t\t\t.where(\"id\", \"in\", ids)\n\t\t\t\t.execute();\n\t\t\tif (rows.length !== ids.length) {\n\t\t\t\tthrow new Error(\"One or more byline IDs do not exist\");\n\t\t\t}\n\t\t}\n\n\t\tawait this.db\n\t\t\t.deleteFrom(\"_emdash_content_bylines\")\n\t\t\t.where(\"collection_slug\", \"=\", collectionSlug)\n\t\t\t.where(\"content_id\", \"=\", contentId)\n\t\t\t.execute();\n\n\t\tfor (let i = 0; i < bylines.length; i++) {\n\t\t\tconst item = bylines[i];\n\t\t\tawait this.db\n\t\t\t\t.insertInto(\"_emdash_content_bylines\")\n\t\t\t\t.values({\n\t\t\t\t\tid: ulid(),\n\t\t\t\t\tcollection_slug: collectionSlug,\n\t\t\t\t\tcontent_id: contentId,\n\t\t\t\t\tbyline_id: item.bylineId,\n\t\t\t\t\tsort_order: i,\n\t\t\t\t\trole_label: item.roleLabel ?? null,\n\t\t\t\t\tcreated_at: new Date().toISOString(),\n\t\t\t\t})\n\t\t\t\t.execute();\n\t\t}\n\n\t\tawait sql`\n\t\t\tUPDATE ${sql.ref(tableName)}\n\t\t\tSET primary_byline_id = ${bylines[0]?.bylineId ?? null}\n\t\t\tWHERE id = ${contentId}\n\t\t`.execute(this.db);\n\n\t\treturn await this.getContentBylines(collectionSlug, contentId);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-ClPoSABd.mjs";
|
|
2
2
|
import { t as validateIdentifier } from "./validate-VPnKoIzW.mjs";
|
|
3
3
|
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-HGz06Soa.mjs";
|
|
4
|
-
import { t as BylineRepository } from "./byline-
|
|
5
|
-
import { t as isMissingTableError } from "./db-errors-
|
|
6
|
-
import { n as getDb } from "./loader-
|
|
4
|
+
import { t as BylineRepository } from "./byline-Chbr2GoP.mjs";
|
|
5
|
+
import { t as isMissingTableError } from "./db-errors-l1Qh2RPR.mjs";
|
|
6
|
+
import { n as getDb } from "./loader-CndGj8kM.mjs";
|
|
7
7
|
import { sql } from "kysely";
|
|
8
8
|
|
|
9
9
|
//#region src/bylines/index.ts
|
|
@@ -154,4 +154,4 @@ async function getAuthorIds(db, collection, entryIds) {
|
|
|
154
154
|
|
|
155
155
|
//#endregion
|
|
156
156
|
export { getByline as n, getBylineBySlug as r, bylines_exports as t };
|
|
157
|
-
//# sourceMappingURL=bylines-
|
|
157
|
+
//# sourceMappingURL=bylines-CRNsVG88.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bylines-
|
|
1
|
+
{"version":3,"file":"bylines-CRNsVG88.mjs","names":[],"sources":["../src/bylines/index.ts"],"sourcesContent":["/**\n * Runtime API for bylines\n *\n * Provides functions to query byline profiles and byline credits\n * associated with content entries. Follows the same pattern as\n * the taxonomies runtime API.\n */\n\nimport { sql } from \"kysely\";\n\nimport { BylineRepository } from \"../database/repositories/byline.js\";\nimport type { BylineSummary, ContentBylineCredit } from \"../database/repositories/types.js\";\nimport { validateIdentifier } from \"../database/validate.js\";\nimport { getDb } from \"../loader.js\";\nimport { chunks, SQL_BATCH_SIZE } from \"../utils/chunks.js\";\nimport { isMissingTableError } from \"../utils/db-errors.js\";\n\n/**\n * No-op — kept for API compatibility.\n *\n * Used to invalidate a worker-lifetime \"has any byline?\" probe. That\n * probe added a query on every cold isolate to save one query on sites\n * with zero bylines (i.e. the wrong tradeoff), so we dropped it. The\n * batch byline join below returns an empty map for empty sites at the\n * same cost as the probe, without the pre-check.\n */\nexport function invalidateBylineCache(): void {\n\t// Intentionally empty.\n}\n\n/**\n * Get a byline by ID.\n *\n * @example\n * ```ts\n * import { getByline } from \"emdash\";\n *\n * const byline = await getByline(\"01HXYZ...\");\n * if (byline) {\n * console.log(byline.displayName);\n * }\n * ```\n */\nexport async function getByline(id: string): Promise<BylineSummary | null> {\n\tconst db = await getDb();\n\tconst repo = new BylineRepository(db);\n\treturn repo.findById(id);\n}\n\n/**\n * Get a byline by slug.\n *\n * @example\n * ```ts\n * import { getBylineBySlug } from \"emdash\";\n *\n * const byline = await getBylineBySlug(\"jane-doe\");\n * if (byline) {\n * console.log(byline.displayName); // \"Jane Doe\"\n * }\n * ```\n */\nexport async function getBylineBySlug(slug: string): Promise<BylineSummary | null> {\n\tconst db = await getDb();\n\tconst repo = new BylineRepository(db);\n\treturn repo.findBySlug(slug);\n}\n\n/**\n * Get byline credits for a single content entry.\n *\n * Returns explicit byline credits from the junction table. If none exist\n * but the entry has an `authorId`, falls back to the user-linked byline\n * (marked as source: \"inferred\").\n *\n * @example\n * ```ts\n * import { getEntryBylines } from \"emdash\";\n *\n * const bylines = await getEntryBylines(\"posts\", post.data.id);\n * for (const credit of bylines) {\n * console.log(credit.byline.displayName, credit.roleLabel);\n * }\n * ```\n */\nexport async function getEntryBylines(\n\tcollection: string,\n\tentryId: string,\n): Promise<ContentBylineCredit[]> {\n\tvalidateIdentifier(collection, \"collection\");\n\tconst db = await getDb();\n\tconst repo = new BylineRepository(db);\n\n\tconst explicit = await repo.getContentBylines(collection, entryId);\n\tif (explicit.length > 0) {\n\t\treturn explicit.map((c) => ({ ...c, source: \"explicit\" as const }));\n\t}\n\n\t// Fallback: look up user-linked byline from author_id\n\tconst authorId = await getAuthorId(db, collection, entryId);\n\tif (authorId) {\n\t\tconst fallback = await repo.findByUserId(authorId);\n\t\tif (fallback) {\n\t\t\treturn [{ byline: fallback, sortOrder: 0, roleLabel: null, source: \"inferred\" }];\n\t\t}\n\t}\n\n\treturn [];\n}\n\n/**\n * Batch-fetch byline credits for multiple content entries in a single query.\n *\n * This is more efficient than calling getEntryBylines for each entry\n * when you need bylines for a list of entries (e.g., a blog index page).\n *\n * @param collection - The collection slug (e.g., \"posts\")\n * @param entryIds - Array of entry IDs\n * @returns Map from entry ID to array of byline credits\n *\n * @example\n * ```ts\n * import { getBylinesForEntries, getEmDashCollection } from \"emdash\";\n *\n * const { entries } = await getEmDashCollection(\"posts\");\n * const ids = entries.map(e => e.data.id);\n * const bylinesMap = await getBylinesForEntries(\"posts\", ids);\n *\n * for (const entry of entries) {\n * const bylines = bylinesMap.get(entry.data.id) ?? [];\n * // render bylines\n * }\n * ```\n */\nexport async function getBylinesForEntries(\n\tcollection: string,\n\tentryIds: string[],\n): Promise<Map<string, ContentBylineCredit[]>> {\n\tvalidateIdentifier(collection, \"collection\");\n\tconst result = new Map<string, ContentBylineCredit[]>();\n\n\t// Initialize all entry IDs with empty arrays\n\tfor (const id of entryIds) {\n\t\tresult.set(id, []);\n\t}\n\n\tif (entryIds.length === 0) {\n\t\treturn result;\n\t}\n\n\tconst db = await getDb();\n\tconst repo = new BylineRepository(db);\n\n\t// 1. Batch fetch all explicit byline credits. Sites with no bylines\n\t// get an empty map back for one query — the previous \"has any bylines\"\n\t// probe traded an extra round-trip on every request to save that one\n\t// query on empty sites, which is exactly backwards for the common case.\n\t// Pre-migration databases (bylines table missing) fall through to the\n\t// `isMissingTableError` catch below and return empty results.\n\tlet bylinesMap;\n\ttry {\n\t\tbylinesMap = await repo.getContentBylinesMany(collection, entryIds);\n\t} catch (error) {\n\t\tif (isMissingTableError(error)) return result;\n\t\tthrow error;\n\t}\n\n\t// 2. Collect entry IDs that need fallback lookup\n\tconst fallbackEntryIds: string[] = [];\n\tconst needsFallback: Map<string, string> = new Map(); // entryId -> authorId\n\n\tfor (const id of entryIds) {\n\t\tif (!bylinesMap.has(id)) {\n\t\t\t// Need to check author_id for this entry — but we only have the IDs,\n\t\t\t// so batch-fetch them from the content table\n\t\t\tfallbackEntryIds.push(id);\n\t\t}\n\t}\n\n\t// Batch-fetch author_ids for entries that need fallback\n\tif (fallbackEntryIds.length > 0) {\n\t\tconst authorMap = await getAuthorIds(db, collection, fallbackEntryIds);\n\t\tfor (const [entryId, authorId] of authorMap) {\n\t\t\tneedsFallback.set(entryId, authorId);\n\t\t}\n\t}\n\n\t// 3. Batch fetch user-linked bylines for fallback\n\tconst uniqueAuthorIds = [...new Set(needsFallback.values())];\n\tconst authorBylineMap = await repo.findByUserIds(uniqueAuthorIds);\n\n\t// 4. Assign results\n\tfor (const id of entryIds) {\n\t\tconst explicit = bylinesMap.get(id);\n\t\tif (explicit && explicit.length > 0) {\n\t\t\tresult.set(\n\t\t\t\tid,\n\t\t\t\texplicit.map((c) => ({ ...c, source: \"explicit\" as const })),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst authorId = needsFallback.get(id);\n\t\tif (authorId) {\n\t\t\tconst fallback = authorBylineMap.get(authorId);\n\t\t\tif (fallback) {\n\t\t\t\tresult.set(id, [{ byline: fallback, sortOrder: 0, roleLabel: null, source: \"inferred\" }]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Already initialized with empty array\n\t}\n\n\treturn result;\n}\n\n/**\n * Look up the author_id for a single content entry.\n * Uses raw SQL since we need dynamic table names.\n */\nasync function getAuthorId(\n\tdb: Awaited<ReturnType<typeof getDb>>,\n\tcollection: string,\n\tentryId: string,\n): Promise<string | null> {\n\tvalidateIdentifier(collection, \"collection\");\n\tconst tableName = `ec_${collection}`;\n\n\tconst result = await sql<{ author_id: string | null }>`\n\t\tSELECT author_id FROM ${sql.ref(tableName)}\n\t\tWHERE id = ${entryId}\n\t\tLIMIT 1\n\t`.execute(db);\n\n\treturn result.rows[0]?.author_id ?? null;\n}\n\n/**\n * Batch-fetch author_ids for multiple content entries.\n * Returns Map<entryId, authorId> (only entries with non-null author_id).\n */\nasync function getAuthorIds(\n\tdb: Awaited<ReturnType<typeof getDb>>,\n\tcollection: string,\n\tentryIds: string[],\n): Promise<Map<string, string>> {\n\tvalidateIdentifier(collection, \"collection\");\n\tconst tableName = `ec_${collection}`;\n\n\tconst map = new Map<string, string>();\n\tfor (const chunk of chunks(entryIds, SQL_BATCH_SIZE)) {\n\t\tconst result = await sql<{ id: string; author_id: string | null }>`\n\t\t\tSELECT id, author_id FROM ${sql.ref(tableName)}\n\t\t\tWHERE id IN (${sql.join(chunk.map((id) => sql`${id}`))})\n\t\t`.execute(db);\n\n\t\tfor (const row of result.rows) {\n\t\t\tif (row.author_id) {\n\t\t\t\tmap.set(row.id, row.author_id);\n\t\t\t}\n\t\t}\n\t}\n\treturn map;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,wBAA8B;;;;;;;;;;;;;;AAiB9C,eAAsB,UAAU,IAA2C;AAG1E,QADa,IAAI,iBADN,MAAM,OAAO,CACa,CACzB,SAAS,GAAG;;;;;;;;;;;;;;;AAgBzB,eAAsB,gBAAgB,MAA6C;AAGlF,QADa,IAAI,iBADN,MAAM,OAAO,CACa,CACzB,WAAW,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;AAqE7B,eAAsB,qBACrB,YACA,UAC8C;AAC9C,oBAAmB,YAAY,aAAa;CAC5C,MAAM,yBAAS,IAAI,KAAoC;AAGvD,MAAK,MAAM,MAAM,SAChB,QAAO,IAAI,IAAI,EAAE,CAAC;AAGnB,KAAI,SAAS,WAAW,EACvB,QAAO;CAGR,MAAM,KAAK,MAAM,OAAO;CACxB,MAAM,OAAO,IAAI,iBAAiB,GAAG;CAQrC,IAAI;AACJ,KAAI;AACH,eAAa,MAAM,KAAK,sBAAsB,YAAY,SAAS;UAC3D,OAAO;AACf,MAAI,oBAAoB,MAAM,CAAE,QAAO;AACvC,QAAM;;CAIP,MAAM,mBAA6B,EAAE;CACrC,MAAM,gCAAqC,IAAI,KAAK;AAEpD,MAAK,MAAM,MAAM,SAChB,KAAI,CAAC,WAAW,IAAI,GAAG,CAGtB,kBAAiB,KAAK,GAAG;AAK3B,KAAI,iBAAiB,SAAS,GAAG;EAChC,MAAM,YAAY,MAAM,aAAa,IAAI,YAAY,iBAAiB;AACtE,OAAK,MAAM,CAAC,SAAS,aAAa,UACjC,eAAc,IAAI,SAAS,SAAS;;CAKtC,MAAM,kBAAkB,CAAC,GAAG,IAAI,IAAI,cAAc,QAAQ,CAAC,CAAC;CAC5D,MAAM,kBAAkB,MAAM,KAAK,cAAc,gBAAgB;AAGjE,MAAK,MAAM,MAAM,UAAU;EAC1B,MAAM,WAAW,WAAW,IAAI,GAAG;AACnC,MAAI,YAAY,SAAS,SAAS,GAAG;AACpC,UAAO,IACN,IACA,SAAS,KAAK,OAAO;IAAE,GAAG;IAAG,QAAQ;IAAqB,EAAE,CAC5D;AACD;;EAGD,MAAM,WAAW,cAAc,IAAI,GAAG;AACtC,MAAI,UAAU;GACb,MAAM,WAAW,gBAAgB,IAAI,SAAS;AAC9C,OAAI,UAAU;AACb,WAAO,IAAI,IAAI,CAAC;KAAE,QAAQ;KAAU,WAAW;KAAG,WAAW;KAAM,QAAQ;KAAY,CAAC,CAAC;AACzF;;;;AAOH,QAAO;;;;;;AA4BR,eAAe,aACd,IACA,YACA,UAC+B;AAC/B,oBAAmB,YAAY,aAAa;CAC5C,MAAM,YAAY,MAAM;CAExB,MAAM,sBAAM,IAAI,KAAqB;AACrC,MAAK,MAAM,SAAS,OAAO,UAAU,eAAe,EAAE;EACrD,MAAM,SAAS,MAAM,GAA6C;+BACrC,IAAI,IAAI,UAAU,CAAC;kBAChC,IAAI,KAAK,MAAM,KAAK,OAAO,GAAG,GAAG,KAAK,CAAC,CAAC;IACtD,QAAQ,GAAG;AAEb,OAAK,MAAM,OAAO,OAAO,KACxB,KAAI,IAAI,UACP,KAAI,IAAI,IAAI,IAAI,IAAI,UAAU;;AAIjC,QAAO"}
|
package/dist/cli/index.mjs
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
import { t as __exportAll } from "../chunk-ClPoSABd.mjs";
|
|
3
3
|
import { n as createDatabase } from "../connection-2igzM-AT.mjs";
|
|
4
4
|
import { s as listTablesLike } from "../dialect-helpers-DhTzaUxP.mjs";
|
|
5
|
-
import { r as runMigrations, t as getMigrationStatus } from "../runner-
|
|
6
|
-
import { t as ContentRepository } from "../content-
|
|
5
|
+
import { r as runMigrations, t as getMigrationStatus } from "../runner-tQ7BJ4T7.mjs";
|
|
6
|
+
import { t as ContentRepository } from "../content-BcQPYxdV.mjs";
|
|
7
7
|
import { i as encodeBase64url } from "../base64-MBPo9ozB.mjs";
|
|
8
|
-
import "../types-
|
|
9
|
-
import { t as MediaRepository } from "../media-
|
|
10
|
-
import {
|
|
11
|
-
import "../redirect-
|
|
12
|
-
import "../byline-
|
|
8
|
+
import "../types-BIgulNsW.mjs";
|
|
9
|
+
import { t as MediaRepository } from "../media-D8FbNsl0.mjs";
|
|
10
|
+
import { m as TaxonomyRepository, p as OptionsRepository, t as applySeed } from "../apply-x0eMK1lX.mjs";
|
|
11
|
+
import "../redirect-D_pshWdf.mjs";
|
|
12
|
+
import "../byline-Chbr2GoP.mjs";
|
|
13
13
|
import { r as isI18nEnabled } from "../config-BXwuX8Bx.mjs";
|
|
14
|
-
import { n as SchemaRegistry } from "../registry-
|
|
15
|
-
import "../loader-
|
|
16
|
-
import "../request-cache-
|
|
17
|
-
import { i as pluginManifestSchema } from "../manifest-schema-
|
|
18
|
-
import { t as validateSeed } from "../validate-
|
|
14
|
+
import { n as SchemaRegistry } from "../registry-C3Mr0ODu.mjs";
|
|
15
|
+
import "../loader-CndGj8kM.mjs";
|
|
16
|
+
import "../request-cache-Ci7f5pBb.mjs";
|
|
17
|
+
import { i as pluginManifestSchema } from "../manifest-schema-DH9xhc6t.mjs";
|
|
18
|
+
import { t as validateSeed } from "../validate-CxVsLehf.mjs";
|
|
19
19
|
import { LocalStorage } from "../storage/local.mjs";
|
|
20
20
|
import { createHeaderAwareFetch, customHeadersInterceptor, getCachedAccessToken, isAccessRedirect, resolveCustomHeaders, runCloudflaredLogin } from "../client/cf-access.mjs";
|
|
21
21
|
import { EmDashClient } from "../client/index.mjs";
|
|
@@ -2324,7 +2324,7 @@ async function createTarball(sourceDir, outputPath) {
|
|
|
2324
2324
|
* 7. Create tarball ({id}-{version}.tar.gz)
|
|
2325
2325
|
*/
|
|
2326
2326
|
var bundle_exports = /* @__PURE__ */ __exportAll({ bundleCommand: () => bundleCommand });
|
|
2327
|
-
const TS_EXT_RE = /\.tsx
|
|
2327
|
+
const TS_EXT_RE = /\.(tsx?|[mc]?js)$/;
|
|
2328
2328
|
const SLASH_RE = /\//g;
|
|
2329
2329
|
const LEADING_AT_RE = /^@/;
|
|
2330
2330
|
const emdash_SCOPE_RE = /^@emdash-cms\//;
|
|
@@ -2398,6 +2398,10 @@ const bundleCommand = defineCommand({
|
|
|
2398
2398
|
const { build } = await import("tsdown");
|
|
2399
2399
|
const tmpDir = join(pluginDir, ".emdash-bundle-tmp");
|
|
2400
2400
|
try {
|
|
2401
|
+
await rm(tmpDir, {
|
|
2402
|
+
recursive: true,
|
|
2403
|
+
force: true
|
|
2404
|
+
});
|
|
2401
2405
|
await mkdir(tmpDir, { recursive: true });
|
|
2402
2406
|
const mainOutDir = join(tmpDir, "main");
|
|
2403
2407
|
await build({
|