emdash 0.8.0 → 0.10.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-BKSf3T9R.d.mts → adapters-BktHA7EO.d.mts} +1 -1
- package/dist/{adapters-BKSf3T9R.d.mts.map → adapters-BktHA7EO.d.mts.map} +1 -1
- package/dist/{apply-x0eMK1lX.mjs → apply-UsrFuO7l.mjs} +207 -355
- package/dist/apply-UsrFuO7l.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 +118 -4
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +6 -7
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +14 -57
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +15 -10
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +8 -5
- 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 +70 -121
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +25 -10
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{byline-Chbr2GoP.mjs → byline-C3vnhIpU.mjs} +4 -4
- package/dist/{byline-Chbr2GoP.mjs.map → byline-C3vnhIpU.mjs.map} +1 -1
- package/dist/bylines-esI7ioa9.mjs +113 -0
- package/dist/bylines-esI7ioa9.mjs.map +1 -0
- package/dist/cache-fTzxgMFJ.mjs +65 -0
- package/dist/cache-fTzxgMFJ.mjs.map +1 -0
- package/dist/{chunks-HGz06Soa.mjs → chunks-Da2-b-oA.mjs} +8 -2
- package/dist/{chunks-HGz06Soa.mjs.map → chunks-Da2-b-oA.mjs.map} +1 -1
- package/dist/cli/index.mjs +456 -90
- 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 +3 -3
- package/dist/client/index.mjs.map +1 -1
- package/dist/{config-BXwuX8Bx.mjs → config-CVssduLe.mjs} +1 -1
- package/dist/{config-BXwuX8Bx.mjs.map → config-CVssduLe.mjs.map} +1 -1
- package/dist/{content-BcQPYxdV.mjs → content-C7G4QXkK.mjs} +42 -14
- package/dist/content-C7G4QXkK.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/libsql.d.mts.map +1 -1
- package/dist/db/libsql.mjs +7 -2
- package/dist/db/libsql.mjs.map +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.d.mts.map +1 -1
- package/dist/db/sqlite.mjs +8 -3
- package/dist/db/sqlite.mjs.map +1 -1
- package/dist/{db-errors-l1Qh2RPR.mjs → db-errors-B7P2pSCn.mjs} +1 -1
- package/dist/{db-errors-l1Qh2RPR.mjs.map → db-errors-B7P2pSCn.mjs.map} +1 -1
- package/dist/{default-DCVqE5ib.mjs → default-pHuz9WF6.mjs} +1 -1
- package/dist/{default-DCVqE5ib.mjs.map → default-pHuz9WF6.mjs.map} +1 -1
- package/dist/{dialect-helpers-DhTzaUxP.mjs → dialect-helpers-BKCvISIQ.mjs} +19 -2
- package/dist/dialect-helpers-BKCvISIQ.mjs.map +1 -0
- package/dist/{error-zG5T1UGA.mjs → error-DqnRMM5z.mjs} +1 -1
- package/dist/{error-zG5T1UGA.mjs.map → error-DqnRMM5z.mjs.map} +1 -1
- package/dist/{index-DIb-CzNx.d.mts → index-DjPMOfO0.d.mts} +162 -87
- package/dist/index-DjPMOfO0.d.mts.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +27 -24
- package/dist/{load-CyEoextb.mjs → load-sXRuM7Us.mjs} +2 -2
- package/dist/{load-CyEoextb.mjs.map → load-sXRuM7Us.mjs.map} +1 -1
- package/dist/{loader-CndGj8kM.mjs → loader-Bx2_9-5e.mjs} +53 -8
- package/dist/loader-Bx2_9-5e.mjs.map +1 -0
- package/dist/{manifest-schema-DH9xhc6t.mjs → manifest-schema-CXAbd1vH.mjs} +33 -3
- package/dist/manifest-schema-CXAbd1vH.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +1 -1
- package/dist/media/local-runtime.d.mts +7 -7
- package/dist/{mode-BnAOqItE.mjs → mode-YhqNVef_.mjs} +1 -1
- package/dist/{mode-BnAOqItE.mjs.map → mode-YhqNVef_.mjs.map} +1 -1
- package/dist/options-nPxWnrya.mjs +117 -0
- package/dist/options-nPxWnrya.mjs.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/{patterns-CrCYkMBb.mjs → patterns-DsUZ4uxI.mjs} +1 -1
- package/dist/{patterns-CrCYkMBb.mjs.map → patterns-DsUZ4uxI.mjs.map} +1 -1
- package/dist/{placeholder-D29tWZ7o.d.mts → placeholder-CDPtkelt.d.mts} +1 -1
- package/dist/{placeholder-D29tWZ7o.d.mts.map → placeholder-CDPtkelt.d.mts.map} +1 -1
- package/dist/{placeholder-C-fk5hYI.mjs → placeholder-Ci0RLeCk.mjs} +1 -1
- package/dist/{placeholder-C-fk5hYI.mjs.map → placeholder-Ci0RLeCk.mjs.map} +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +6 -5
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/public-url-B1AxbbbQ.mjs +51 -0
- package/dist/public-url-B1AxbbbQ.mjs.map +1 -0
- package/dist/{query-fqEdLFms.mjs → query-Bo-msrmu.mjs} +114 -16
- package/dist/query-Bo-msrmu.mjs.map +1 -0
- package/dist/{redirect-D_pshWdf.mjs → redirect-C5H7VGIX.mjs} +11 -6
- package/dist/redirect-C5H7VGIX.mjs.map +1 -0
- package/dist/{registry-C3Mr0ODu.mjs → registry-Beb7wxFc.mjs} +39 -5
- package/dist/registry-Beb7wxFc.mjs.map +1 -0
- package/dist/{request-cache-Ci7f5pBb.mjs → request-cache-C-tIpYIw.mjs} +1 -1
- package/dist/{request-cache-Ci7f5pBb.mjs.map → request-cache-C-tIpYIw.mjs.map} +1 -1
- package/dist/runner-Clwe4Mme.d.mts +44 -0
- package/dist/runner-Clwe4Mme.d.mts.map +1 -0
- package/dist/{runner-tQ7BJ4T7.mjs → runner-DMnlIkh4.mjs} +616 -191
- package/dist/runner-DMnlIkh4.mjs.map +1 -0
- package/dist/runtime.d.mts +6 -6
- package/dist/runtime.mjs +2 -2
- package/dist/{search-BoZYFuUk.mjs → search-DkN-BqsS.mjs} +270 -152
- package/dist/search-DkN-BqsS.mjs.map +1 -0
- package/dist/secrets-CZ8rxLX3.mjs +314 -0
- package/dist/secrets-CZ8rxLX3.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +13 -11
- 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.mjs +1 -1
- package/dist/taxonomies-CTtewrSQ.mjs +407 -0
- package/dist/taxonomies-CTtewrSQ.mjs.map +1 -0
- package/dist/taxonomy-DSxx2K2L.mjs +218 -0
- package/dist/taxonomy-DSxx2K2L.mjs.map +1 -0
- package/dist/{tokens-D9vnZqYS.mjs → tokens-CyRDPVW2.mjs} +1 -1
- package/dist/{tokens-D9vnZqYS.mjs.map → tokens-CyRDPVW2.mjs.map} +1 -1
- package/dist/{transaction-Cn2rjY78.mjs → transaction-D44LBXvU.mjs} +1 -1
- package/dist/{transaction-Cn2rjY78.mjs.map → transaction-D44LBXvU.mjs.map} +1 -1
- package/dist/{transport-CUnEL3Vs.d.mts → transport-DX_5rpsq.d.mts} +1 -1
- package/dist/{transport-CUnEL3Vs.d.mts.map → transport-DX_5rpsq.d.mts.map} +1 -1
- package/dist/{transport-C9ugt2Nr.mjs → transport-xpzIjCIB.mjs} +6 -5
- package/dist/{transport-C9ugt2Nr.mjs.map → transport-xpzIjCIB.mjs.map} +1 -1
- package/dist/{types-BrA0xf5I.d.mts → types-B_CXXnzh.d.mts} +1 -1
- package/dist/{types-BrA0xf5I.d.mts.map → types-B_CXXnzh.d.mts.map} +1 -1
- package/dist/{types-DIMwPFub.d.mts → types-C-aFbqmA.d.mts} +1 -1
- package/dist/{types-DIMwPFub.d.mts.map → types-C-aFbqmA.d.mts.map} +1 -1
- package/dist/types-CoO6mpV3.mjs +68 -0
- package/dist/types-CoO6mpV3.mjs.map +1 -0
- package/dist/{types-i36XcA_X.d.mts → types-D19uBYWn.d.mts} +83 -7
- package/dist/types-D19uBYWn.d.mts.map +1 -0
- package/dist/{types-BmPPSUEx.d.mts → types-Dl1fgFjn.d.mts} +24 -2
- package/dist/{types-BmPPSUEx.d.mts.map → types-Dl1fgFjn.d.mts.map} +1 -1
- package/dist/{types-CS8FIX7L.d.mts → types-Dtx1mSMX.d.mts} +9 -1
- package/dist/types-Dtx1mSMX.d.mts.map +1 -0
- package/dist/{types-Bm1dn-q3.mjs → types-Eg829jj9.mjs} +1 -1
- package/dist/{types-Bm1dn-q3.mjs.map → types-Eg829jj9.mjs.map} +1 -1
- package/dist/{types-CgqmmMJB.mjs → types-K-EkEQCI.mjs} +1 -1
- package/dist/{types-CgqmmMJB.mjs.map → types-K-EkEQCI.mjs.map} +1 -1
- package/dist/{validate-CxVsLehf.mjs → validate-CBIbxM3L.mjs} +14 -10
- package/dist/validate-CBIbxM3L.mjs.map +1 -0
- package/dist/{validate-DHxmpFJt.d.mts → validate-DHGwADqO.d.mts} +18 -5
- package/dist/validate-DHGwADqO.d.mts.map +1 -0
- package/dist/{validation-C-ZpN2GI.mjs → validation-B1NYiEos.mjs} +6 -6
- package/dist/{validation-C-ZpN2GI.mjs.map → validation-B1NYiEos.mjs.map} +1 -1
- package/dist/version-CMD42IRC.mjs +7 -0
- package/dist/{version-Bbq8TCrz.mjs.map → version-CMD42IRC.mjs.map} +1 -1
- package/dist/{zod-generator-CpwccCIv.mjs → zod-generator-BNJDQBSZ.mjs} +11 -6
- package/dist/{zod-generator-CpwccCIv.mjs.map → zod-generator-BNJDQBSZ.mjs.map} +1 -1
- package/locals.d.ts +1 -6
- package/package.json +9 -8
- package/src/api/handlers/comments.ts +6 -4
- package/src/api/handlers/content.ts +40 -1
- package/src/api/handlers/dashboard.ts +29 -36
- package/src/api/handlers/device-flow.ts +5 -0
- package/src/api/handlers/marketplace.ts +11 -4
- package/src/api/handlers/menus.ts +256 -75
- package/src/api/handlers/oauth-authorization.ts +72 -33
- package/src/api/handlers/revision.ts +23 -14
- package/src/api/handlers/taxonomies.ts +273 -100
- package/src/api/public-url.ts +48 -2
- package/src/api/schemas/comments.ts +2 -2
- package/src/api/schemas/common.ts +7 -0
- package/src/api/schemas/content.ts +17 -0
- package/src/api/schemas/menus.ts +23 -0
- package/src/api/schemas/sections.ts +3 -3
- package/src/api/schemas/taxonomies.ts +39 -0
- package/src/api/schemas/users.ts +1 -1
- package/src/api/types.ts +5 -1
- package/src/astro/integration/index.ts +17 -0
- package/src/astro/integration/routes.ts +10 -0
- package/src/astro/integration/runtime.ts +30 -0
- package/src/astro/integration/virtual-modules.ts +32 -2
- package/src/astro/integration/vite-config.ts +6 -1
- package/src/astro/middleware/auth.ts +13 -6
- package/src/astro/middleware/redirect.ts +29 -16
- package/src/astro/middleware/request-context.ts +15 -5
- package/src/astro/middleware.ts +23 -9
- package/src/astro/routes/api/auth/invite/complete.ts +6 -1
- package/src/astro/routes/api/auth/passkey/register/verify.ts +6 -1
- package/src/astro/routes/api/auth/passkey/verify.ts +6 -1
- package/src/astro/routes/api/auth/signup/complete.ts +6 -1
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +4 -2
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +34 -12
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +32 -2
- package/src/astro/routes/api/content/[collection]/[id]/restore.ts +4 -2
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -2
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +8 -4
- package/src/astro/routes/api/content/[collection]/[id].ts +12 -0
- package/src/astro/routes/api/import/wordpress/execute.ts +3 -1
- package/src/astro/routes/api/import/wordpress/prepare.ts +7 -8
- package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +196 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +9 -177
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +3 -1
- package/src/astro/routes/api/manifest.ts +62 -45
- package/src/astro/routes/api/media/[id]/confirm.ts +10 -1
- package/src/astro/routes/api/media/providers/[providerId]/index.ts +12 -3
- package/src/astro/routes/api/menus/[name]/items.ts +16 -6
- package/src/astro/routes/api/menus/[name]/reorder.ts +8 -3
- package/src/astro/routes/api/menus/[name]/translations.ts +82 -0
- package/src/astro/routes/api/menus/[name].ts +19 -10
- package/src/astro/routes/api/menus/index.ts +9 -6
- package/src/astro/routes/api/openapi.json.ts +27 -10
- package/src/astro/routes/api/redirects/404s/index.ts +10 -4
- package/src/astro/routes/api/redirects/404s/summary.ts +4 -2
- package/src/astro/routes/api/redirects/[id].ts +10 -4
- package/src/astro/routes/api/redirects/index.ts +7 -3
- package/src/astro/routes/api/revisions/[revisionId]/index.ts +1 -1
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +0 -2
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +0 -1
- package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +0 -1
- package/src/astro/routes/api/schema/collections/[slug]/index.ts +2 -2
- package/src/astro/routes/api/schema/collections/index.ts +1 -1
- package/src/astro/routes/api/search/index.ts +10 -2
- package/src/astro/routes/api/sections/[slug].ts +10 -4
- package/src/astro/routes/api/sections/index.ts +7 -3
- package/src/astro/routes/api/setup/admin-verify.ts +6 -1
- package/src/astro/routes/api/snapshot.ts +44 -18
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +89 -0
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +22 -22
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +11 -14
- package/src/astro/routes/api/taxonomies/index.ts +9 -7
- package/src/astro/routes/api/themes/preview.ts +11 -5
- package/src/astro/types.ts +23 -3
- package/src/auth/allowed-origins.ts +168 -0
- package/src/auth/passkey-config.ts +35 -13
- package/src/bylines/index.ts +37 -88
- package/src/cli/commands/auth.ts +28 -6
- package/src/cli/commands/bundle-utils.ts +11 -2
- package/src/cli/commands/bundle.ts +28 -8
- package/src/cli/commands/content.ts +13 -0
- package/src/cli/commands/export-seed.ts +82 -21
- package/src/cli/commands/login.ts +8 -1
- package/src/cli/commands/plugin-init.ts +216 -90
- package/src/cli/commands/publish.ts +24 -0
- package/src/cli/commands/secrets.ts +183 -0
- package/src/cli/credentials.ts +1 -1
- package/src/cli/index.ts +5 -1
- package/src/client/index.ts +4 -4
- package/src/client/transport.ts +17 -7
- package/src/components/Break.astro +2 -2
- package/src/components/EmDashHead.astro +18 -13
- package/src/components/Embed.astro +1 -1
- package/src/components/Gallery.astro +1 -1
- package/src/components/Image.astro +1 -1
- package/src/components/InlinePortableTextEditor.tsx +104 -18
- package/src/config/secrets.ts +528 -0
- package/src/database/dialect-helpers.ts +50 -0
- package/src/database/migrations/034_published_at_index.ts +1 -1
- package/src/database/migrations/035_bounded_404_log.ts +56 -39
- package/src/database/migrations/036_i18n_menus_and_taxonomies.ts +477 -0
- package/src/database/migrations/runner.ts +158 -23
- package/src/database/repositories/content.ts +47 -12
- package/src/database/repositories/redirect.ts +14 -3
- package/src/database/repositories/taxonomy.ts +212 -82
- package/src/database/types.ts +10 -2
- package/src/db/libsql.ts +1 -3
- package/src/db/sqlite.ts +2 -5
- package/src/emdash-runtime.ts +84 -159
- package/src/i18n/resolve.ts +37 -0
- package/src/index.ts +9 -0
- package/src/loader.ts +73 -3
- package/src/mcp/server.ts +180 -54
- package/src/menus/index.ts +143 -124
- package/src/menus/types.ts +15 -1
- package/src/page/site-identity.ts +58 -0
- package/src/plugins/adapt-sandbox-entry.ts +22 -10
- package/src/plugins/context.ts +13 -10
- package/src/plugins/define-plugin.ts +40 -12
- package/src/plugins/hooks.ts +23 -19
- package/src/plugins/index.ts +9 -0
- package/src/plugins/manifest-schema.ts +37 -2
- package/src/plugins/types.ts +151 -11
- package/src/preview/urls.ts +23 -3
- package/src/query.ts +148 -5
- package/src/redirects/cache.ts +38 -18
- package/src/schema/registry.ts +56 -0
- package/src/schema/zod-generator.ts +39 -7
- package/src/seed/apply.ts +142 -54
- package/src/seed/types.ts +14 -1
- package/src/seed/validate.ts +27 -13
- package/src/settings/index.ts +80 -6
- package/src/settings/types.ts +23 -1
- package/src/taxonomies/index.ts +237 -210
- package/src/taxonomies/types.ts +10 -0
- package/dist/apply-x0eMK1lX.mjs.map +0 -1
- package/dist/bylines-CRNsVG88.mjs +0 -157
- package/dist/bylines-CRNsVG88.mjs.map +0 -1
- package/dist/cache-BkKBuIvS.mjs +0 -56
- package/dist/cache-BkKBuIvS.mjs.map +0 -1
- package/dist/chunk-ClPoSABd.mjs +0 -21
- package/dist/content-BcQPYxdV.mjs.map +0 -1
- package/dist/dialect-helpers-DhTzaUxP.mjs.map +0 -1
- package/dist/index-DIb-CzNx.d.mts.map +0 -1
- package/dist/loader-CndGj8kM.mjs.map +0 -1
- package/dist/manifest-schema-DH9xhc6t.mjs.map +0 -1
- package/dist/query-fqEdLFms.mjs.map +0 -1
- package/dist/redirect-D_pshWdf.mjs.map +0 -1
- package/dist/registry-C3Mr0ODu.mjs.map +0 -1
- package/dist/runner-OURCaApa.d.mts +0 -34
- package/dist/runner-OURCaApa.d.mts.map +0 -1
- package/dist/runner-tQ7BJ4T7.mjs.map +0 -1
- package/dist/search-BoZYFuUk.mjs.map +0 -1
- package/dist/taxonomies-B4IAshV8.mjs +0 -308
- package/dist/taxonomies-B4IAshV8.mjs.map +0 -1
- package/dist/types-CS8FIX7L.d.mts.map +0 -1
- package/dist/types-i36XcA_X.d.mts.map +0 -1
- package/dist/validate-CxVsLehf.mjs.map +0 -1
- package/dist/validate-DHxmpFJt.d.mts.map +0 -1
- package/dist/version-Bbq8TCrz.mjs +0 -7
package/dist/cli/index.mjs
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { i as __exportAll, r as runMigrations, t as getMigrationStatus } from "../runner-DMnlIkh4.mjs";
|
|
3
3
|
import { n as createDatabase } from "../connection-2igzM-AT.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { r as
|
|
6
|
-
import { t as ContentRepository } from "../content-
|
|
4
|
+
import { c as listTablesLike } from "../dialect-helpers-BKCvISIQ.mjs";
|
|
5
|
+
import { r as isI18nEnabled } from "../config-CVssduLe.mjs";
|
|
6
|
+
import { t as ContentRepository } from "../content-C7G4QXkK.mjs";
|
|
7
7
|
import { i as encodeBase64url } from "../base64-MBPo9ozB.mjs";
|
|
8
8
|
import "../types-BIgulNsW.mjs";
|
|
9
9
|
import { t as MediaRepository } from "../media-D8FbNsl0.mjs";
|
|
10
|
-
import {
|
|
11
|
-
import "../
|
|
12
|
-
import "../
|
|
13
|
-
import
|
|
14
|
-
import { n as SchemaRegistry } from "../registry-
|
|
15
|
-
import "../loader-
|
|
16
|
-
import "../request-cache-
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
10
|
+
import { t as TaxonomyRepository } from "../taxonomy-DSxx2K2L.mjs";
|
|
11
|
+
import { t as OptionsRepository } from "../options-nPxWnrya.mjs";
|
|
12
|
+
import "../redirect-C5H7VGIX.mjs";
|
|
13
|
+
import "../byline-C3vnhIpU.mjs";
|
|
14
|
+
import { n as SchemaRegistry } from "../registry-Beb7wxFc.mjs";
|
|
15
|
+
import "../loader-Bx2_9-5e.mjs";
|
|
16
|
+
import "../request-cache-C-tIpYIw.mjs";
|
|
17
|
+
import { t as applySeed } from "../apply-UsrFuO7l.mjs";
|
|
18
|
+
import { i as pluginManifestSchema } from "../manifest-schema-CXAbd1vH.mjs";
|
|
19
|
+
import { n as isDeprecatedCapability, t as CAPABILITY_RENAMES } from "../types-CoO6mpV3.mjs";
|
|
20
|
+
import { t as validateSeed } from "../validate-CBIbxM3L.mjs";
|
|
21
|
+
import { n as fingerprintKey, r as generateEncryptionKey, t as EmDashSecretsError } from "../secrets-CZ8rxLX3.mjs";
|
|
19
22
|
import { LocalStorage } from "../storage/local.mjs";
|
|
23
|
+
import { o as convertDataForRead } from "../transport-xpzIjCIB.mjs";
|
|
20
24
|
import { createHeaderAwareFetch, customHeadersInterceptor, getCachedAccessToken, isAccessRedirect, resolveCustomHeaders, runCloudflaredLogin } from "../client/cf-access.mjs";
|
|
21
25
|
import { EmDashClient } from "../client/index.mjs";
|
|
22
26
|
import { imageSize } from "image-size";
|
|
@@ -35,10 +39,24 @@ import { packTar } from "modern-tar/fs";
|
|
|
35
39
|
|
|
36
40
|
//#region src/cli/commands/auth.ts
|
|
37
41
|
/**
|
|
38
|
-
* Auth CLI commands
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
*
|
|
42
|
+
* Auth CLI commands (deprecated)
|
|
43
|
+
*
|
|
44
|
+
* Kept as a deprecated alias for backwards compatibility. The original
|
|
45
|
+
* `emdash auth secret` was documented in published docs and is plausibly
|
|
46
|
+
* scripted in user CI (e.g. `npx emdash auth secret >> .env`). Removing
|
|
47
|
+
* it outright would break those scripts on minor-version upgrade.
|
|
48
|
+
*
|
|
49
|
+
* The command still emits an `EMDASH_AUTH_SECRET=<32-byte-base64url>`
|
|
50
|
+
* line, unchanged. `EMDASH_AUTH_SECRET` itself is now legacy: it's only
|
|
51
|
+
* read as a fallback source for the commenter-IP hash salt so installs
|
|
52
|
+
* upgrading from a prior version keep stable IP hashes (and therefore
|
|
53
|
+
* stable rate-limit buckets). New installs don't need to set it.
|
|
54
|
+
*
|
|
55
|
+
* The deprecation note steers users toward `emdash secrets generate`
|
|
56
|
+
* (which emits a different, versioned `emdash_enc_v1_*` value for
|
|
57
|
+
* `EMDASH_ENCRYPTION_KEY` — used to encrypt plugin secrets at rest).
|
|
58
|
+
*
|
|
59
|
+
* Will be removed in a future minor.
|
|
42
60
|
*/
|
|
43
61
|
function generateAuthSecret() {
|
|
44
62
|
const bytes = new Uint8Array(32);
|
|
@@ -48,7 +66,7 @@ function generateAuthSecret() {
|
|
|
48
66
|
const secretCommand = defineCommand({
|
|
49
67
|
meta: {
|
|
50
68
|
name: "secret",
|
|
51
|
-
description: "Generate a
|
|
69
|
+
description: "[DEPRECATED] Generate a value for legacy EMDASH_AUTH_SECRET"
|
|
52
70
|
},
|
|
53
71
|
run() {
|
|
54
72
|
const secret = generateAuthSecret();
|
|
@@ -59,12 +77,13 @@ const secretCommand = defineCommand({
|
|
|
59
77
|
consola$1.log("");
|
|
60
78
|
consola$1.log(pc.dim("Add this to your environment variables."));
|
|
61
79
|
consola$1.log("");
|
|
80
|
+
process.stderr.write(`${pc.yellow("Note:")} ${pc.bold("emdash auth secret")} is deprecated and will be removed in a future minor. ${pc.cyan("EMDASH_AUTH_SECRET")} itself is now optional — it's only used as a legacy fallback for the commenter-IP hash salt. For encrypting plugin secrets at rest, use ${pc.bold("emdash secrets generate")} (a different secret: ${pc.cyan("EMDASH_ENCRYPTION_KEY")}).\n`);
|
|
62
81
|
}
|
|
63
82
|
});
|
|
64
83
|
const authCommand = defineCommand({
|
|
65
84
|
meta: {
|
|
66
85
|
name: "auth",
|
|
67
|
-
description: "Authentication utilities"
|
|
86
|
+
description: "[DEPRECATED] Authentication utilities (use `emdash secrets` for new flows)"
|
|
68
87
|
},
|
|
69
88
|
subCommands: { secret: secretCommand }
|
|
70
89
|
});
|
|
@@ -134,7 +153,10 @@ function readStore() {
|
|
|
134
153
|
return {};
|
|
135
154
|
}
|
|
136
155
|
function writeStore(store) {
|
|
137
|
-
mkdirSync(getConfigDir(), {
|
|
156
|
+
mkdirSync(getConfigDir(), {
|
|
157
|
+
recursive: true,
|
|
158
|
+
mode: 448
|
|
159
|
+
});
|
|
138
160
|
writeFileSync(getCredentialPath(), JSON.stringify(store, null, " "), {
|
|
139
161
|
encoding: "utf-8",
|
|
140
162
|
mode: 384
|
|
@@ -483,7 +505,16 @@ const getCommand$3 = defineCommand({
|
|
|
483
505
|
});
|
|
484
506
|
if (!args.published && item.draftRevisionId) {
|
|
485
507
|
const comparison = await client.compare(args.collection, args.id);
|
|
486
|
-
if (comparison.hasChanges && comparison.draft)
|
|
508
|
+
if (comparison.hasChanges && comparison.draft) {
|
|
509
|
+
item.data = comparison.draft;
|
|
510
|
+
if (!args.raw && item.data) {
|
|
511
|
+
const fields = (await client.collection(args.collection)).fields.map((f) => ({
|
|
512
|
+
slug: f.slug,
|
|
513
|
+
type: f.type
|
|
514
|
+
}));
|
|
515
|
+
item.data = convertDataForRead(item.data, fields, false);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
487
518
|
}
|
|
488
519
|
output(item, args);
|
|
489
520
|
} catch (error) {
|
|
@@ -626,6 +657,7 @@ const deleteCommand$2 = defineCommand({
|
|
|
626
657
|
configureOutputMode(args);
|
|
627
658
|
try {
|
|
628
659
|
await createClientFromArgs(args).delete(args.collection, args.id);
|
|
660
|
+
output({ success: true }, args);
|
|
629
661
|
consola$1.success(`Deleted ${args.collection}/${args.id}`);
|
|
630
662
|
} catch (error) {
|
|
631
663
|
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -655,6 +687,7 @@ const publishCommand$1 = defineCommand({
|
|
|
655
687
|
configureOutputMode(args);
|
|
656
688
|
try {
|
|
657
689
|
await createClientFromArgs(args).publish(args.collection, args.id);
|
|
690
|
+
output({ success: true }, args);
|
|
658
691
|
consola$1.success(`Published ${args.collection}/${args.id}`);
|
|
659
692
|
} catch (error) {
|
|
660
693
|
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -684,6 +717,7 @@ const unpublishCommand = defineCommand({
|
|
|
684
717
|
configureOutputMode(args);
|
|
685
718
|
try {
|
|
686
719
|
await createClientFromArgs(args).unpublish(args.collection, args.id);
|
|
720
|
+
output({ success: true }, args);
|
|
687
721
|
consola$1.success(`Unpublished ${args.collection}/${args.id}`);
|
|
688
722
|
} catch (error) {
|
|
689
723
|
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -718,6 +752,7 @@ const scheduleCommand = defineCommand({
|
|
|
718
752
|
configureOutputMode(args);
|
|
719
753
|
try {
|
|
720
754
|
await createClientFromArgs(args).schedule(args.collection, args.id, { at: args.at });
|
|
755
|
+
output({ success: true }, args);
|
|
721
756
|
consola$1.success(`Scheduled ${args.collection}/${args.id} for ${args.at}`);
|
|
722
757
|
} catch (error) {
|
|
723
758
|
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -747,6 +782,7 @@ const restoreCommand = defineCommand({
|
|
|
747
782
|
configureOutputMode(args);
|
|
748
783
|
try {
|
|
749
784
|
await createClientFromArgs(args).restore(args.collection, args.id);
|
|
785
|
+
output({ success: true }, args);
|
|
750
786
|
consola$1.success(`Restored ${args.collection}/${args.id}`);
|
|
751
787
|
} catch (error) {
|
|
752
788
|
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -1213,49 +1249,88 @@ async function exportCollections(db) {
|
|
|
1213
1249
|
* Export taxonomy definitions and terms
|
|
1214
1250
|
*/
|
|
1215
1251
|
async function exportTaxonomies(db) {
|
|
1216
|
-
const
|
|
1252
|
+
const i18nEnabled = isI18nEnabled();
|
|
1253
|
+
const defs = await db.selectFrom("_emdash_taxonomy_defs").selectAll().orderBy(["name", "locale"]).execute();
|
|
1217
1254
|
const result = [];
|
|
1218
1255
|
const termRepo = new TaxonomyRepository(db);
|
|
1256
|
+
const defGroupToSeedId = /* @__PURE__ */ new Map();
|
|
1219
1257
|
for (const def of defs) {
|
|
1220
|
-
const
|
|
1221
|
-
const
|
|
1258
|
+
const defSeedId = i18nEnabled && def.locale ? `tax:${def.name}:${def.locale}` : `tax:${def.name}`;
|
|
1259
|
+
const terms = await termRepo.findByName(def.name, { locale: def.locale });
|
|
1222
1260
|
const idToSlug = /* @__PURE__ */ new Map();
|
|
1223
1261
|
for (const term of terms) idToSlug.set(term.id, term.slug);
|
|
1262
|
+
const termGroupToSeedId = /* @__PURE__ */ new Map();
|
|
1263
|
+
const seedTerms = [];
|
|
1224
1264
|
for (const term of terms) {
|
|
1265
|
+
const termSeedId = i18nEnabled && term.locale ? `term:${def.name}:${term.slug}:${term.locale}` : `term:${def.name}:${term.slug}`;
|
|
1225
1266
|
const seedTerm = {
|
|
1267
|
+
id: termSeedId,
|
|
1226
1268
|
slug: term.slug,
|
|
1227
1269
|
label: term.label,
|
|
1228
1270
|
description: typeof term.data?.description === "string" ? term.data.description : void 0
|
|
1229
1271
|
};
|
|
1230
1272
|
if (term.parentId) seedTerm.parent = idToSlug.get(term.parentId);
|
|
1273
|
+
if (i18nEnabled && term.locale) {
|
|
1274
|
+
seedTerm.locale = term.locale;
|
|
1275
|
+
if (term.translationGroup) {
|
|
1276
|
+
const anchor = termGroupToSeedId.get(term.translationGroup);
|
|
1277
|
+
if (anchor) seedTerm.translationOf = anchor;
|
|
1278
|
+
else termGroupToSeedId.set(term.translationGroup, termSeedId);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1231
1281
|
seedTerms.push(seedTerm);
|
|
1232
1282
|
}
|
|
1283
|
+
seedTerms.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));
|
|
1233
1284
|
const taxonomy = {
|
|
1285
|
+
id: defSeedId,
|
|
1234
1286
|
name: def.name,
|
|
1235
1287
|
label: def.label,
|
|
1236
1288
|
labelSingular: def.label_singular || void 0,
|
|
1237
1289
|
hierarchical: def.hierarchical === 1,
|
|
1238
1290
|
collections: def.collections ? JSON.parse(def.collections) : []
|
|
1239
1291
|
};
|
|
1292
|
+
if (i18nEnabled && def.locale) {
|
|
1293
|
+
taxonomy.locale = def.locale;
|
|
1294
|
+
if (def.translation_group) {
|
|
1295
|
+
const anchor = defGroupToSeedId.get(def.translation_group);
|
|
1296
|
+
if (anchor) taxonomy.translationOf = anchor;
|
|
1297
|
+
else defGroupToSeedId.set(def.translation_group, defSeedId);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1240
1300
|
if (seedTerms.length > 0) taxonomy.terms = seedTerms;
|
|
1241
1301
|
result.push(taxonomy);
|
|
1242
1302
|
}
|
|
1303
|
+
result.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));
|
|
1243
1304
|
return result;
|
|
1244
1305
|
}
|
|
1245
1306
|
/**
|
|
1246
1307
|
* Export menus with their items
|
|
1247
1308
|
*/
|
|
1248
1309
|
async function exportMenus(db) {
|
|
1249
|
-
const
|
|
1310
|
+
const i18nEnabled = isI18nEnabled();
|
|
1311
|
+
const menus = await db.selectFrom("_emdash_menus").selectAll().orderBy(["name", "locale"]).execute();
|
|
1250
1312
|
const result = [];
|
|
1313
|
+
const groupToSeedId = /* @__PURE__ */ new Map();
|
|
1251
1314
|
for (const menu of menus) {
|
|
1315
|
+
const seedId = i18nEnabled && menu.locale ? `menu:${menu.name}:${menu.locale}` : `menu:${menu.name}`;
|
|
1252
1316
|
const seedItems = buildMenuItemTree(await db.selectFrom("_emdash_menu_items").selectAll().where("menu_id", "=", menu.id).orderBy("sort_order", "asc").execute());
|
|
1253
|
-
|
|
1317
|
+
const seedMenu = {
|
|
1318
|
+
id: seedId,
|
|
1254
1319
|
name: menu.name,
|
|
1255
1320
|
label: menu.label,
|
|
1256
1321
|
items: seedItems
|
|
1257
|
-
}
|
|
1322
|
+
};
|
|
1323
|
+
if (i18nEnabled && menu.locale) {
|
|
1324
|
+
seedMenu.locale = menu.locale;
|
|
1325
|
+
if (menu.translation_group) {
|
|
1326
|
+
const anchor = groupToSeedId.get(menu.translation_group);
|
|
1327
|
+
if (anchor) seedMenu.translationOf = anchor;
|
|
1328
|
+
else groupToSeedId.set(menu.translation_group, seedId);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
result.push(seedMenu);
|
|
1258
1332
|
}
|
|
1333
|
+
result.sort((a, b) => Number(!!a.translationOf) - Number(!!b.translationOf));
|
|
1259
1334
|
return result;
|
|
1260
1335
|
}
|
|
1261
1336
|
/** Type guard for valid widget types */
|
|
@@ -1841,7 +1916,8 @@ const whoamiCommand = defineCommand({
|
|
|
1841
1916
|
})
|
|
1842
1917
|
});
|
|
1843
1918
|
if (refreshRes.ok) {
|
|
1844
|
-
const
|
|
1919
|
+
const json = await refreshRes.json();
|
|
1920
|
+
const refreshed = json.data && typeof json.data === "object" && "access_token" in json.data ? json.data : json;
|
|
1845
1921
|
token = refreshed.access_token;
|
|
1846
1922
|
saveCredentials(baseUrl, {
|
|
1847
1923
|
...cred,
|
|
@@ -2125,8 +2201,16 @@ const MAX_SCREENSHOTS = 5;
|
|
|
2125
2201
|
const MAX_SCREENSHOT_WIDTH = 1920;
|
|
2126
2202
|
const MAX_SCREENSHOT_HEIGHT = 1080;
|
|
2127
2203
|
const ICON_SIZE = 256;
|
|
2128
|
-
/**
|
|
2129
|
-
|
|
2204
|
+
/**
|
|
2205
|
+
* Matches Node.js built-in imports in bundled output:
|
|
2206
|
+
* - require("node:xxx") / require("xxx")
|
|
2207
|
+
* - import("node:xxx") / import("xxx")
|
|
2208
|
+
* - import X from "node:xxx" / import { X } from "node:xxx"
|
|
2209
|
+
* - import * as X from "node:xxx"
|
|
2210
|
+
* - export { X } from "node:xxx"
|
|
2211
|
+
* Captures the base module name (e.g. "fs" from "node:fs/promises").
|
|
2212
|
+
*/
|
|
2213
|
+
const NODE_BUILTIN_IMPORT_RE = /(?:import|export|require)\s*(?:\(|[^(]*?\bfrom\s+)["'](?:node:)?([a-z_]+)(?:\/[^"']*)?\s*["']\)?/g;
|
|
2130
2214
|
const LEADING_DOT_SLASH_RE = /^\.\//;
|
|
2131
2215
|
const DIST_PREFIX_RE = /^dist\//;
|
|
2132
2216
|
const MJS_EXT_RE = /\.m?js$/;
|
|
@@ -2619,8 +2703,18 @@ const bundleCommand = defineCommand({
|
|
|
2619
2703
|
hasErrors = true;
|
|
2620
2704
|
}
|
|
2621
2705
|
}
|
|
2622
|
-
|
|
2623
|
-
|
|
2706
|
+
const declaresUnrestricted = manifest.capabilities.includes("network:request:unrestricted") || manifest.capabilities.includes("network:fetch:any");
|
|
2707
|
+
const declaresHostRestricted = manifest.capabilities.includes("network:request") || manifest.capabilities.includes("network:fetch");
|
|
2708
|
+
if (declaresUnrestricted) consola.warn("Plugin declares unrestricted network access (network:request:unrestricted) — it can make requests to any host");
|
|
2709
|
+
else if (declaresHostRestricted && manifest.allowedHosts.length === 0) consola.warn("Plugin declares network:request capability but no allowedHosts — all requests will be blocked");
|
|
2710
|
+
const deprecatedCaps = manifest.capabilities.filter(isDeprecatedCapability);
|
|
2711
|
+
if (deprecatedCaps.length > 0) {
|
|
2712
|
+
consola.warn("Plugin uses deprecated capability names. Rename them before publishing:");
|
|
2713
|
+
for (const cap of deprecatedCaps) {
|
|
2714
|
+
const replacement = CAPABILITY_RENAMES[cap];
|
|
2715
|
+
consola.warn(` ${cap} → ${replacement}`);
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2624
2718
|
if (resolvedPlugin.admin?.portableTextBlocks && resolvedPlugin.admin.portableTextBlocks.length > 0) consola.warn("Plugin declares portableTextBlocks — these require trusted mode and will be ignored in sandboxed plugins");
|
|
2625
2719
|
if (resolvedPlugin.admin?.entry) consola.warn("Plugin declares admin.entry — custom React components require trusted mode. Use Block Kit for sandboxed admin pages");
|
|
2626
2720
|
if (resolvedPlugin.hooks["page:fragments"]) consola.warn("Plugin declares page:fragments hook — this is trusted-only and will not work in sandboxed mode");
|
|
@@ -2672,13 +2766,15 @@ const bundleCommand = defineCommand({
|
|
|
2672
2766
|
/**
|
|
2673
2767
|
* emdash plugin init
|
|
2674
2768
|
*
|
|
2675
|
-
* Scaffold a new EmDash plugin. Generates the
|
|
2769
|
+
* Scaffold a new EmDash plugin. Generates the sandboxed-format boilerplate:
|
|
2676
2770
|
* src/index.ts -- descriptor factory
|
|
2677
2771
|
* src/sandbox-entry.ts -- definePlugin({ hooks, routes })
|
|
2678
2772
|
* package.json
|
|
2679
2773
|
* tsconfig.json
|
|
2680
2774
|
*
|
|
2681
|
-
* Use --native to generate native-format boilerplate
|
|
2775
|
+
* Use --format=native (or --native) to generate native-format boilerplate
|
|
2776
|
+
* instead (createPlugin + React admin). When neither is passed and stdout
|
|
2777
|
+
* is a TTY, the user is prompted to choose.
|
|
2682
2778
|
*
|
|
2683
2779
|
*/
|
|
2684
2780
|
const SLUG_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
@@ -2698,15 +2794,25 @@ const pluginInitCommand = defineCommand({
|
|
|
2698
2794
|
type: "string",
|
|
2699
2795
|
description: "Plugin name/id (e.g. my-plugin or @org/my-plugin)"
|
|
2700
2796
|
},
|
|
2797
|
+
format: {
|
|
2798
|
+
type: "string",
|
|
2799
|
+
description: "Plugin format: sandboxed or native. Prompts when running interactively if not set.",
|
|
2800
|
+
valueHint: "sandboxed|native"
|
|
2801
|
+
},
|
|
2701
2802
|
native: {
|
|
2702
2803
|
type: "boolean",
|
|
2703
|
-
description: "
|
|
2804
|
+
description: "Shortcut for --format=native",
|
|
2704
2805
|
default: false
|
|
2705
2806
|
}
|
|
2706
2807
|
},
|
|
2707
2808
|
async run({ args }) {
|
|
2708
2809
|
const targetDir = resolve(args.dir);
|
|
2709
|
-
const
|
|
2810
|
+
const format = await resolveFormat(args.format, args.native);
|
|
2811
|
+
if (!format) {
|
|
2812
|
+
consola.info("Cancelled");
|
|
2813
|
+
return;
|
|
2814
|
+
}
|
|
2815
|
+
const isNative = format === "native";
|
|
2710
2816
|
let pluginName = args.name || basename(targetDir);
|
|
2711
2817
|
if (!pluginName || pluginName === ".") pluginName = basename(resolve("."));
|
|
2712
2818
|
const slug = pluginName.replace(SCOPE_RE, "");
|
|
@@ -2719,69 +2825,162 @@ const pluginInitCommand = defineCommand({
|
|
|
2719
2825
|
consola.error(`package.json already exists in ${targetDir}`);
|
|
2720
2826
|
process.exit(1);
|
|
2721
2827
|
}
|
|
2722
|
-
consola.start(`Scaffolding ${isNative ? "native" : "
|
|
2828
|
+
consola.start(`Scaffolding ${isNative ? "native" : "sandboxed"} plugin: ${pluginName}`);
|
|
2723
2829
|
await mkdir(srcDir, { recursive: true });
|
|
2724
2830
|
if (isNative) await scaffoldNative(targetDir, srcDir, pluginName, slug);
|
|
2725
2831
|
else await scaffoldStandard(targetDir, srcDir, pluginName, slug);
|
|
2726
2832
|
consola.success(`Plugin scaffolded in ${targetDir}`);
|
|
2727
2833
|
consola.info("Next steps:");
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2834
|
+
const steps = [];
|
|
2835
|
+
if (args.dir !== ".") steps.push(`cd ${args.dir}`);
|
|
2836
|
+
steps.push("pnpm install");
|
|
2837
|
+
steps.push(isNative ? "Edit src/index.ts to add hooks and routes" : "Edit src/sandbox-entry.ts to add hooks and routes");
|
|
2838
|
+
steps.push("pnpm build");
|
|
2839
|
+
if (!isNative) steps.push("emdash plugin validate --dir .");
|
|
2840
|
+
steps.forEach((step, i) => consola.info(` ${i + 1}. ${step}`));
|
|
2733
2841
|
}
|
|
2734
2842
|
});
|
|
2843
|
+
async function resolveFormat(formatArg, nativeFlag) {
|
|
2844
|
+
if (formatArg) {
|
|
2845
|
+
const normalized = formatArg.toLowerCase();
|
|
2846
|
+
let parsed;
|
|
2847
|
+
if (normalized === "native") parsed = "native";
|
|
2848
|
+
else if (normalized === "sandboxed" || normalized === "standard") parsed = "standard";
|
|
2849
|
+
else {
|
|
2850
|
+
consola.error(`Invalid --format "${formatArg}". Use "sandboxed" or "native".`);
|
|
2851
|
+
process.exit(1);
|
|
2852
|
+
}
|
|
2853
|
+
if (nativeFlag && parsed !== "native") {
|
|
2854
|
+
consola.error(`Conflicting flags: --native and --format=${formatArg}. Pass only one.`);
|
|
2855
|
+
process.exit(1);
|
|
2856
|
+
}
|
|
2857
|
+
return parsed;
|
|
2858
|
+
}
|
|
2859
|
+
if (nativeFlag) return "native";
|
|
2860
|
+
if (!process.stdout.isTTY) return "standard";
|
|
2861
|
+
const choice = await consola.prompt("Which plugin format?", {
|
|
2862
|
+
type: "select",
|
|
2863
|
+
initial: "standard",
|
|
2864
|
+
options: [{
|
|
2865
|
+
label: "Sandboxed",
|
|
2866
|
+
value: "standard",
|
|
2867
|
+
hint: "runs in an isolated sandbox; safe to install from the marketplace"
|
|
2868
|
+
}, {
|
|
2869
|
+
label: "Native",
|
|
2870
|
+
value: "native",
|
|
2871
|
+
hint: "full runtime access; install from npm"
|
|
2872
|
+
}],
|
|
2873
|
+
cancel: "null"
|
|
2874
|
+
});
|
|
2875
|
+
if (choice === null) return null;
|
|
2876
|
+
return choice;
|
|
2877
|
+
}
|
|
2878
|
+
function camelCase(slug) {
|
|
2879
|
+
return slug.split("-").map((s, i) => i === 0 ? s : s[0].toUpperCase() + s.slice(1)).join("");
|
|
2880
|
+
}
|
|
2881
|
+
function pascalCase(slug) {
|
|
2882
|
+
return slug.split("-").map((s) => s[0].toUpperCase() + s.slice(1)).join("");
|
|
2883
|
+
}
|
|
2884
|
+
const TSCONFIG = {
|
|
2885
|
+
compilerOptions: {
|
|
2886
|
+
target: "ES2022",
|
|
2887
|
+
module: "preserve",
|
|
2888
|
+
moduleResolution: "bundler",
|
|
2889
|
+
strict: true,
|
|
2890
|
+
esModuleInterop: true,
|
|
2891
|
+
declaration: true,
|
|
2892
|
+
outDir: "./dist",
|
|
2893
|
+
rootDir: "./src"
|
|
2894
|
+
},
|
|
2895
|
+
include: ["src/**/*"],
|
|
2896
|
+
exclude: ["node_modules", "dist"]
|
|
2897
|
+
};
|
|
2898
|
+
const TSDOWN_VERSION = "^0.20.0";
|
|
2899
|
+
const TYPESCRIPT_VERSION = "^5.9.0";
|
|
2735
2900
|
async function scaffoldStandard(targetDir, srcDir, pluginName, slug) {
|
|
2736
|
-
const fnName = slug
|
|
2901
|
+
const fnName = camelCase(slug);
|
|
2737
2902
|
await writeFile(join(targetDir, "package.json"), JSON.stringify({
|
|
2738
2903
|
name: pluginName,
|
|
2739
2904
|
version: "0.1.0",
|
|
2740
2905
|
type: "module",
|
|
2906
|
+
main: "./dist/index.mjs",
|
|
2741
2907
|
exports: {
|
|
2742
|
-
".":
|
|
2743
|
-
|
|
2908
|
+
".": {
|
|
2909
|
+
types: "./dist/index.d.mts",
|
|
2910
|
+
import: "./dist/index.mjs"
|
|
2911
|
+
},
|
|
2912
|
+
"./sandbox": {
|
|
2913
|
+
types: "./dist/sandbox-entry.d.mts",
|
|
2914
|
+
import: "./dist/sandbox-entry.mjs"
|
|
2915
|
+
}
|
|
2744
2916
|
},
|
|
2745
|
-
files: ["
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
}
|
|
2759
|
-
include: ["src/**/*"],
|
|
2760
|
-
exclude: ["node_modules", "dist"]
|
|
2917
|
+
files: ["dist"],
|
|
2918
|
+
scripts: {
|
|
2919
|
+
build: "tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --clean",
|
|
2920
|
+
dev: "tsdown src/index.ts src/sandbox-entry.ts --format esm --dts --watch",
|
|
2921
|
+
typecheck: "tsc --noEmit"
|
|
2922
|
+
},
|
|
2923
|
+
keywords: ["emdash", "emdash-plugin"],
|
|
2924
|
+
license: "MIT",
|
|
2925
|
+
peerDependencies: { emdash: "*" },
|
|
2926
|
+
devDependencies: {
|
|
2927
|
+
emdash: "*",
|
|
2928
|
+
tsdown: TSDOWN_VERSION,
|
|
2929
|
+
typescript: TYPESCRIPT_VERSION
|
|
2930
|
+
}
|
|
2761
2931
|
}, null, " ") + "\n");
|
|
2932
|
+
await writeFile(join(targetDir, "tsconfig.json"), JSON.stringify(TSCONFIG, null, " ") + "\n");
|
|
2762
2933
|
await writeFile(join(srcDir, "index.ts"), `import type { PluginDescriptor } from "emdash";
|
|
2763
2934
|
|
|
2764
2935
|
export function ${fnName}Plugin(): PluginDescriptor {
|
|
2765
2936
|
\treturn {
|
|
2766
|
-
\t\tid: "${
|
|
2937
|
+
\t\tid: "${slug}",
|
|
2767
2938
|
\t\tversion: "0.1.0",
|
|
2768
2939
|
\t\tformat: "standard",
|
|
2769
2940
|
\t\tentrypoint: "${pluginName}/sandbox",
|
|
2770
|
-
|
|
2941
|
+
|
|
2942
|
+
\t\tcapabilities: ["content:read"],
|
|
2943
|
+
\t\tstorage: {
|
|
2944
|
+
\t\t\tevents: { indexes: ["timestamp"] },
|
|
2945
|
+
\t\t},
|
|
2771
2946
|
\t};
|
|
2772
2947
|
}
|
|
2773
2948
|
`);
|
|
2774
2949
|
await writeFile(join(srcDir, "sandbox-entry.ts"), `import { definePlugin } from "emdash";
|
|
2775
2950
|
import type { PluginContext } from "emdash";
|
|
2776
2951
|
|
|
2952
|
+
interface ContentSaveEvent {
|
|
2953
|
+
\tcollection: string;
|
|
2954
|
+
\tcontent: { id: string };
|
|
2955
|
+
\tisNew: boolean;
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2777
2958
|
export default definePlugin({
|
|
2778
2959
|
\thooks: {
|
|
2779
2960
|
\t\t"content:afterSave": {
|
|
2780
|
-
\t\t\thandler: async (event:
|
|
2961
|
+
\t\t\thandler: async (event: ContentSaveEvent, ctx: PluginContext) => {
|
|
2781
2962
|
\t\t\t\tctx.log.info("Content saved", {
|
|
2782
2963
|
\t\t\t\t\tcollection: event.collection,
|
|
2783
2964
|
\t\t\t\t\tid: event.content.id,
|
|
2784
2965
|
\t\t\t\t});
|
|
2966
|
+
|
|
2967
|
+
\t\t\t\tawait ctx.storage.events.put(\`save-\${Date.now()}\`, {
|
|
2968
|
+
\t\t\t\t\ttimestamp: new Date().toISOString(),
|
|
2969
|
+
\t\t\t\t\tcollection: event.collection,
|
|
2970
|
+
\t\t\t\t\tcontentId: event.content.id,
|
|
2971
|
+
\t\t\t\t});
|
|
2972
|
+
\t\t\t},
|
|
2973
|
+
\t\t},
|
|
2974
|
+
\t},
|
|
2975
|
+
|
|
2976
|
+
\troutes: {
|
|
2977
|
+
\t\trecent: {
|
|
2978
|
+
\t\t\thandler: async (_routeCtx, ctx: PluginContext) => {
|
|
2979
|
+
\t\t\t\tconst result = await ctx.storage.events.query({
|
|
2980
|
+
\t\t\t\t\torderBy: { timestamp: "desc" },
|
|
2981
|
+
\t\t\t\t\tlimit: 10,
|
|
2982
|
+
\t\t\t\t});
|
|
2983
|
+
\t\t\t\treturn { events: result.items };
|
|
2785
2984
|
\t\t\t},
|
|
2786
2985
|
\t\t},
|
|
2787
2986
|
\t},
|
|
@@ -2789,55 +2988,82 @@ export default definePlugin({
|
|
|
2789
2988
|
`);
|
|
2790
2989
|
}
|
|
2791
2990
|
async function scaffoldNative(targetDir, srcDir, pluginName, slug) {
|
|
2792
|
-
const fnName = slug
|
|
2991
|
+
const fnName = camelCase(slug);
|
|
2992
|
+
const typeName = pascalCase(slug);
|
|
2793
2993
|
await writeFile(join(targetDir, "package.json"), JSON.stringify({
|
|
2794
2994
|
name: pluginName,
|
|
2795
2995
|
version: "0.1.0",
|
|
2796
2996
|
type: "module",
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2997
|
+
main: "./dist/index.mjs",
|
|
2998
|
+
exports: { ".": {
|
|
2999
|
+
types: "./dist/index.d.mts",
|
|
3000
|
+
import: "./dist/index.mjs"
|
|
3001
|
+
} },
|
|
3002
|
+
files: ["dist"],
|
|
3003
|
+
scripts: {
|
|
3004
|
+
build: "tsdown src/index.ts --format esm --dts --clean",
|
|
3005
|
+
dev: "tsdown src/index.ts --format esm --dts --watch",
|
|
3006
|
+
typecheck: "tsc --noEmit"
|
|
3007
|
+
},
|
|
3008
|
+
keywords: ["emdash", "emdash-plugin"],
|
|
3009
|
+
license: "MIT",
|
|
3010
|
+
peerDependencies: { emdash: "*" },
|
|
3011
|
+
devDependencies: {
|
|
3012
|
+
emdash: "*",
|
|
3013
|
+
tsdown: TSDOWN_VERSION,
|
|
3014
|
+
typescript: TYPESCRIPT_VERSION
|
|
3015
|
+
}
|
|
2814
3016
|
}, null, " ") + "\n");
|
|
3017
|
+
await writeFile(join(targetDir, "tsconfig.json"), JSON.stringify(TSCONFIG, null, " ") + "\n");
|
|
2815
3018
|
await writeFile(join(srcDir, "index.ts"), `import { definePlugin } from "emdash";
|
|
2816
3019
|
import type { PluginDescriptor } from "emdash";
|
|
2817
3020
|
|
|
2818
|
-
export
|
|
3021
|
+
export interface ${typeName}Options {
|
|
3022
|
+
\tenabled?: boolean;
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
export function ${fnName}Plugin(options: ${typeName}Options = {}): PluginDescriptor<${typeName}Options> {
|
|
2819
3026
|
\treturn {
|
|
2820
|
-
\t\tid: "${
|
|
3027
|
+
\t\tid: "${slug}",
|
|
2821
3028
|
\t\tversion: "0.1.0",
|
|
2822
3029
|
\t\tformat: "native",
|
|
2823
3030
|
\t\tentrypoint: "${pluginName}",
|
|
2824
|
-
\t\toptions
|
|
3031
|
+
\t\toptions,
|
|
2825
3032
|
\t};
|
|
2826
3033
|
}
|
|
2827
3034
|
|
|
2828
|
-
export function createPlugin() {
|
|
3035
|
+
export function createPlugin(options: ${typeName}Options = {}) {
|
|
2829
3036
|
\treturn definePlugin({
|
|
2830
|
-
\t\tid: "${
|
|
3037
|
+
\t\tid: "${slug}",
|
|
2831
3038
|
\t\tversion: "0.1.0",
|
|
2832
3039
|
|
|
3040
|
+
\t\tcapabilities: ["content:read"],
|
|
3041
|
+
\t\tstorage: {
|
|
3042
|
+
\t\t\tevents: { indexes: ["createdAt"] },
|
|
3043
|
+
\t\t},
|
|
3044
|
+
|
|
2833
3045
|
\t\thooks: {
|
|
2834
3046
|
\t\t\t"content:afterSave": async (event, ctx) => {
|
|
2835
|
-
\t\t\t\
|
|
3047
|
+
\t\t\t\tif (options.enabled === false) return;
|
|
3048
|
+
\t\t\t\tawait ctx.storage.events.put(\`evt_\${Date.now()}\`, {
|
|
2836
3049
|
\t\t\t\t\tcollection: event.collection,
|
|
2837
|
-
\t\t\t\t\
|
|
3050
|
+
\t\t\t\t\tcontentId: event.content.id,
|
|
3051
|
+
\t\t\t\t\tcreatedAt: new Date().toISOString(),
|
|
2838
3052
|
\t\t\t\t});
|
|
2839
3053
|
\t\t\t},
|
|
2840
3054
|
\t\t},
|
|
3055
|
+
|
|
3056
|
+
\t\troutes: {
|
|
3057
|
+
\t\t\trecent: {
|
|
3058
|
+
\t\t\t\thandler: async (ctx) => {
|
|
3059
|
+
\t\t\t\t\tconst result = await ctx.storage.events.query({
|
|
3060
|
+
\t\t\t\t\t\torderBy: { createdAt: "desc" },
|
|
3061
|
+
\t\t\t\t\t\tlimit: 10,
|
|
3062
|
+
\t\t\t\t\t});
|
|
3063
|
+
\t\t\t\t\treturn { events: result.items };
|
|
3064
|
+
\t\t\t\t},
|
|
3065
|
+
\t\t\t},
|
|
3066
|
+
\t\t},
|
|
2841
3067
|
\t});
|
|
2842
3068
|
}
|
|
2843
3069
|
|
|
@@ -3115,6 +3341,16 @@ const publishCommand = defineCommand({
|
|
|
3115
3341
|
if (manifest.capabilities.length > 0) consola.info(`Capabilities: ${manifest.capabilities.join(", ")}`);
|
|
3116
3342
|
if (manifest.allowedHosts?.length) consola.info(`Allowed hosts: ${manifest.allowedHosts.join(", ")}`);
|
|
3117
3343
|
console.log();
|
|
3344
|
+
const deprecatedCaps = manifest.capabilities.filter(isDeprecatedCapability);
|
|
3345
|
+
if (deprecatedCaps.length > 0) {
|
|
3346
|
+
consola.error("Plugin declares deprecated capability names. Rename them and re-bundle before publishing:");
|
|
3347
|
+
for (const cap of deprecatedCaps) {
|
|
3348
|
+
const replacement = CAPABILITY_RENAMES[cap];
|
|
3349
|
+
consola.error(` ${cap} → ${replacement}`);
|
|
3350
|
+
}
|
|
3351
|
+
consola.error("See https://emdashcms.com/docs/plugins/overview#capabilities for the full rename table.");
|
|
3352
|
+
process.exit(1);
|
|
3353
|
+
}
|
|
3118
3354
|
let token;
|
|
3119
3355
|
const envToken = process.env.EMDASH_MARKETPLACE_TOKEN;
|
|
3120
3356
|
const stored = !envToken ? getMarketplaceCredential(registryUrl) : null;
|
|
@@ -3572,6 +3808,134 @@ const searchCommand = defineCommand({
|
|
|
3572
3808
|
}
|
|
3573
3809
|
});
|
|
3574
3810
|
|
|
3811
|
+
//#endregion
|
|
3812
|
+
//#region src/cli/commands/secrets.ts
|
|
3813
|
+
/**
|
|
3814
|
+
* Secrets CLI commands
|
|
3815
|
+
*
|
|
3816
|
+
* Pure (no-DB) commands for working with EmDash secrets:
|
|
3817
|
+
*
|
|
3818
|
+
* - `emdash secrets generate` — emits a fresh `EMDASH_ENCRYPTION_KEY`.
|
|
3819
|
+
* Optionally writes it to `.dev.vars` (Workers) or `.env` (Node).
|
|
3820
|
+
* - `emdash secrets fingerprint <key>` — prints the kid for a key,
|
|
3821
|
+
* useful in CI for verifying what's been deployed without exposing
|
|
3822
|
+
* the raw value.
|
|
3823
|
+
*
|
|
3824
|
+
* DB-touching commands (`status`, `migrate`, `rotate`) live elsewhere:
|
|
3825
|
+
* the CLI process can't open the production D1/Postgres binding from
|
|
3826
|
+
* the operator's machine, so those operations ship as admin HTTP
|
|
3827
|
+
* endpoints in a later PR. A thin `--site <url>` wrapper for those
|
|
3828
|
+
* endpoints can land alongside.
|
|
3829
|
+
*/
|
|
3830
|
+
const KEY_VAR_NAME = "EMDASH_ENCRYPTION_KEY";
|
|
3831
|
+
/** Matches a populated entry — `KEY=<at least one char>`. */
|
|
3832
|
+
const POPULATED_KEY_LINE_PATTERN = /^EMDASH_ENCRYPTION_KEY=.+$/m;
|
|
3833
|
+
/**
|
|
3834
|
+
* Matches any line starting `KEY=` including `KEY=` with empty value.
|
|
3835
|
+
* Used for in-place replacement when the entry exists but has no value.
|
|
3836
|
+
*/
|
|
3837
|
+
const ANY_KEY_LINE_PATTERN = /^EMDASH_ENCRYPTION_KEY=.*$/m;
|
|
3838
|
+
/**
|
|
3839
|
+
* Append (or replace) `EMDASH_ENCRYPTION_KEY` in a dotenv-style file.
|
|
3840
|
+
*
|
|
3841
|
+
* Idempotent: if the entry exists with a populated value, leaves it alone
|
|
3842
|
+
* (returns `"skipped"`) unless `force` is set. An entry with an empty
|
|
3843
|
+
* value (`EMDASH_ENCRYPTION_KEY=`) is treated as "not set" and gets
|
|
3844
|
+
* replaced — placeholder lines aren't a reason to refuse.
|
|
3845
|
+
*
|
|
3846
|
+
* Always ends the resulting file with a trailing newline. Doesn't touch
|
|
3847
|
+
* other variables.
|
|
3848
|
+
*
|
|
3849
|
+
* Exported for tests.
|
|
3850
|
+
*/
|
|
3851
|
+
function writeEncryptionKeyToFile(targetPath, value, force) {
|
|
3852
|
+
const existing = existsSync(targetPath) ? readFileSync(targetPath, "utf-8") : "";
|
|
3853
|
+
if (POPULATED_KEY_LINE_PATTERN.test(existing) && !force) return "skipped";
|
|
3854
|
+
const newLine = `${KEY_VAR_NAME}=${value}`;
|
|
3855
|
+
let next;
|
|
3856
|
+
if (ANY_KEY_LINE_PATTERN.test(existing)) {
|
|
3857
|
+
next = existing.replace(ANY_KEY_LINE_PATTERN, newLine);
|
|
3858
|
+
if (!next.endsWith("\n")) next += "\n";
|
|
3859
|
+
} else next = `${existing}${existing.length === 0 ? "" : existing.endsWith("\n") ? "" : "\n"}${newLine}\n`;
|
|
3860
|
+
writeFileSync(targetPath, next);
|
|
3861
|
+
return "wrote";
|
|
3862
|
+
}
|
|
3863
|
+
const generateCommand = defineCommand({
|
|
3864
|
+
meta: {
|
|
3865
|
+
name: "generate",
|
|
3866
|
+
description: "Generate a new EmDash encryption key"
|
|
3867
|
+
},
|
|
3868
|
+
args: {
|
|
3869
|
+
write: {
|
|
3870
|
+
type: "string",
|
|
3871
|
+
description: "Optional path to write the key to (e.g. .dev.vars or .env). Won't overwrite an existing entry without --force."
|
|
3872
|
+
},
|
|
3873
|
+
force: {
|
|
3874
|
+
type: "boolean",
|
|
3875
|
+
description: "When used with --write, overwrite an existing entry",
|
|
3876
|
+
default: false
|
|
3877
|
+
}
|
|
3878
|
+
},
|
|
3879
|
+
run({ args }) {
|
|
3880
|
+
const value = generateEncryptionKey();
|
|
3881
|
+
if (args.write) {
|
|
3882
|
+
if (writeEncryptionKeyToFile(resolve(process.cwd(), args.write), value, args.force) === "skipped") {
|
|
3883
|
+
consola$1.info(`${KEY_VAR_NAME} already set in ${pc.cyan(args.write)}; leaving it alone. Pass ${pc.bold("--force")} to replace it.`);
|
|
3884
|
+
return;
|
|
3885
|
+
}
|
|
3886
|
+
consola$1.log("");
|
|
3887
|
+
consola$1.log(`${pc.bold("Wrote")} ${pc.cyan(KEY_VAR_NAME)} to ${pc.cyan(args.write)}`);
|
|
3888
|
+
consola$1.log("");
|
|
3889
|
+
consola$1.log(pc.yellow("Keep this file out of version control. Losing the key means losing every secret encrypted with it."));
|
|
3890
|
+
consola$1.log("");
|
|
3891
|
+
return;
|
|
3892
|
+
}
|
|
3893
|
+
process.stdout.write(`${value}\n`);
|
|
3894
|
+
const guidance = [
|
|
3895
|
+
"",
|
|
3896
|
+
pc.bold("EmDash encryption key generated."),
|
|
3897
|
+
"",
|
|
3898
|
+
`Set ${pc.cyan(KEY_VAR_NAME)} in your environment.`,
|
|
3899
|
+
"For Cloudflare deployments, push it to your Worker's secrets.",
|
|
3900
|
+
"For Node deployments, add it to your process environment or .env file.",
|
|
3901
|
+
"",
|
|
3902
|
+
pc.yellow("Keep this value secret. Losing it means losing every secret encrypted with it."),
|
|
3903
|
+
""
|
|
3904
|
+
].join("\n");
|
|
3905
|
+
process.stderr.write(`${guidance}\n`);
|
|
3906
|
+
}
|
|
3907
|
+
});
|
|
3908
|
+
const fingerprintCommand = defineCommand({
|
|
3909
|
+
meta: {
|
|
3910
|
+
name: "fingerprint",
|
|
3911
|
+
description: "Print the kid (8-char fingerprint) for an encryption key"
|
|
3912
|
+
},
|
|
3913
|
+
args: { key: {
|
|
3914
|
+
type: "positional",
|
|
3915
|
+
description: "The full key value (with the emdash_enc_v1_ prefix)",
|
|
3916
|
+
required: true
|
|
3917
|
+
} },
|
|
3918
|
+
async run({ args }) {
|
|
3919
|
+
try {
|
|
3920
|
+
const kid = await fingerprintKey(args.key);
|
|
3921
|
+
process.stdout.write(`${kid}\n`);
|
|
3922
|
+
} catch (error) {
|
|
3923
|
+
consola$1.error(error instanceof EmDashSecretsError ? error.message : "Failed to fingerprint key");
|
|
3924
|
+
process.exit(1);
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
});
|
|
3928
|
+
const secretsCommand = defineCommand({
|
|
3929
|
+
meta: {
|
|
3930
|
+
name: "secrets",
|
|
3931
|
+
description: "Manage EmDash secrets (generate, inspect)"
|
|
3932
|
+
},
|
|
3933
|
+
subCommands: {
|
|
3934
|
+
generate: generateCommand,
|
|
3935
|
+
fingerprint: fingerprintCommand
|
|
3936
|
+
}
|
|
3937
|
+
});
|
|
3938
|
+
|
|
3575
3939
|
//#endregion
|
|
3576
3940
|
//#region src/cli/commands/seed.ts
|
|
3577
3941
|
/**
|
|
@@ -3934,7 +4298,8 @@ const typesCommand = defineCommand({
|
|
|
3934
4298
|
* - dev: Run dev server with local D1
|
|
3935
4299
|
* - seed: Apply a seed file to the database
|
|
3936
4300
|
* - export-seed: Export database schema and content as a seed file
|
|
3937
|
-
* -
|
|
4301
|
+
* - secrets: Generate and inspect EmDash secrets (encryption keys, etc.)
|
|
4302
|
+
* - auth: [DEPRECATED] Generate auth secret (use `secrets` instead)
|
|
3938
4303
|
* - login/logout/whoami: Session management
|
|
3939
4304
|
* - content: Create, read, update, delete content
|
|
3940
4305
|
* - schema: Manage collections and fields
|
|
@@ -3957,6 +4322,7 @@ runMain(defineCommand({
|
|
|
3957
4322
|
doctor: doctorCommand,
|
|
3958
4323
|
seed: seedCommand,
|
|
3959
4324
|
"export-seed": exportSeedCommand,
|
|
4325
|
+
secrets: secretsCommand,
|
|
3960
4326
|
auth: authCommand,
|
|
3961
4327
|
login: loginCommand,
|
|
3962
4328
|
logout: logoutCommand,
|