dineway 0.1.45 → 0.1.47
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/{activity-events-CpcTzKpF.mjs → activity-events-CNk3clTT.mjs} +1 -1
- package/dist/{allowed-origins-3RuuoFjC.mjs → allowed-origins-QirBXiDj.mjs} +1 -1
- package/dist/api/route-utils.d.mts +9 -10
- package/dist/api/route-utils.mjs +13 -13
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +4 -4
- package/dist/{api-DkFSCD74.mjs → api-ePsOhL3q.mjs} +101 -56
- package/dist/{api-tokens-BFg7tiOQ.mjs → api-tokens-DtvdtIkm.mjs} +1 -1
- package/dist/{apply-TIoQ00aH.mjs → apply-BpRBCqUt.mjs} +76 -31
- package/dist/astro/index.d.mts +10 -11
- package/dist/astro/index.mjs +23 -3
- package/dist/astro/middleware/auth.d.mts +9 -10
- package/dist/astro/middleware/auth.mjs +5 -5
- package/dist/astro/middleware/redirect.mjs +13 -7
- package/dist/astro/middleware/request-context.mjs +3 -3
- package/dist/astro/middleware/seed.d.mts +1 -1
- package/dist/astro/middleware/seed.mjs +2 -2
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.mjs +120 -82
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +5 -5
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +4 -4
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +6 -6
- package/dist/astro/routes/api/admin/briefing.mjs +17 -17
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.d.mts +7 -0
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +17 -0
- package/dist/astro/routes/api/admin/byline-fields/_slug_.d.mts +9 -0
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +38 -0
- package/dist/astro/routes/api/admin/byline-fields/index.d.mts +8 -0
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +31 -0
- package/dist/astro/routes/api/admin/byline-fields/reorder.d.mts +7 -0
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +24 -0
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +27 -27
- package/dist/astro/routes/api/admin/bylines/_id_/translations.d.mts +8 -0
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +57 -0
- package/dist/astro/routes/api/admin/bylines/index.mjs +30 -26
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +11 -11
- package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/bulk.mjs +9 -9
- package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
- package/dist/astro/routes/api/admin/comments/index.mjs +9 -9
- package/dist/astro/routes/api/admin/context/_id_/history.mjs +23 -23
- package/dist/astro/routes/api/admin/context/_id_/index.mjs +23 -23
- package/dist/astro/routes/api/admin/context/_id_/review.mjs +27 -27
- package/dist/astro/routes/api/admin/context/_id_/supersede.mjs +27 -27
- package/dist/astro/routes/api/admin/context/diff.mjs +26 -26
- package/dist/astro/routes/api/admin/context/index.mjs +27 -27
- package/dist/astro/routes/api/admin/context/stale.mjs +26 -26
- package/dist/astro/routes/api/admin/hitl-requests/_id_/index.mjs +23 -23
- package/dist/astro/routes/api/admin/hitl-requests/_id_/resolve.mjs +26 -26
- package/dist/astro/routes/api/admin/hitl-requests/index.mjs +26 -26
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +24 -24
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +2 -2
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +48 -44
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +48 -44
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +42 -38
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +47 -43
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +47 -43
- package/dist/astro/routes/api/admin/plugins/index.mjs +42 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +42 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +47 -43
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +42 -38
- package/dist/astro/routes/api/admin/plugins/updates.mjs +42 -38
- package/dist/astro/routes/api/admin/review-requests/_id_/index.mjs +5 -5
- package/dist/astro/routes/api/admin/review-requests/_id_/resolve.mjs +26 -26
- package/dist/astro/routes/api/admin/review-requests/index.mjs +9 -9
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +42 -38
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +42 -38
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +1 -1
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +5 -5
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
- package/dist/astro/routes/api/admin/users/index.mjs +5 -5
- package/dist/astro/routes/api/auth/dev-bypass.mjs +5 -5
- package/dist/astro/routes/api/auth/invite/accept.mjs +1 -1
- package/dist/astro/routes/api/auth/invite/complete.mjs +9 -9
- package/dist/astro/routes/api/auth/invite/index.mjs +6 -6
- package/dist/astro/routes/api/auth/invite/register-options.mjs +8 -8
- package/dist/astro/routes/api/auth/logout.mjs +2 -2
- package/dist/astro/routes/api/auth/magic-link/send.mjs +8 -8
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/me.mjs +20 -11
- package/dist/astro/routes/api/auth/mode.mjs +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +2 -2
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +2 -2
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +5 -5
- package/dist/astro/routes/api/auth/passkey/index.mjs +1 -1
- package/dist/astro/routes/api/auth/passkey/options.mjs +10 -10
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +8 -8
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +9 -9
- package/dist/astro/routes/api/auth/passkey/verify.mjs +9 -9
- package/dist/astro/routes/api/auth/setup-token/index.mjs +5 -5
- package/dist/astro/routes/api/auth/setup-token/verify.mjs +2 -2
- package/dist/astro/routes/api/auth/signup/complete.mjs +9 -9
- package/dist/astro/routes/api/auth/signup/request.mjs +8 -8
- package/dist/astro/routes/api/auth/signup/verify.mjs +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +12 -12
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +11 -11
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +20 -14
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +12 -10
- package/dist/astro/routes/api/content/_collection_/index.mjs +9 -9
- package/dist/astro/routes/api/content/_collection_/trash.mjs +6 -6
- package/dist/astro/routes/api/dashboard.mjs +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +2 -2
- package/dist/astro/routes/api/health.mjs +1 -1
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +7 -7
- package/dist/astro/routes/api/import/wordpress/execute.mjs +29 -28
- package/dist/astro/routes/api/import/wordpress/media.mjs +10 -10
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +31 -31
- package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.d.mts +5 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-url-helpers.mjs +16 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +30 -30
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +13 -13
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +31 -30
- package/dist/astro/routes/api/manifest.mjs +4 -4
- package/dist/astro/routes/api/mcp.mjs +75 -50
- package/dist/astro/routes/api/media/_id_/confirm.mjs +8 -8
- package/dist/astro/routes/api/media/_id_.mjs +6 -6
- package/dist/astro/routes/api/media/file/_...key_.mjs +1 -1
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +2 -2
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +2 -2
- package/dist/astro/routes/api/media/providers/index.mjs +2 -2
- package/dist/astro/routes/api/media/upload-url.mjs +10 -10
- package/dist/astro/routes/api/media.mjs +14 -13
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +27 -27
- package/dist/astro/routes/api/menus/_name_/items.mjs +27 -27
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +27 -27
- package/dist/astro/routes/api/menus/_name_/translations.mjs +27 -27
- package/dist/astro/routes/api/menus/_name_.mjs +27 -27
- package/dist/astro/routes/api/menus/index.mjs +27 -27
- package/dist/astro/routes/api/oauth/authorize.mjs +7 -7
- package/dist/astro/routes/api/oauth/device/authorize.mjs +6 -6
- package/dist/astro/routes/api/oauth/device/code.mjs +9 -9
- package/dist/astro/routes/api/oauth/device/token.mjs +8 -8
- package/dist/astro/routes/api/oauth/register.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/refresh.mjs +6 -6
- package/dist/astro/routes/api/oauth/token/revoke.mjs +6 -6
- package/dist/astro/routes/api/oauth/token.mjs +6 -6
- package/dist/astro/routes/api/openapi.json.mjs +10 -7
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
- package/dist/astro/routes/api/redirects/404s/index.mjs +10 -10
- package/dist/astro/routes/api/redirects/404s/summary.mjs +10 -10
- package/dist/astro/routes/api/redirects/_id_.mjs +28 -28
- package/dist/astro/routes/api/redirects/index.mjs +28 -28
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +2 -2
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +2 -2
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +43 -39
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +43 -39
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +43 -39
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +43 -39
- package/dist/astro/routes/api/schema/collections/index.mjs +43 -39
- package/dist/astro/routes/api/schema/index.mjs +7 -7
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +42 -38
- package/dist/astro/routes/api/schema/orphans/index.mjs +42 -38
- package/dist/astro/routes/api/search/enable.mjs +11 -11
- package/dist/astro/routes/api/search/index.mjs +10 -10
- package/dist/astro/routes/api/search/rebuild.mjs +11 -11
- package/dist/astro/routes/api/search/stats.mjs +7 -7
- package/dist/astro/routes/api/search/suggest.mjs +10 -10
- package/dist/astro/routes/api/sections/_slug_.mjs +27 -27
- package/dist/astro/routes/api/sections/index.mjs +27 -27
- package/dist/astro/routes/api/settings/email.mjs +3 -3
- package/dist/astro/routes/api/settings.mjs +27 -27
- package/dist/astro/routes/api/setup/admin-verify.mjs +11 -11
- package/dist/astro/routes/api/setup/admin.mjs +9 -9
- package/dist/astro/routes/api/setup/dev-bypass.mjs +24 -23
- package/dist/astro/routes/api/setup/dev-reset.mjs +1 -1
- package/dist/astro/routes/api/setup/index.mjs +25 -24
- package/dist/astro/routes/api/setup/status.mjs +3 -3
- package/dist/astro/routes/api/snapshot.mjs +7 -6
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +30 -29
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +30 -29
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +30 -29
- package/dist/astro/routes/api/taxonomies/index.mjs +30 -29
- package/dist/astro/routes/api/themes/preview.mjs +4 -4
- package/dist/astro/routes/api/typegen.mjs +4 -4
- package/dist/astro/routes/api/well-known/auth.mjs +2 -2
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +3 -3
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +3 -3
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +26 -26
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +27 -27
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +27 -27
- package/dist/astro/routes/api/widget-areas/_name_.mjs +25 -25
- package/dist/astro/routes/api/widget-areas/index.mjs +27 -27
- package/dist/astro/routes/api/widget-components.mjs +2 -2
- package/dist/astro/routes/robots.txt.mjs +7 -7
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +59 -15
- package/dist/astro/routes/sitemap.xml.mjs +8 -8
- package/dist/astro/session-driver.d.mts +1 -1
- package/dist/astro/session-driver.mjs +3 -3
- package/dist/astro/types.d.mts +16 -14
- package/dist/{audit-NgiRzqP9.mjs → audit-DuRbTm8L.mjs} +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{auth-control-guard-1FHtkDP6.mjs → auth-control-guard-Dr14I98m.mjs} +1 -1
- package/dist/{authorize-BbIhZi3a.mjs → authorize-BLO0m7fW.mjs} +1 -1
- package/dist/{briefing-Jsxs587i.mjs → briefing-BFEWeJtR.mjs} +6 -6
- package/dist/{briefing-DD82WaEy.mjs → briefing-C4fJSVYW.mjs} +1 -1
- package/dist/byline-CXQcMsBu.mjs +628 -0
- package/dist/{bylines-BU6b8jSi.d.mts → byline-fields-Cuo-JI3B.d.mts} +150 -19
- package/dist/{import-Br7aP9yh.mjs → byline-fields-D7TJ_oHF.mjs} +57 -3
- package/dist/byline-fields-Dc7L6Yry.mjs +113 -0
- package/dist/byline-registry-CL8BxPPp.mjs +287 -0
- package/dist/bylines-BgriNlW7.mjs +165 -0
- package/dist/bylines-D2vqm1aZ.mjs +163 -0
- package/dist/{cache-DQyZ-QaB.mjs → cache-GRK71jOU.mjs} +2 -2
- package/dist/{chunks-D8KL0nCY.mjs → chunks-DgEw12Bc.mjs} +1 -1
- package/dist/cli/index.mjs +993 -90
- package/dist/client/external-auth-headers.d.mts +1 -1
- package/dist/client/index.d.mts +2 -1
- package/dist/client/index.mjs +5 -2
- package/dist/{comment-BmJXz3lc.mjs → comment-ogMaF1gk.mjs} +1 -1
- package/dist/{comments-yTbeIYc2.mjs → comments-CTSOKrZq.mjs} +1 -1
- package/dist/{connection-BCNICDWN.mjs → connection-CiJWiWya.mjs} +44 -13
- package/dist/{content-DvpMad_N.mjs → content-BfyjOiMi.mjs} +24 -4
- package/dist/content-index-names-Bbu1FY1r.mjs +26 -0
- package/dist/{context-DgqEfcWz.mjs → context-CdsYb1m8.mjs} +2 -2
- package/dist/{context-Ufrm1lOv.mjs → context-ZMHhwzkG.mjs} +8 -8
- package/dist/{context-route-helpers-Dq5U_AXp.mjs → context-route-helpers-YLWx2N1j.mjs} +1 -1
- package/dist/{dashboard-BC9bgPOH.mjs → dashboard-D0gWuzNp.mjs} +4 -4
- 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.mjs +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.mjs +1 -1
- package/dist/{device-flow-CTS91g4A.mjs → device-flow-B3_FEoMI.mjs} +4 -4
- package/dist/{dialect-helpers-TkdbkFad.mjs → dialect-helpers-fk43GbDb.mjs} +13 -3
- package/dist/{fts-manager-DnfOsF4s.mjs → fts-manager-EHY2Kes9.mjs} +2 -2
- package/dist/{hitl-requests-DaRuZ7tb.mjs → hitl-requests-B1Zqgut6.mjs} +2 -2
- package/dist/{hitl-route-helpers-DcPySbZ3.mjs → hitl-route-helpers-CjpWUMuw.mjs} +4 -4
- package/dist/{import-DSXK3aQF.mjs → import-CvHY6sf5.mjs} +3 -3
- package/dist/{index-BwOO3vu2.d.mts → index-DJVaYiUV.d.mts} +2 -2
- package/dist/index.d.mts +16 -17
- package/dist/index.mjs +69 -65
- package/dist/{jsonld-CLbYsYYH.d.mts → jsonld-AcPnCEGD.d.mts} +2 -2
- package/dist/{load-BCCcmoW9.mjs → load-BdbvtoDb.mjs} +1 -1
- package/dist/{loader-p2imNN98.mjs → loader-Y0QvC_QO.mjs} +167 -61
- package/dist/media/index.d.mts +1 -2
- package/dist/media/index.mjs +2 -2
- package/dist/media/local-runtime.d.mts +11 -12
- package/dist/media/local-runtime.mjs +2 -2
- package/dist/{media-Cg4zc9fq.mjs → media-DhBwiCYR.mjs} +6 -1
- package/dist/{media-allowlist-D8gsm8_t.mjs → media-allowlist-BsXkT9RK.mjs} +1 -1
- package/dist/{menus-DOaL6NaF.mjs → menus-BzGQpw9d.mjs} +2 -2
- package/dist/{menus-DzG3-9tQ.mjs → menus-fqqzXyHd.mjs} +5 -5
- package/dist/{oauth-authorization-DyOFXQWq.mjs → oauth-authorization-DsF81vki.mjs} +4 -4
- package/dist/{oauth-clients-BMs_bmoz.mjs → oauth-clients-Du-V0fEm.mjs} +2 -2
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.mjs +1 -1
- package/dist/{parse-D7Tu6ku4.mjs → parse-CneSgl7-.mjs} +1 -1
- package/dist/{types-cn-fvYQ1.d.mts → placeholder-CXfoCtCd.d.mts} +38 -1
- package/dist/plugin-utils.d.mts +22 -10
- package/dist/plugin-utils.mjs +8 -10
- package/dist/plugins/adapt-sandbox-entry.d.mts +9 -10
- package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
- package/dist/{plugins-DCDVDF4B.mjs → plugins-BQ5Joz6v.mjs} +36 -6
- package/dist/{preview-BhgxNRWI.mjs → preview-D5rvDhRt.mjs} +7 -7
- package/dist/{provider-loader-B19YyyBp.d.mts → provider-loader-B5PMjpN7.d.mts} +1 -1
- package/dist/{query-BnRpB09I.mjs → query-BJuUydtD.mjs} +3 -3
- package/dist/{query-DHvNhBhi.mjs → query-CSx0EdSW.mjs} +30 -18
- package/dist/{rate-limit-BWP_kKiZ.mjs → rate-limit-i0G3IAOX.mjs} +2 -2
- package/dist/{redirect-BaVvo2te.mjs → redirect-BqFMj67n.mjs} +20 -6
- package/dist/{redirects-Ba-lJA5j.mjs → redirects-CJwHl_YG.mjs} +3 -3
- package/dist/{redirects-x5ol_Qj9.mjs → redirects-q_cToaHv.mjs} +29 -8
- package/dist/{registry-i__XP2WV.mjs → registry-Cq3QRBW2.mjs} +14 -5
- package/dist/{request-cache-BpwuE2ix.mjs → request-cache-w5cj5itT.mjs} +9 -1
- package/dist/{request-meta-DUGfAeXy.mjs → request-meta-DAb6xaP9.mjs} +1 -1
- package/dist/resolve-DTuDyYKs.mjs +100 -0
- package/dist/{review-requests-DuIxM4YM.mjs → review-requests-GYqjl2jO.mjs} +1 -1
- package/dist/{review-requests-CTUU_RJm.mjs → review-requests-tPw8_pAO.mjs} +1 -1
- package/dist/{runner-FhUNNaqA.d.mts → runner-Cnz4dl0f.d.mts} +1 -1
- package/dist/{runner-DF2DgD_B.mjs → runner-DTfG5v0G.mjs} +574 -196
- package/dist/{runtime-1bE80cmL.d.mts → runtime-Cd-kjPfN.d.mts} +1155 -273
- package/dist/runtime.d.mts +10 -11
- package/dist/runtime.mjs +4 -4
- package/dist/schema-DmHMWnSA.mjs +8 -0
- package/dist/{search-Cl9preJT.mjs → search-BAiFLz81.mjs} +3 -3
- package/dist/{sections-Zx-2q9IH.mjs → sections-DsuIrFDC.mjs} +2 -2
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +18 -17
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.mjs +1 -0
- package/dist/{seo-CJBiMDkj.mjs → seo-5lJOtB5J.mjs} +4 -2
- package/dist/{seo-BPb_reaG.mjs → seo-uMFBaR8G.mjs} +1 -1
- package/dist/{service-wPGgmbUa.mjs → service-CifrxCru.mjs} +2 -2
- package/dist/{settings-nr15a8uv.mjs → settings-BYGdocdj.mjs} +2 -2
- package/dist/{settings-DORe02PC.mjs → settings-DNRQuX3d.mjs} +3 -3
- package/dist/{site-activity-KFZprBZM.mjs → site-activity-6x1JccoR.mjs} +1 -1
- package/dist/{site-context-DuBQk6Mp.mjs → site-context-c1ZFa_OF.mjs} +13 -13
- 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-DGaw_-aU.mjs → taxonomies-CQFmkP5u.mjs} +3 -3
- package/dist/{taxonomies-BVBKoXRf.mjs → taxonomies-faQVeMgj.mjs} +7 -32
- package/dist/{taxonomy-BvXRL85P.mjs → taxonomy-BnH-6VsX.mjs} +2 -2
- package/dist/{types-DvwHUku7.d.mts → types-B7_vSiPD.d.mts} +16 -0
- package/dist/{types-D1DjBFA9.mjs → types-Ck7-WoUD.mjs} +1 -1
- package/dist/{types-t7_nCCA9.d.mts → types-DEAQG87T.d.mts} +2 -56
- package/dist/{types-C-CMfzSl.d.mts → types-DYKtk8f1.d.mts} +31 -0
- package/dist/{types-C3Em8xpG.mjs → types-DbZhHtqS.mjs} +23 -1
- package/dist/{types-BIM7jwxr.d.mts → types-UGmU5sWx.d.mts} +1 -1
- package/dist/types-nP9vGUFq.d.mts +56 -0
- package/dist/ui/server-runtime.d.mts +13 -7
- package/dist/ui/server-runtime.mjs +18 -17
- package/dist/{user-2aI21yV1.mjs → user-CqZwN21P.mjs} +1 -1
- package/dist/{validate-CvQ6cvHH.d.mts → validate-BJuG-ISL.d.mts} +21 -3
- package/dist/{validate-JE-WfUQ5.mjs → validate-CK4a1sIF.mjs} +22 -2
- package/dist/version-Cb1tZ6s_.mjs +6 -0
- package/dist/{widgets-Cj6ULpED.mjs → widgets-CdDvF4fV.mjs} +2 -2
- package/dist/{wordpress-slugs-hqItqJrQ.mjs → wordpress-slugs-B6Gw9q3Q.mjs} +1 -1
- package/dist/{zod-generator-C4BgFBZV.mjs → zod-generator-D1ROBNuC.mjs} +2 -2
- package/package.json +7 -8
- package/src/components/InlinePortableTextEditor.tsx +66 -0
- package/src/components/code-block-languages.ts +76 -0
- package/src/components/inline-code-block.tsx +241 -0
- package/dist/byline-DpNNSjET.mjs +0 -219
- package/dist/bylines-75_STR73.mjs +0 -114
- package/dist/chunk-ClPoSABd.mjs +0 -21
- package/dist/db-errors-DHJCB_gY.mjs +0 -23
- package/dist/index-Ct0pjZwW.d.mts +0 -835
- package/dist/placeholder-BZpCpid_.d.mts +0 -40
- package/dist/schema-U-SeFWwn.mjs +0 -8
- package/dist/version-DTpFm69w.mjs +0 -6
- /package/dist/{adapters-kZjS7plb.d.mts → adapters-OQCImOL7.d.mts} +0 -0
- /package/dist/{api-tokens-L0o9Bd7v.mjs → api-tokens-CYUoFGo7.mjs} +0 -0
- /package/dist/{challenge-store-cJam-E5R.mjs → challenge-store-DFxX0_15.mjs} +0 -0
- /package/dist/{components-BJfa-F6n.mjs → components--pg6zBvu.mjs} +0 -0
- /package/dist/{config-XW5tMrH8.mjs → config-CVssduLe.mjs} +0 -0
- /package/dist/{context-types-BrSQNye5.mjs → context-types-DQh_XKkn.mjs} +0 -0
- /package/dist/{cron-D7FDsRu-.mjs → cron-DxCAU_Sn.mjs} +0 -0
- /package/dist/{default-5A3XVR7L.mjs → default-BHauvIdG.mjs} +0 -0
- /package/dist/{email-console-Bs1qKx59.mjs → email-console-BOVqIYpB.mjs} +0 -0
- /package/dist/{error-DLkgOP5m.mjs → error-DCSuUAZW.mjs} +0 -0
- /package/dist/{escape-r8_GbEU2.mjs → escape-BDgouFFY.mjs} +0 -0
- /package/dist/{experimental-workflows-BbZbIEZp.mjs → experimental-workflows-CSMffP6q.mjs} +0 -0
- /package/dist/{hash-DFFrkivP.mjs → hash-BPmX6P8I.mjs} +0 -0
- /package/dist/{manifest-schema-C6fzQoWn.mjs → manifest-schema-qh2P7RDX.mjs} +0 -0
- /package/dist/{mime-DYP4V5Ks.mjs → mime-8pAB8-77.mjs} +0 -0
- /package/dist/{mode-Bd55iLcP.mjs → mode-CZqCF9dZ.mjs} +0 -0
- /package/dist/{normalize-BY_EJnd9.mjs → normalize-O-hi3a27.mjs} +0 -0
- /package/dist/{oauth-state-store-BRSUEkmx.mjs → oauth-state-store-qncPB_IU.mjs} +0 -0
- /package/dist/{oauth-user-lookup-DdcI8ZVL.mjs → oauth-user-lookup-BFjWF8wK.mjs} +0 -0
- /package/dist/{parser-egIGEco-.mjs → parser-DxfsARXL.mjs} +0 -0
- /package/dist/{passkey-config-AX4sjpQ4.mjs → passkey-config-DzHQK90v.mjs} +0 -0
- /package/dist/{patterns-CiyXeDgr.mjs → patterns-D9iDO3j8.mjs} +0 -0
- /package/dist/{placeholder-b0Ufu0La.mjs → placeholder-BDo81Is5.mjs} +0 -0
- /package/dist/{provider-loader-BdRV01gr.mjs → provider-loader-DzUxejk7.mjs} +0 -0
- /package/dist/{public-url-BL2r8dmQ.mjs → public-url-DLUM5OOv.mjs} +0 -0
- /package/dist/{redirect-Ce_6Yb6z.mjs → redirect-BjIBtDWY.mjs} +0 -0
- /package/dist/{secrets-DfeNNoLa.mjs → secrets-CPoFLJjm.mjs} +0 -0
- /package/dist/{seo-contributions-C0LXoWw3.mjs → seo-contributions-CqVvReEj.mjs} +0 -0
- /package/dist/{setup-complete-C2ztsNhJ.mjs → setup-complete-4EiBS1E5.mjs} +0 -0
- /package/dist/{setup-nonce-BTKq7uBi.mjs → setup-nonce-pyGfc9hV.mjs} +0 -0
- /package/dist/{sidecar-client-lrf7ErYJ.mjs → sidecar-client-mJxwayYN.mjs} +0 -0
- /package/dist/{site-url-C18yBhtv.mjs → site-url-C-cu8Ff2.mjs} +0 -0
- /package/dist/{ssrf-KAIQS48_.mjs → ssrf-DiKqWd3N.mjs} +0 -0
- /package/dist/{tokens-CsP8Se8S.mjs → tokens-CjSgb0AC.mjs} +0 -0
- /package/dist/{transport-nNEGdHkI.d.mts → transport-DidKKxvW.d.mts} +0 -0
- /package/dist/{transport-B7kO-4ee.mjs → transport-LSdZVXHF.mjs} +0 -0
- /package/dist/{trusted-proxy-Bbm6PLR6.mjs → trusted-proxy-BgIIcbsN.mjs} +0 -0
- /package/dist/{types-CNNQ8l0v.mjs → types-Cg276-3z.mjs} +0 -0
- /package/dist/{types-BYjPylrZ.d.mts → types-DZpT-PnG.d.mts} +0 -0
- /package/dist/{types-BgE6gMFI.d.mts → types-Dryvv7LH.d.mts} +0 -0
- /package/dist/{types-BBETcziA.d.mts → types-GaCtZ1k9.d.mts} +0 -0
- /package/dist/{url-BzhfYtRn.mjs → url-w7Mp5qAD.mjs} +0 -0
- /package/dist/{utils-FEbQMgB5.mjs → utils-wv-zvC-Y.mjs} +0 -0
package/dist/cli/index.mjs
CHANGED
|
@@ -1,37 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { r as isI18nEnabled } from "../config-
|
|
2
|
+
import { a as __exportAll, i as runMigrations, n as getMigrationStatus, t as getMigrationFingerprint } from "../runner-DTfG5v0G.mjs";
|
|
3
|
+
import { t as createDatabase } from "../connection-CiJWiWya.mjs";
|
|
4
|
+
import { t as validateIdentifier } from "../validate-VPnKoIzW.mjs";
|
|
5
|
+
import { l as listTablesLike } from "../dialect-helpers-fk43GbDb.mjs";
|
|
6
|
+
import { r as isI18nEnabled } from "../config-CVssduLe.mjs";
|
|
7
7
|
import { n as slugify } from "../slugify-BzGxlOFx.mjs";
|
|
8
|
-
import { t as ContentRepository } from "../content-
|
|
8
|
+
import { t as ContentRepository } from "../content-BfyjOiMi.mjs";
|
|
9
9
|
import { i as encodeBase64url } from "../base64-C1Q9yr0B.mjs";
|
|
10
|
-
import "../types-
|
|
11
|
-
import { t as MediaRepository } from "../media-
|
|
12
|
-
import { t as TaxonomyRepository } from "../taxonomy-
|
|
10
|
+
import "../types-Ck7-WoUD.mjs";
|
|
11
|
+
import { t as MediaRepository } from "../media-DhBwiCYR.mjs";
|
|
12
|
+
import { t as TaxonomyRepository } from "../taxonomy-BnH-6VsX.mjs";
|
|
13
13
|
import { t as OptionsRepository } from "../options-BF11H_FD.mjs";
|
|
14
|
-
import "../redirect-
|
|
15
|
-
import "../
|
|
16
|
-
import "../
|
|
17
|
-
import "../
|
|
18
|
-
import
|
|
19
|
-
import "../
|
|
20
|
-
import "../
|
|
21
|
-
import
|
|
22
|
-
import "../
|
|
23
|
-
import {
|
|
24
|
-
import
|
|
25
|
-
import {
|
|
14
|
+
import "../redirect-BqFMj67n.mjs";
|
|
15
|
+
import "../request-cache-w5cj5itT.mjs";
|
|
16
|
+
import "../byline-registry-CL8BxPPp.mjs";
|
|
17
|
+
import { t as BylineRepository } from "../byline-CXQcMsBu.mjs";
|
|
18
|
+
import "../fts-manager-EHY2Kes9.mjs";
|
|
19
|
+
import { n as SchemaRegistry } from "../registry-Cq3QRBW2.mjs";
|
|
20
|
+
import { a as isMissingTableError } from "../loader-Y0QvC_QO.mjs";
|
|
21
|
+
import "../settings-DNRQuX3d.mjs";
|
|
22
|
+
import { n as VERSION } from "../version-Cb1tZ6s_.mjs";
|
|
23
|
+
import { i as pluginManifestSchema } from "../manifest-schema-qh2P7RDX.mjs";
|
|
24
|
+
import "../ssrf-DiKqWd3N.mjs";
|
|
25
|
+
import { t as validateSeed } from "../validate-CK4a1sIF.mjs";
|
|
26
|
+
import { t as applySeed } from "../apply-BpRBCqUt.mjs";
|
|
27
|
+
import { n as fingerprintKey, r as generateEncryptionKey, t as DinewaySecretsError } from "../secrets-CPoFLJjm.mjs";
|
|
26
28
|
import { createHeaderAwareFetch, customHeadersInterceptor, isRedirectResponse, resolveCustomHeaders } from "../client/external-auth-headers.mjs";
|
|
27
|
-
import { o as convertDataForRead } from "../transport-
|
|
29
|
+
import { o as convertDataForRead } from "../transport-LSdZVXHF.mjs";
|
|
28
30
|
import { DinewayClient } from "../client/index.mjs";
|
|
29
31
|
import { LocalStorage } from "../storage/local.mjs";
|
|
30
32
|
import { createHash } from "node:crypto";
|
|
33
|
+
import { sql } from "kysely";
|
|
31
34
|
import { imageSize } from "image-size";
|
|
32
35
|
import { createGzipDecoder, unpackTar } from "modern-tar";
|
|
33
36
|
import { createReadStream, createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
34
37
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
38
|
+
import { pathToFileURL } from "node:url";
|
|
35
39
|
import { defineCommand, runCommand, runMain } from "citty";
|
|
36
40
|
import consola, { consola as consola$1 } from "consola";
|
|
37
41
|
import pc from "picocolors";
|
|
@@ -718,6 +722,10 @@ const updateCommand = defineCommand({
|
|
|
718
722
|
description: "Revision token from get (prevents overwriting unseen changes)",
|
|
719
723
|
required: true
|
|
720
724
|
},
|
|
725
|
+
locale: {
|
|
726
|
+
type: "string",
|
|
727
|
+
description: "Locale for slug resolution"
|
|
728
|
+
},
|
|
721
729
|
draft: {
|
|
722
730
|
type: "boolean",
|
|
723
731
|
description: "Keep as draft instead of auto-publishing"
|
|
@@ -731,10 +739,11 @@ const updateCommand = defineCommand({
|
|
|
731
739
|
const client = createClientFromArgs(args);
|
|
732
740
|
const updated = await client.update(args.collection, args.id, {
|
|
733
741
|
data,
|
|
734
|
-
_rev: args.rev
|
|
742
|
+
_rev: args.rev,
|
|
743
|
+
locale: args.locale
|
|
735
744
|
});
|
|
736
|
-
if (!args.draft && updated.draftRevisionId) await client.publish(args.collection,
|
|
737
|
-
output(await client.get(args.collection,
|
|
745
|
+
if (!args.draft && updated.draftRevisionId) await client.publish(args.collection, updated.id);
|
|
746
|
+
output(await client.get(args.collection, updated.id), args);
|
|
738
747
|
} catch (error) {
|
|
739
748
|
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
740
749
|
process.exit(1);
|
|
@@ -1631,13 +1640,33 @@ async function writeForgewayDeployMetadata(cwd, metadata) {
|
|
|
1631
1640
|
//#endregion
|
|
1632
1641
|
//#region src/cli/commands/deploy/utils/forgeway-secrets.ts
|
|
1633
1642
|
const DINEWAY_CONFIG_DIR_NAME = ".dineway";
|
|
1634
|
-
const
|
|
1643
|
+
const DINEWAY_USER_CONFIG_DIR_NAME = "dineway";
|
|
1644
|
+
const TRAILING_SLASH_PATTERN$2 = /\/$/;
|
|
1635
1645
|
function getDinewayConfigDir(cwd = process.cwd()) {
|
|
1636
1646
|
return join(cwd, DINEWAY_CONFIG_DIR_NAME);
|
|
1637
1647
|
}
|
|
1648
|
+
function getDinewayUserConfigDir() {
|
|
1649
|
+
return join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), DINEWAY_USER_CONFIG_DIR_NAME);
|
|
1650
|
+
}
|
|
1638
1651
|
function getForgewaySecretPath(cwd = process.cwd()) {
|
|
1639
1652
|
return join(getDinewayConfigDir(cwd), "forgeway.json");
|
|
1640
1653
|
}
|
|
1654
|
+
function getForgewayAccountSecretPath() {
|
|
1655
|
+
return join(getDinewayUserConfigDir(), "forgeway.json");
|
|
1656
|
+
}
|
|
1657
|
+
function normalizePlatformApiUrl$1(platformApiUrl) {
|
|
1658
|
+
return platformApiUrl.replace(TRAILING_SLASH_PATTERN$2, "");
|
|
1659
|
+
}
|
|
1660
|
+
function normalizeEmail$2(email) {
|
|
1661
|
+
return email.trim().toLowerCase();
|
|
1662
|
+
}
|
|
1663
|
+
function accountKey(platformApiUrl, email) {
|
|
1664
|
+
return `${normalizePlatformApiUrl$1(platformApiUrl)}#${normalizeEmail$2(email)}`;
|
|
1665
|
+
}
|
|
1666
|
+
function normalizeLookup(lookup) {
|
|
1667
|
+
if (typeof lookup === "string") return { cwd: lookup };
|
|
1668
|
+
return lookup ?? {};
|
|
1669
|
+
}
|
|
1641
1670
|
async function readStore(cwd = process.cwd()) {
|
|
1642
1671
|
try {
|
|
1643
1672
|
const raw = await readFile(getForgewaySecretPath(cwd), "utf-8");
|
|
@@ -1658,16 +1687,66 @@ async function writeStore(store, cwd = process.cwd()) {
|
|
|
1658
1687
|
});
|
|
1659
1688
|
await chmod(file, 384);
|
|
1660
1689
|
}
|
|
1661
|
-
async function
|
|
1662
|
-
|
|
1690
|
+
async function readAccountStore() {
|
|
1691
|
+
try {
|
|
1692
|
+
const raw = await readFile(getForgewayAccountSecretPath(), "utf-8");
|
|
1693
|
+
return JSON.parse(raw);
|
|
1694
|
+
} catch {
|
|
1695
|
+
return { version: 1 };
|
|
1696
|
+
}
|
|
1663
1697
|
}
|
|
1664
|
-
async function
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1698
|
+
async function writeAccountStore(store) {
|
|
1699
|
+
await mkdir(getDinewayUserConfigDir(), {
|
|
1700
|
+
recursive: true,
|
|
1701
|
+
mode: 448
|
|
1702
|
+
});
|
|
1703
|
+
const file = getForgewayAccountSecretPath();
|
|
1704
|
+
await writeFile(file, JSON.stringify({
|
|
1705
|
+
...store,
|
|
1706
|
+
version: 1
|
|
1707
|
+
}, null, " ") + "\n", {
|
|
1708
|
+
encoding: "utf-8",
|
|
1709
|
+
mode: 384
|
|
1710
|
+
});
|
|
1711
|
+
await chmod(file, 384);
|
|
1712
|
+
}
|
|
1713
|
+
function accountMatches(credentials, lookup) {
|
|
1714
|
+
if (lookup.platformApiUrl && normalizePlatformApiUrl$1(credentials.platformApiUrl) !== normalizePlatformApiUrl$1(lookup.platformApiUrl)) return false;
|
|
1715
|
+
if (lookup.email && normalizeEmail$2(credentials.user?.email ?? "") !== normalizeEmail$2(lookup.email)) return false;
|
|
1716
|
+
return true;
|
|
1717
|
+
}
|
|
1718
|
+
async function readForgewayCredentials(lookup) {
|
|
1719
|
+
const normalizedLookup = normalizeLookup(lookup);
|
|
1720
|
+
const store = await readAccountStore();
|
|
1721
|
+
const accounts = Object.values(store.accounts ?? {}).filter((credentials) => accountMatches(credentials, normalizedLookup));
|
|
1722
|
+
if (normalizedLookup.platformApiUrl && normalizedLookup.email) return store.accounts?.[accountKey(normalizedLookup.platformApiUrl, normalizedLookup.email)] ?? null;
|
|
1723
|
+
if (accounts.length === 1) return accounts[0] ?? null;
|
|
1724
|
+
return null;
|
|
1725
|
+
}
|
|
1726
|
+
async function writeForgewayCredentials(credentials, lookup) {
|
|
1727
|
+
const normalizedLookup = normalizeLookup(lookup);
|
|
1728
|
+
const platformApiUrl = normalizePlatformApiUrl$1(normalizedLookup.platformApiUrl ?? credentials.platformApiUrl);
|
|
1729
|
+
const email = normalizeEmail$2(normalizedLookup.email ?? credentials.user?.email ?? "");
|
|
1730
|
+
if (!email) throw new Error("Forgeway credentials require a user email before they can be stored.");
|
|
1731
|
+
const key = accountKey(platformApiUrl, email);
|
|
1732
|
+
const store = await readAccountStore();
|
|
1733
|
+
store.accounts = {
|
|
1734
|
+
...store.accounts,
|
|
1735
|
+
[key]: {
|
|
1736
|
+
...credentials,
|
|
1737
|
+
platformApiUrl
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1740
|
+
store.lastAccountKey = key;
|
|
1741
|
+
await writeAccountStore(store);
|
|
1742
|
+
}
|
|
1743
|
+
async function listForgewayCredentials(platformApiUrl) {
|
|
1744
|
+
const lookup = platformApiUrl ? { platformApiUrl } : {};
|
|
1745
|
+
const store = await readAccountStore();
|
|
1746
|
+
return Object.values(store.accounts ?? {}).filter((credentials) => accountMatches(credentials, lookup));
|
|
1668
1747
|
}
|
|
1669
1748
|
function shadowGrantKey(platformApiUrl, placeId) {
|
|
1670
|
-
return `${platformApiUrl.replace(TRAILING_SLASH_PATTERN$
|
|
1749
|
+
return `${platformApiUrl.replace(TRAILING_SLASH_PATTERN$2, "")}#${placeId ?? "__unbound__"}`;
|
|
1671
1750
|
}
|
|
1672
1751
|
async function readForgewayShadowGrant(platformApiUrl, placeId, cwd) {
|
|
1673
1752
|
const store = await readStore(cwd);
|
|
@@ -1690,7 +1769,7 @@ async function writeForgewayShadowGrant(grant, cwd) {
|
|
|
1690
1769
|
|
|
1691
1770
|
//#endregion
|
|
1692
1771
|
//#region src/cli/commands/deploy/targets/forgeway.ts
|
|
1693
|
-
const DEFAULT_DINEWAY_API_BASE_URL = "https://api.dineway.ai";
|
|
1772
|
+
const DEFAULT_DINEWAY_API_BASE_URL$1 = "https://api.dineway.ai";
|
|
1694
1773
|
const DATABASE_ENV_VAR_NAMES = ["DINEWAY_DATABASE_URL", "DINEWAY_DATABASE_AUTH_TOKEN"];
|
|
1695
1774
|
const POLL_INTERVAL_MS$1 = 5e3;
|
|
1696
1775
|
const POLL_TIMEOUT_MS$1 = 3e5;
|
|
@@ -1705,9 +1784,12 @@ const NON_COMPARE_PATTERN = /[^\p{Letter}\p{Number}]+/gu;
|
|
|
1705
1784
|
const LOCATION_PARTS_PATTERN = /[,;|/]+|\s+-\s+/u;
|
|
1706
1785
|
const JWT_PATTERN = /[A-Za-z0-9_-]{32,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/g;
|
|
1707
1786
|
const TOKEN_ASSIGNMENT_PATTERN = /(DINEWAY_DATABASE_AUTH_TOKEN|DATABASE_AUTH_TOKEN|AUTH_TOKEN)=\S+/gi;
|
|
1708
|
-
const TRAILING_SLASH_PATTERN = /\/$/;
|
|
1787
|
+
const TRAILING_SLASH_PATTERN$1 = /\/$/;
|
|
1709
1788
|
const BACKSLASH_PATTERN = /\\/g;
|
|
1710
|
-
const
|
|
1789
|
+
const DINEWAY_PACKAGE_NAME = "dineway";
|
|
1790
|
+
const SEMVER_VERSION_PATTERN = /^\d+\.\d+\.\d+(?:[-+].*)?$/;
|
|
1791
|
+
const LOCAL_PACKAGE_SPEC_PATTERN = /^(?:workspace|file|link|portal):/;
|
|
1792
|
+
const SHADOW_EMAIL_PATTERN$1 = /^shadow_[a-f0-9]{16}@dineway\.ai$/i;
|
|
1711
1793
|
const OTP_PATTERN = /^\d{6}$/;
|
|
1712
1794
|
const FOOD_TYPES = new Set([
|
|
1713
1795
|
"restaurant",
|
|
@@ -1756,7 +1838,7 @@ var ForgewayApiError = class extends Error {
|
|
|
1756
1838
|
this.name = "ForgewayApiError";
|
|
1757
1839
|
}
|
|
1758
1840
|
};
|
|
1759
|
-
function normalizeForgewayUser(user) {
|
|
1841
|
+
function normalizeForgewayUser$1(user) {
|
|
1760
1842
|
return {
|
|
1761
1843
|
id: user.id,
|
|
1762
1844
|
name: user.profile?.name ?? user.name ?? user.email,
|
|
@@ -1777,7 +1859,7 @@ async function fileExists$8(path) {
|
|
|
1777
1859
|
}
|
|
1778
1860
|
}
|
|
1779
1861
|
function normalizePlatformApiUrl(value) {
|
|
1780
|
-
return (value || DEFAULT_DINEWAY_API_BASE_URL).replace(TRAILING_SLASH_PATTERN, "");
|
|
1862
|
+
return (value || DEFAULT_DINEWAY_API_BASE_URL$1).replace(TRAILING_SLASH_PATTERN$1, "");
|
|
1781
1863
|
}
|
|
1782
1864
|
function resolvePlatformApiUrl(savedPlatformApiUrl) {
|
|
1783
1865
|
return normalizePlatformApiUrl(getEnv("DINEWAY_API_BASE_URL") ?? (typeof savedPlatformApiUrl === "string" ? savedPlatformApiUrl : void 0));
|
|
@@ -1840,7 +1922,7 @@ async function parseErrorResponse(response) {
|
|
|
1840
1922
|
}
|
|
1841
1923
|
return `Forgeway request failed: ${response.status}`;
|
|
1842
1924
|
}
|
|
1843
|
-
function normalizeEmail(email) {
|
|
1925
|
+
function normalizeEmail$1(email) {
|
|
1844
1926
|
return email.trim().toLowerCase();
|
|
1845
1927
|
}
|
|
1846
1928
|
function normalizeOtp(otp) {
|
|
@@ -1848,8 +1930,8 @@ function normalizeOtp(otp) {
|
|
|
1848
1930
|
if (!OTP_PATTERN.test(value)) throw new Error("Forgeway email verification OTP must be a 6-digit numeric code.");
|
|
1849
1931
|
return value;
|
|
1850
1932
|
}
|
|
1851
|
-
function isShadowEmail(email) {
|
|
1852
|
-
return Boolean(email && SHADOW_EMAIL_PATTERN.test(email));
|
|
1933
|
+
function isShadowEmail$1(email) {
|
|
1934
|
+
return Boolean(email && SHADOW_EMAIL_PATTERN$1.test(email));
|
|
1853
1935
|
}
|
|
1854
1936
|
async function refreshFormalAccessToken(context, deps) {
|
|
1855
1937
|
if (!context.refreshToken) throw new Error("Forgeway formal account refresh token is missing. Run dineway deploy again.");
|
|
@@ -1861,19 +1943,22 @@ async function refreshFormalAccessToken(context, deps) {
|
|
|
1861
1943
|
if (!response.ok) throw new Error("Failed to refresh Forgeway formal account credentials. Run dineway deploy again.");
|
|
1862
1944
|
const payload = await response.json();
|
|
1863
1945
|
if (!payload.accessToken) throw new Error("Forgeway refresh response was missing accessToken.");
|
|
1864
|
-
const user = assertVerifiedFormalAccountUser(payload.user ? normalizeForgewayUser(payload.user) : context.user, context.user?.email);
|
|
1946
|
+
const user = assertVerifiedFormalAccountUser(payload.user ? normalizeForgewayUser$1(payload.user) : context.user, context.user?.email);
|
|
1865
1947
|
const updated = {
|
|
1866
1948
|
platformApiUrl: context.platformApiUrl,
|
|
1867
1949
|
accessToken: payload.accessToken,
|
|
1868
1950
|
refreshToken: payload.refreshToken ?? context.refreshToken,
|
|
1869
1951
|
...user ? { user } : {},
|
|
1870
|
-
source: "shadow-email-upgrade"
|
|
1871
|
-
...context.placeId ? { placeId: context.placeId } : {}
|
|
1952
|
+
source: "shadow-email-upgrade"
|
|
1872
1953
|
};
|
|
1873
1954
|
context.accessToken = updated.accessToken;
|
|
1874
1955
|
context.refreshToken = updated.refreshToken;
|
|
1875
1956
|
context.user = updated.user;
|
|
1876
|
-
await (deps.writeCredentials ?? writeForgewayCredentials)(updated,
|
|
1957
|
+
await (deps.writeCredentials ?? writeForgewayCredentials)(updated, {
|
|
1958
|
+
cwd: context.projectDir,
|
|
1959
|
+
platformApiUrl: context.platformApiUrl,
|
|
1960
|
+
email: user.email
|
|
1961
|
+
});
|
|
1877
1962
|
return payload.accessToken;
|
|
1878
1963
|
}
|
|
1879
1964
|
async function refreshShadowAccessToken(context, deps) {
|
|
@@ -1895,7 +1980,7 @@ async function refreshShadowAccessToken(context, deps) {
|
|
|
1895
1980
|
refreshToken: payload.refreshToken,
|
|
1896
1981
|
restaurantName: context.restaurantName,
|
|
1897
1982
|
city: context.city,
|
|
1898
|
-
user: payload.user ? normalizeForgewayUser(payload.user) : void 0,
|
|
1983
|
+
user: payload.user ? normalizeForgewayUser$1(payload.user) : void 0,
|
|
1899
1984
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1900
1985
|
}, context.projectDir);
|
|
1901
1986
|
return payload.accessToken;
|
|
@@ -1922,25 +2007,62 @@ async function promptRequired(question, initialValue, deps, errorMessage) {
|
|
|
1922
2007
|
async function readSavedForgewayMetadata(cwd) {
|
|
1923
2008
|
return await readForgewayDeployMetadata(cwd).catch(() => ({}));
|
|
1924
2009
|
}
|
|
1925
|
-
|
|
1926
|
-
const
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
2010
|
+
function getDependencySpec(pkg, name) {
|
|
2011
|
+
for (const key of ["dependencies", "devDependencies"]) {
|
|
2012
|
+
const deps = pkg[key];
|
|
2013
|
+
if (!deps || typeof deps !== "object") continue;
|
|
2014
|
+
const value = deps[name];
|
|
2015
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
async function readProjectPackage(cwd) {
|
|
2019
|
+
try {
|
|
2020
|
+
return await readDeployPackageJson(cwd);
|
|
2021
|
+
} catch {
|
|
2022
|
+
return null;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
function isDinewayDependencySpecCompatible(dependencySpec, cliVersion) {
|
|
2026
|
+
const spec = dependencySpec.trim();
|
|
2027
|
+
if (LOCAL_PACKAGE_SPEC_PATTERN.test(spec)) return true;
|
|
2028
|
+
return spec.includes(cliVersion);
|
|
2029
|
+
}
|
|
2030
|
+
async function assertProjectDinewayRuntimeCompatible(cwd, cliVersion = VERSION) {
|
|
2031
|
+
if (!SEMVER_VERSION_PATTERN.test(cliVersion)) return;
|
|
2032
|
+
const pkg = await readProjectPackage(cwd);
|
|
2033
|
+
if (!pkg) return;
|
|
2034
|
+
const dependencySpec = getDependencySpec(pkg, DINEWAY_PACKAGE_NAME);
|
|
2035
|
+
if (!dependencySpec) return;
|
|
2036
|
+
if (isDinewayDependencySpecCompatible(dependencySpec, cliVersion)) return;
|
|
2037
|
+
throw new Error(`Forgeway deploy requires the deployed Dineway runtime to match the deploy CLI because the CLI initializes the managed database before the site starts. The CLI is ${DINEWAY_PACKAGE_NAME}@${cliVersion}, but package.json declares ${DINEWAY_PACKAGE_NAME}: ${JSON.stringify(dependencySpec)}. Update package.json and reinstall with your package manager, for example: ${DINEWAY_PACKAGE_NAME}@^${cliVersion}. To deploy with the current manifest instead, run the matching CLI version.`);
|
|
2038
|
+
}
|
|
2039
|
+
function explicitPublisherEmail(options) {
|
|
2040
|
+
return options.email ?? getEnv("DINEWAY_EMAIL") ?? getEnv("FORGEWAY_EMAIL");
|
|
2041
|
+
}
|
|
2042
|
+
function savedPublisherEmail(saved) {
|
|
2043
|
+
return typeof saved.publisherEmail === "string" && saved.publisherEmail.trim() ? saved.publisherEmail : void 0;
|
|
2044
|
+
}
|
|
2045
|
+
function validatePublisherEmail(rawEmail) {
|
|
2046
|
+
const email = normalizeEmail$1(rawEmail);
|
|
2047
|
+
if (!email || isShadowEmail$1(email)) throw new Error("Dineway account email must be a real owner email, not a shadow user email.");
|
|
1932
2048
|
return email;
|
|
1933
2049
|
}
|
|
1934
|
-
function
|
|
1935
|
-
|
|
1936
|
-
|
|
2050
|
+
async function resolveForgewayAccountEmail(options, saved, deps, preferredEmail) {
|
|
2051
|
+
const suppliedEmail = options.email ?? getEnv("DINEWAY_EMAIL") ?? getEnv("FORGEWAY_EMAIL");
|
|
2052
|
+
const savedEmail = savedPublisherEmail(saved);
|
|
2053
|
+
if ((options.sendOtp || options.otp) && !suppliedEmail && !preferredEmail && !savedEmail) throw new Error("Forgeway OTP deploy requires --email or DINEWAY_EMAIL.");
|
|
2054
|
+
return validatePublisherEmail(suppliedEmail ?? preferredEmail ?? savedEmail ?? await promptRequired("Dineway account email: ", void 0, deps, "Dineway account email is required. Pass --email or set DINEWAY_EMAIL."));
|
|
2055
|
+
}
|
|
2056
|
+
function isStoredFormalCredentialForEmail(stored, email) {
|
|
2057
|
+
if (!stored?.accessToken || !stored.user) return false;
|
|
2058
|
+
if (email && normalizeEmail$1(stored.user.email) !== email) return false;
|
|
1937
2059
|
if (stored.user.emailVerified !== true) return false;
|
|
1938
|
-
if (isShadowEmail(stored.user.email)) return false;
|
|
2060
|
+
if (isShadowEmail$1(stored.user.email)) return false;
|
|
1939
2061
|
return true;
|
|
1940
2062
|
}
|
|
1941
2063
|
function assertVerifiedFormalAccountUser(user, expectedEmail) {
|
|
1942
|
-
if (!user || user.emailVerified !== true || isShadowEmail(user.email)) throw new Error("Forgeway formal account credentials require a verified formal account.");
|
|
1943
|
-
if (expectedEmail && normalizeEmail(user.email) !== normalizeEmail(expectedEmail)) throw new Error("Forgeway refresh returned credentials for a different email.");
|
|
2064
|
+
if (!user || user.emailVerified !== true || isShadowEmail$1(user.email)) throw new Error("Forgeway formal account credentials require a verified formal account.");
|
|
2065
|
+
if (expectedEmail && normalizeEmail$1(user.email) !== normalizeEmail$1(expectedEmail)) throw new Error("Forgeway refresh returned credentials for a different email.");
|
|
1944
2066
|
return user;
|
|
1945
2067
|
}
|
|
1946
2068
|
async function shadowUpgradeFetch(context, path, deps, options) {
|
|
@@ -1963,7 +2085,7 @@ async function startShadowEmailUpgrade(context, email, deps) {
|
|
|
1963
2085
|
method: "POST",
|
|
1964
2086
|
body: JSON.stringify({ email })
|
|
1965
2087
|
});
|
|
1966
|
-
if (payload.email && normalizeEmail(payload.email) !== email) throw new Error("Forgeway email verification response returned a different email.");
|
|
2088
|
+
if (payload.email && normalizeEmail$1(payload.email) !== email) throw new Error("Forgeway email verification response returned a different email.");
|
|
1967
2089
|
return payload;
|
|
1968
2090
|
}
|
|
1969
2091
|
async function verifyShadowEmailUpgrade(context, email, otp, deps) {
|
|
@@ -1975,21 +2097,24 @@ async function verifyShadowEmailUpgrade(context, email, otp, deps) {
|
|
|
1975
2097
|
})
|
|
1976
2098
|
});
|
|
1977
2099
|
if (!payload.accessToken || !payload.refreshToken || !payload.user) throw new Error("Forgeway email upgrade response was missing credentials.");
|
|
1978
|
-
const user = normalizeForgewayUser(payload.user);
|
|
1979
|
-
if (normalizeEmail(user.email) !== email) throw new Error("Forgeway email upgrade returned credentials for a different email.");
|
|
1980
|
-
if (user.emailVerified !== true || isShadowEmail(user.email)) throw new Error("Forgeway email upgrade did not return a verified formal account.");
|
|
2100
|
+
const user = normalizeForgewayUser$1(payload.user);
|
|
2101
|
+
if (normalizeEmail$1(user.email) !== email) throw new Error("Forgeway email upgrade returned credentials for a different email.");
|
|
2102
|
+
if (user.emailVerified !== true || isShadowEmail$1(user.email)) throw new Error("Forgeway email upgrade did not return a verified formal account.");
|
|
1981
2103
|
return {
|
|
1982
2104
|
platformApiUrl: context.platformApiUrl,
|
|
1983
2105
|
accessToken: payload.accessToken,
|
|
1984
2106
|
refreshToken: payload.refreshToken,
|
|
1985
2107
|
user,
|
|
1986
|
-
source: "shadow-email-upgrade"
|
|
1987
|
-
...context.placeId ? { placeId: context.placeId } : {}
|
|
2108
|
+
source: "shadow-email-upgrade"
|
|
1988
2109
|
};
|
|
1989
2110
|
}
|
|
1990
|
-
async function resolveFormalAccountCredentials(context,
|
|
1991
|
-
const stored = await (deps.readCredentials ?? readForgewayCredentials)(
|
|
1992
|
-
|
|
2111
|
+
async function resolveFormalAccountCredentials(context, email, options, deps) {
|
|
2112
|
+
const stored = await (deps.readCredentials ?? readForgewayCredentials)({
|
|
2113
|
+
cwd: context.projectDir,
|
|
2114
|
+
platformApiUrl: context.platformApiUrl,
|
|
2115
|
+
email
|
|
2116
|
+
});
|
|
2117
|
+
if (!options.sendOtp && !options.otp && isStoredFormalCredentialForEmail(stored, email)) return {
|
|
1993
2118
|
status: "verified",
|
|
1994
2119
|
credentials: {
|
|
1995
2120
|
...stored,
|
|
@@ -2000,13 +2125,17 @@ async function resolveFormalAccountCredentials(context, grant, email, options, d
|
|
|
2000
2125
|
const response = await startShadowEmailUpgrade(context, email, deps);
|
|
2001
2126
|
return {
|
|
2002
2127
|
status: "otp-sent",
|
|
2003
|
-
email: response.email ? normalizeEmail(response.email) : email,
|
|
2128
|
+
email: response.email ? normalizeEmail$1(response.email) : email,
|
|
2004
2129
|
expiresAt: response.expiresAt
|
|
2005
2130
|
};
|
|
2006
2131
|
}
|
|
2007
2132
|
if (options.otp) {
|
|
2008
2133
|
const credentials = await verifyShadowEmailUpgrade(context, email, normalizeOtp(options.otp), deps);
|
|
2009
|
-
await (deps.writeCredentials ?? writeForgewayCredentials)(credentials,
|
|
2134
|
+
await (deps.writeCredentials ?? writeForgewayCredentials)(credentials, {
|
|
2135
|
+
cwd: context.projectDir,
|
|
2136
|
+
platformApiUrl: context.platformApiUrl,
|
|
2137
|
+
email
|
|
2138
|
+
});
|
|
2010
2139
|
return {
|
|
2011
2140
|
status: "verified",
|
|
2012
2141
|
credentials
|
|
@@ -2015,13 +2144,111 @@ async function resolveFormalAccountCredentials(context, grant, email, options, d
|
|
|
2015
2144
|
await startShadowEmailUpgrade(context, email, deps);
|
|
2016
2145
|
consola.info(`Sent Forgeway email verification code to ${email}`);
|
|
2017
2146
|
const credentials = await verifyShadowEmailUpgrade(context, email, await promptRequired("Email verification code: ", void 0, deps, "Email verification code is required."), deps);
|
|
2018
|
-
await (deps.writeCredentials ?? writeForgewayCredentials)(credentials,
|
|
2147
|
+
await (deps.writeCredentials ?? writeForgewayCredentials)(credentials, {
|
|
2148
|
+
cwd: context.projectDir,
|
|
2149
|
+
platformApiUrl: context.platformApiUrl,
|
|
2150
|
+
email
|
|
2151
|
+
});
|
|
2019
2152
|
return {
|
|
2020
2153
|
status: "verified",
|
|
2021
2154
|
credentials
|
|
2022
2155
|
};
|
|
2023
2156
|
}
|
|
2024
|
-
async function
|
|
2157
|
+
async function readCachedPublisherCredentials(cwd, platformApiUrl, email, deps) {
|
|
2158
|
+
const credentials = await (deps.readCredentials ?? readForgewayCredentials)({
|
|
2159
|
+
cwd,
|
|
2160
|
+
platformApiUrl,
|
|
2161
|
+
email
|
|
2162
|
+
});
|
|
2163
|
+
return isStoredFormalCredentialForEmail(credentials, email) ? credentials : void 0;
|
|
2164
|
+
}
|
|
2165
|
+
async function resolveCachedPublisherAccount(cwd, options, saved, platformApiUrl, deps) {
|
|
2166
|
+
const suppliedEmail = explicitPublisherEmail(options);
|
|
2167
|
+
if (suppliedEmail) {
|
|
2168
|
+
const email = validatePublisherEmail(suppliedEmail);
|
|
2169
|
+
return {
|
|
2170
|
+
email,
|
|
2171
|
+
credentials: await readCachedPublisherCredentials(cwd, platformApiUrl, email, deps)
|
|
2172
|
+
};
|
|
2173
|
+
}
|
|
2174
|
+
const projectEmail = savedPublisherEmail(saved);
|
|
2175
|
+
if (projectEmail) {
|
|
2176
|
+
const email = validatePublisherEmail(projectEmail);
|
|
2177
|
+
return {
|
|
2178
|
+
email,
|
|
2179
|
+
credentials: await readCachedPublisherCredentials(cwd, platformApiUrl, email, deps)
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
const singleCredentials = await (deps.readCredentials ?? readForgewayCredentials)({
|
|
2183
|
+
cwd,
|
|
2184
|
+
platformApiUrl
|
|
2185
|
+
});
|
|
2186
|
+
if (isStoredFormalCredentialForEmail(singleCredentials)) return {
|
|
2187
|
+
email: normalizeEmail$1(singleCredentials.user.email),
|
|
2188
|
+
credentials: singleCredentials
|
|
2189
|
+
};
|
|
2190
|
+
const accounts = (await (deps.listCredentials ?? listForgewayCredentials)(platformApiUrl)).filter((credentials) => isStoredFormalCredentialForEmail(credentials));
|
|
2191
|
+
if (accounts.length === 1) {
|
|
2192
|
+
const credentials = accounts[0];
|
|
2193
|
+
return {
|
|
2194
|
+
email: normalizeEmail$1(credentials.user.email),
|
|
2195
|
+
credentials
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
2198
|
+
if (accounts.length > 1) {
|
|
2199
|
+
const email = validatePublisherEmail(await promptRequired("Dineway account email: ", void 0, deps, "Multiple Dineway accounts are stored on this computer. Pass --email or set DINEWAY_EMAIL."));
|
|
2200
|
+
return {
|
|
2201
|
+
email,
|
|
2202
|
+
credentials: await readCachedPublisherCredentials(cwd, platformApiUrl, email, deps)
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
return {};
|
|
2206
|
+
}
|
|
2207
|
+
async function resolveFormalProjectContext(cwd, options, deps) {
|
|
2208
|
+
const saved = await readSavedForgewayMetadata(cwd);
|
|
2209
|
+
const platformApiUrl = resolvePlatformApiUrl(saved.platformApiUrl);
|
|
2210
|
+
const account = await resolveCachedPublisherAccount(cwd, options, saved, platformApiUrl, deps);
|
|
2211
|
+
if (!account.credentials) return {
|
|
2212
|
+
status: "missing",
|
|
2213
|
+
email: account.email
|
|
2214
|
+
};
|
|
2215
|
+
const user = assertVerifiedFormalAccountUser(account.credentials.user, account.email);
|
|
2216
|
+
const savedPlaceId = options.placeId ?? getEnv("DINEWAY_PLACE_ID") ?? (typeof saved.placeId === "string" ? saved.placeId : void 0);
|
|
2217
|
+
if (savedPlaceId && !PLACE_ID_PATTERN.test(savedPlaceId)) throw new Error("Could not resolve a valid Dineway place id for Forgeway deploy.");
|
|
2218
|
+
const context = {
|
|
2219
|
+
projectDir: cwd,
|
|
2220
|
+
platformApiUrl,
|
|
2221
|
+
authKind: "formal-account",
|
|
2222
|
+
accessToken: account.credentials.accessToken,
|
|
2223
|
+
refreshToken: account.credentials.refreshToken,
|
|
2224
|
+
user,
|
|
2225
|
+
ossHost: platformApiUrl,
|
|
2226
|
+
placeId: savedPlaceId,
|
|
2227
|
+
restaurantName: options.restaurantName,
|
|
2228
|
+
city: options.city
|
|
2229
|
+
};
|
|
2230
|
+
let restaurant = {
|
|
2231
|
+
name: options.restaurantName,
|
|
2232
|
+
city: options.city
|
|
2233
|
+
};
|
|
2234
|
+
if (!context.placeId) {
|
|
2235
|
+
const resolvedRestaurant = await resolveShadowRestaurantInfo(options, deps);
|
|
2236
|
+
restaurant = resolvedRestaurant;
|
|
2237
|
+
context.placeId = await resolvePlaceIdWithFormalSearch({
|
|
2238
|
+
context,
|
|
2239
|
+
restaurant: resolvedRestaurant,
|
|
2240
|
+
deps
|
|
2241
|
+
});
|
|
2242
|
+
context.restaurantName = resolvedRestaurant.name;
|
|
2243
|
+
context.city = resolvedRestaurant.city;
|
|
2244
|
+
}
|
|
2245
|
+
return {
|
|
2246
|
+
status: "ready",
|
|
2247
|
+
context,
|
|
2248
|
+
restaurant
|
|
2249
|
+
};
|
|
2250
|
+
}
|
|
2251
|
+
async function resolveShadowProjectContext(cwd, options, deps, preferredEmail) {
|
|
2025
2252
|
const saved = await readSavedForgewayMetadata(cwd);
|
|
2026
2253
|
const platformApiUrl = resolvePlatformApiUrl(saved.platformApiUrl);
|
|
2027
2254
|
const savedPlaceId = options.placeId ?? getEnv("DINEWAY_PLACE_ID") ?? (typeof saved.placeId === "string" ? saved.placeId : void 0);
|
|
@@ -2077,8 +2304,7 @@ async function resolveShadowProjectContext(cwd, options, deps) {
|
|
|
2077
2304
|
restaurantName: restaurant.name,
|
|
2078
2305
|
city: restaurant.city
|
|
2079
2306
|
};
|
|
2080
|
-
const
|
|
2081
|
-
const credentialsResult = await resolveFormalAccountCredentials(shadowContext, grant, accountEmail, options, deps);
|
|
2307
|
+
const credentialsResult = await resolveFormalAccountCredentials(shadowContext, await resolveForgewayAccountEmail(options, saved, deps, preferredEmail), options, deps);
|
|
2082
2308
|
if (credentialsResult.status === "otp-sent") return credentialsResult;
|
|
2083
2309
|
const { credentials } = credentialsResult;
|
|
2084
2310
|
return {
|
|
@@ -2095,7 +2321,13 @@ async function resolveShadowProjectContext(cwd, options, deps) {
|
|
|
2095
2321
|
};
|
|
2096
2322
|
}
|
|
2097
2323
|
async function resolveProjectContext(cwd, options, deps) {
|
|
2098
|
-
|
|
2324
|
+
let preferredEmail;
|
|
2325
|
+
if (!options.sendOtp && !options.otp) {
|
|
2326
|
+
const formal = await resolveFormalProjectContext(cwd, options, deps);
|
|
2327
|
+
if (formal.status !== "missing") return formal;
|
|
2328
|
+
preferredEmail = formal.email;
|
|
2329
|
+
}
|
|
2330
|
+
return await resolveShadowProjectContext(cwd, options, deps, preferredEmail);
|
|
2099
2331
|
}
|
|
2100
2332
|
async function createShadowUser(platformApiUrl, placeId, deps) {
|
|
2101
2333
|
const response = await forgewayRequest(`${platformApiUrl}/api/auth/users/shadow`, {
|
|
@@ -2344,7 +2576,7 @@ async function bindShadowGrantPlace(options) {
|
|
|
2344
2576
|
refreshToken: payload.refreshToken ?? context.refreshToken ?? options.grant.refreshToken,
|
|
2345
2577
|
restaurantName: options.restaurant.name,
|
|
2346
2578
|
city: options.restaurant.city,
|
|
2347
|
-
user: payload.user ? normalizeForgewayUser(payload.user) : context.user ?? options.grant.user
|
|
2579
|
+
user: payload.user ? normalizeForgewayUser$1(payload.user) : context.user ?? options.grant.user
|
|
2348
2580
|
});
|
|
2349
2581
|
await (options.deps.writeShadowGrant ?? writeForgewayShadowGrant)(grant, options.cwd);
|
|
2350
2582
|
return grant;
|
|
@@ -2364,6 +2596,20 @@ async function resolvePlaceIdWithShadowSearch(options) {
|
|
|
2364
2596
|
placeId: finalPlaceId
|
|
2365
2597
|
});
|
|
2366
2598
|
}
|
|
2599
|
+
async function resolvePlaceIdWithFormalSearch(options) {
|
|
2600
|
+
const candidates = extractPlaceCandidates(await ossFetch(options.context, "/api/places/search", options.deps, {
|
|
2601
|
+
method: "POST",
|
|
2602
|
+
body: JSON.stringify({ textQuery: `${options.restaurant.name} in ${options.restaurant.city}` })
|
|
2603
|
+
}));
|
|
2604
|
+
if (candidates.length === 0) throw new Error(`Dineway place search returned no candidates for "${options.restaurant.name} in ${options.restaurant.city}".`);
|
|
2605
|
+
const selected = selectPlaceCandidate(candidates, {
|
|
2606
|
+
name: options.restaurant.name,
|
|
2607
|
+
city: options.restaurant.city
|
|
2608
|
+
});
|
|
2609
|
+
const finalPlaceId = selected ? candidatePlaceId(selected.candidate) : "";
|
|
2610
|
+
if (!PLACE_ID_PATTERN.test(finalPlaceId)) throw new Error("Could not resolve a valid Dineway place id for Forgeway deploy.");
|
|
2611
|
+
return finalPlaceId;
|
|
2612
|
+
}
|
|
2367
2613
|
async function createShadowGrant(options) {
|
|
2368
2614
|
if (options.placeId && !PLACE_ID_PATTERN.test(options.placeId)) throw new Error("Could not resolve a valid Dineway place id for Forgeway deploy.");
|
|
2369
2615
|
const auth = await createShadowUser(options.platformApiUrl, options.placeId, options.deps);
|
|
@@ -2374,14 +2620,14 @@ async function createShadowGrant(options) {
|
|
|
2374
2620
|
refreshToken: auth.refreshToken,
|
|
2375
2621
|
restaurantName: options.restaurantName,
|
|
2376
2622
|
city: options.city,
|
|
2377
|
-
user: auth.user ? normalizeForgewayUser(auth.user) : void 0,
|
|
2623
|
+
user: auth.user ? normalizeForgewayUser$1(auth.user) : void 0,
|
|
2378
2624
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2379
2625
|
};
|
|
2380
2626
|
await (options.deps.writeShadowGrant ?? writeForgewayShadowGrant)(grant, options.cwd);
|
|
2381
2627
|
return grant;
|
|
2382
2628
|
}
|
|
2383
2629
|
async function ossFetch(context, path, deps, options = {}) {
|
|
2384
|
-
const request = async (token) => await forgewayRequest(`${context.ossHost.replace(TRAILING_SLASH_PATTERN, "")}${path}`, {
|
|
2630
|
+
const request = async (token) => await forgewayRequest(`${context.ossHost.replace(TRAILING_SLASH_PATTERN$1, "")}${path}`, {
|
|
2385
2631
|
...options,
|
|
2386
2632
|
headers: {
|
|
2387
2633
|
"Content-Type": "application/json",
|
|
@@ -2861,6 +3107,8 @@ async function deployForgeway(cwd, options, deps = {}) {
|
|
|
2861
3107
|
const sourceDir = resolve(cwd);
|
|
2862
3108
|
if (!(await stat(sourceDir).catch(() => null))?.isDirectory()) throw new Error(`"${sourceDir}" is not a valid directory.`);
|
|
2863
3109
|
if (EXCLUDE_PATTERNS.includes(basename(sourceDir))) throw new Error(`"${basename(sourceDir)}" is an excluded directory and cannot be deployed.`);
|
|
3110
|
+
const database = parseDatabaseMode(options.database);
|
|
3111
|
+
if (database !== "none") await assertProjectDinewayRuntimeCompatible(cwd, deps.dinewayVersion ?? VERSION);
|
|
2864
3112
|
await ensureProjectGitignoreDinewayLocalState(cwd);
|
|
2865
3113
|
const verbose = isVerboseDeploy(options);
|
|
2866
3114
|
const project = await resolveProjectContext(cwd, options, deps);
|
|
@@ -2870,7 +3118,6 @@ async function deployForgeway(cwd, options, deps = {}) {
|
|
|
2870
3118
|
if (options.skipSeed) consola.info("Skipping seed initialization by request");
|
|
2871
3119
|
await ensureRestaurantClaim(context, restaurant, deps);
|
|
2872
3120
|
const { site } = await resolveDeploymentSite(cwd, context, options, seedPath, deps, restaurant);
|
|
2873
|
-
const database = parseDatabaseMode(options.database);
|
|
2874
3121
|
if (database !== "none") {
|
|
2875
3122
|
consola.start("Initializing Forgeway managed database");
|
|
2876
3123
|
try {
|
|
@@ -2905,6 +3152,7 @@ async function deployForgeway(cwd, options, deps = {}) {
|
|
|
2905
3152
|
deps,
|
|
2906
3153
|
verbose
|
|
2907
3154
|
});
|
|
3155
|
+
if (context.user?.email) await writeForgewayDeployMetadata(cwd, { publisherEmail: normalizeEmail$1(context.user.email) });
|
|
2908
3156
|
const url = deployment.liveUrl ?? `https://${site.domain}`;
|
|
2909
3157
|
await (deps.writeProjectEnv ?? persistForgewayCliEnv)(cwd, {
|
|
2910
3158
|
siteUrl: url,
|
|
@@ -3961,15 +4209,77 @@ async function exportSeed(db, withContent) {
|
|
|
3961
4209
|
};
|
|
3962
4210
|
seed.settings = await exportSettings(db);
|
|
3963
4211
|
seed.collections = await exportCollections(db);
|
|
3964
|
-
|
|
3965
|
-
seed.
|
|
4212
|
+
const i18nEnabled = await detectI18nEnabled(db, seed.collections);
|
|
4213
|
+
seed.taxonomies = await exportTaxonomies(db, i18nEnabled);
|
|
4214
|
+
seed.menus = await exportMenus(db, i18nEnabled);
|
|
3966
4215
|
seed.widgetAreas = await exportWidgetAreas(db);
|
|
4216
|
+
const { bylines, idToSeedId: bylineIdToSeedId } = await exportBylines(db);
|
|
4217
|
+
if (bylines.length > 0) seed.bylines = bylines;
|
|
3967
4218
|
if (withContent !== void 0) {
|
|
3968
4219
|
const collections = withContent === "" || withContent === "true" ? null : withContent.split(",").map((s) => s.trim()).filter(Boolean);
|
|
3969
|
-
seed.content = await exportContent(db, seed.collections || [], collections);
|
|
4220
|
+
seed.content = await exportContent(db, seed.collections || [], collections, bylineIdToSeedId, i18nEnabled);
|
|
3970
4221
|
}
|
|
3971
4222
|
return seed;
|
|
3972
4223
|
}
|
|
4224
|
+
async function exportBylines(db) {
|
|
4225
|
+
const bylineRepo = new BylineRepository(db);
|
|
4226
|
+
const bylines = [];
|
|
4227
|
+
const idToSeedId = /* @__PURE__ */ new Map();
|
|
4228
|
+
let cursor;
|
|
4229
|
+
do {
|
|
4230
|
+
const result = await bylineRepo.findMany({
|
|
4231
|
+
limit: 100,
|
|
4232
|
+
cursor
|
|
4233
|
+
});
|
|
4234
|
+
for (const byline of result.items) {
|
|
4235
|
+
const seedId = `byline:${byline.slug}`;
|
|
4236
|
+
idToSeedId.set(byline.id, seedId);
|
|
4237
|
+
bylines.push({
|
|
4238
|
+
id: seedId,
|
|
4239
|
+
slug: byline.slug,
|
|
4240
|
+
displayName: byline.displayName,
|
|
4241
|
+
bio: byline.bio || void 0,
|
|
4242
|
+
websiteUrl: byline.websiteUrl || void 0,
|
|
4243
|
+
isGuest: byline.isGuest || void 0
|
|
4244
|
+
});
|
|
4245
|
+
}
|
|
4246
|
+
cursor = result.nextCursor;
|
|
4247
|
+
} while (cursor);
|
|
4248
|
+
return {
|
|
4249
|
+
bylines,
|
|
4250
|
+
idToSeedId
|
|
4251
|
+
};
|
|
4252
|
+
}
|
|
4253
|
+
/**
|
|
4254
|
+
* Determine whether export should preserve locale-suffixed seed ids.
|
|
4255
|
+
*
|
|
4256
|
+
* Runtime i18n config is initialized by middleware, but `dineway export-seed`
|
|
4257
|
+
* runs in a CLI process. When the runtime flag is unset, derive multi-locale
|
|
4258
|
+
* status from stored rows instead: a project is multi-locale when any
|
|
4259
|
+
* i18n-aware table contains more than one distinct locale.
|
|
4260
|
+
*/
|
|
4261
|
+
async function detectI18nEnabled(db, collections) {
|
|
4262
|
+
if (isI18nEnabled()) return true;
|
|
4263
|
+
const locales = /* @__PURE__ */ new Set();
|
|
4264
|
+
const collectDistinctLocales = async (tableRef) => {
|
|
4265
|
+
const result = await sql`
|
|
4266
|
+
SELECT DISTINCT locale FROM ${tableRef}
|
|
4267
|
+
`.execute(db);
|
|
4268
|
+
for (const row of result.rows) if (row.locale) locales.add(row.locale);
|
|
4269
|
+
return locales.size > 1;
|
|
4270
|
+
};
|
|
4271
|
+
if (await collectDistinctLocales(sql.ref("_dineway_taxonomy_defs"))) return true;
|
|
4272
|
+
if (await collectDistinctLocales(sql.ref("_dineway_menus"))) return true;
|
|
4273
|
+
for (const collection of collections) {
|
|
4274
|
+
validateIdentifier(collection.slug, "collection slug");
|
|
4275
|
+
try {
|
|
4276
|
+
if (await collectDistinctLocales(sql.ref(`ec_${collection.slug}`))) return true;
|
|
4277
|
+
} catch (error) {
|
|
4278
|
+
if (!isMissingTableError(error)) throw error;
|
|
4279
|
+
}
|
|
4280
|
+
}
|
|
4281
|
+
return false;
|
|
4282
|
+
}
|
|
3973
4283
|
/**
|
|
3974
4284
|
* Export site settings
|
|
3975
4285
|
*/
|
|
@@ -4019,8 +4329,7 @@ async function exportCollections(db) {
|
|
|
4019
4329
|
/**
|
|
4020
4330
|
* Export taxonomy definitions and terms
|
|
4021
4331
|
*/
|
|
4022
|
-
async function exportTaxonomies(db) {
|
|
4023
|
-
const i18nEnabled = isI18nEnabled();
|
|
4332
|
+
async function exportTaxonomies(db, i18nEnabled) {
|
|
4024
4333
|
const defs = await db.selectFrom("_dineway_taxonomy_defs").selectAll().orderBy(["name", "locale"]).execute();
|
|
4025
4334
|
const result = [];
|
|
4026
4335
|
const termRepo = new TaxonomyRepository(db);
|
|
@@ -4077,8 +4386,7 @@ async function exportTaxonomies(db) {
|
|
|
4077
4386
|
/**
|
|
4078
4387
|
* Export menus with their items
|
|
4079
4388
|
*/
|
|
4080
|
-
async function exportMenus(db) {
|
|
4081
|
-
const i18nEnabled = isI18nEnabled();
|
|
4389
|
+
async function exportMenus(db, i18nEnabled) {
|
|
4082
4390
|
const menus = await db.selectFrom("_dineway_menus").selectAll().orderBy(["name", "locale"]).execute();
|
|
4083
4391
|
const result = [];
|
|
4084
4392
|
const groupToSeedId = /* @__PURE__ */ new Map();
|
|
@@ -4200,11 +4508,12 @@ async function exportWidgetAreas(db) {
|
|
|
4200
4508
|
/**
|
|
4201
4509
|
* Export content from collections
|
|
4202
4510
|
*/
|
|
4203
|
-
async function exportContent(db, collections, includeCollections) {
|
|
4511
|
+
async function exportContent(db, collections, includeCollections, bylineIdToSeedId, i18nEnabled) {
|
|
4204
4512
|
const content = {};
|
|
4205
4513
|
const contentRepo = new ContentRepository(db);
|
|
4206
4514
|
const taxonomyRepo = new TaxonomyRepository(db);
|
|
4207
4515
|
const mediaRepo = new MediaRepository(db);
|
|
4516
|
+
const bylineRepo = new BylineRepository(db);
|
|
4208
4517
|
const mediaMap = /* @__PURE__ */ new Map();
|
|
4209
4518
|
try {
|
|
4210
4519
|
let cursor;
|
|
@@ -4223,7 +4532,6 @@ async function exportContent(db, collections, includeCollections) {
|
|
|
4223
4532
|
cursor = result.nextCursor;
|
|
4224
4533
|
} while (cursor);
|
|
4225
4534
|
} catch {}
|
|
4226
|
-
const i18nEnabled = isI18nEnabled();
|
|
4227
4535
|
for (const collection of collections) {
|
|
4228
4536
|
if (includeCollections && !includeCollections.includes(collection.slug)) continue;
|
|
4229
4537
|
const entries = [];
|
|
@@ -4253,6 +4561,8 @@ async function exportContent(db, collections, includeCollections) {
|
|
|
4253
4561
|
}
|
|
4254
4562
|
const taxonomies = await getTaxonomyAssignments(taxonomyRepo, collection.slug, item.id);
|
|
4255
4563
|
if (Object.keys(taxonomies).length > 0) entry.taxonomies = taxonomies;
|
|
4564
|
+
const bylines = await getBylineCredits(bylineRepo, collection.slug, item.id, bylineIdToSeedId);
|
|
4565
|
+
if (bylines.length > 0) entry.bylines = bylines;
|
|
4256
4566
|
entries.push(entry);
|
|
4257
4567
|
}
|
|
4258
4568
|
cursor = result.nextCursor;
|
|
@@ -4299,6 +4609,15 @@ function processDataForExport(data, fields, mediaMap) {
|
|
|
4299
4609
|
}
|
|
4300
4610
|
return result;
|
|
4301
4611
|
}
|
|
4612
|
+
async function getBylineCredits(bylineRepo, collection, entryId, bylineIdToSeedId) {
|
|
4613
|
+
return (await bylineRepo.getContentBylines(collection, entryId)).flatMap((credit) => {
|
|
4614
|
+
const seedId = bylineIdToSeedId.get(credit.byline.id);
|
|
4615
|
+
if (!seedId) return [];
|
|
4616
|
+
const seedCredit = { byline: seedId };
|
|
4617
|
+
if (credit.roleLabel) seedCredit.roleLabel = credit.roleLabel;
|
|
4618
|
+
return [seedCredit];
|
|
4619
|
+
});
|
|
4620
|
+
}
|
|
4302
4621
|
/**
|
|
4303
4622
|
* Get taxonomy term assignments for a content entry
|
|
4304
4623
|
*/
|
|
@@ -4977,6 +5296,9 @@ const MAX_SCREENSHOTS = 5;
|
|
|
4977
5296
|
const MAX_SCREENSHOT_WIDTH = 1920;
|
|
4978
5297
|
const MAX_SCREENSHOT_HEIGHT = 1080;
|
|
4979
5298
|
const ICON_SIZE = 256;
|
|
5299
|
+
function toFileImportSpecifier(filePath) {
|
|
5300
|
+
return pathToFileURL(filePath).href;
|
|
5301
|
+
}
|
|
4980
5302
|
/** Matches Node.js built-in imports in bundled output. */
|
|
4981
5303
|
const NODE_BUILTIN_IMPORT_RE = /(?:import|export|require)\s*(?:\(|[^(]*?\bfrom\s+)["'](?:node:)?([a-z_]+)(?:\/[^"']*)?\s*["']\)?/g;
|
|
4982
5304
|
const LEADING_DOT_SLASH_RE = /^\.\//;
|
|
@@ -5303,7 +5625,7 @@ const bundleCommand = defineCommand({
|
|
|
5303
5625
|
consola.error("Failed to build main entry — no output found in", mainOutDir);
|
|
5304
5626
|
process.exit(1);
|
|
5305
5627
|
}
|
|
5306
|
-
const pluginModule = await import(mainOutputPath);
|
|
5628
|
+
const pluginModule = await import(toFileImportSpecifier(mainOutputPath));
|
|
5307
5629
|
let resolvedPlugin;
|
|
5308
5630
|
if (typeof pluginModule.createPlugin === "function") resolvedPlugin = pluginModule.createPlugin();
|
|
5309
5631
|
else if (typeof pluginModule.default === "function") resolvedPlugin = pluginModule.default();
|
|
@@ -5347,7 +5669,7 @@ const bundleCommand = defineCommand({
|
|
|
5347
5669
|
});
|
|
5348
5670
|
const backendProbePath = await findBuildOutput(backendProbeDir, basename(backendEntry).replace(TS_EXT_RE, ""));
|
|
5349
5671
|
if (backendProbePath) {
|
|
5350
|
-
const standardDef = (await import(backendProbePath)).default ?? {};
|
|
5672
|
+
const standardDef = (await import(toFileImportSpecifier(backendProbePath))).default ?? {};
|
|
5351
5673
|
const hooks = standardDef.hooks;
|
|
5352
5674
|
const routes = standardDef.routes;
|
|
5353
5675
|
if (hooks) for (const hookName of Object.keys(hooks)) {
|
|
@@ -6858,6 +7180,586 @@ const seedCommand = defineCommand({
|
|
|
6858
7180
|
}
|
|
6859
7181
|
});
|
|
6860
7182
|
|
|
7183
|
+
//#endregion
|
|
7184
|
+
//#region src/cli/forgeway-seo-client.ts
|
|
7185
|
+
const DEFAULT_DINEWAY_API_BASE_URL = "https://api.dineway.ai";
|
|
7186
|
+
const TRAILING_SLASH_PATTERN = /\/$/;
|
|
7187
|
+
const SHADOW_EMAIL_PATTERN = /^shadow_[a-f0-9]{16}@dineway\.ai$/i;
|
|
7188
|
+
var ForgewaySeoApiError = class extends Error {
|
|
7189
|
+
constructor(message, status, body) {
|
|
7190
|
+
super(message);
|
|
7191
|
+
this.status = status;
|
|
7192
|
+
this.body = body;
|
|
7193
|
+
this.name = "ForgewaySeoApiError";
|
|
7194
|
+
}
|
|
7195
|
+
};
|
|
7196
|
+
function normalizeApiUrl(value) {
|
|
7197
|
+
return (value || DEFAULT_DINEWAY_API_BASE_URL).replace(TRAILING_SLASH_PATTERN, "");
|
|
7198
|
+
}
|
|
7199
|
+
function resolveForgewaySeoApiUrl(savedPlatformApiUrl, cwd = process.cwd()) {
|
|
7200
|
+
return normalizeApiUrl(getProjectEnvValue("DINEWAY_API_BASE_URL", cwd) ?? (typeof savedPlatformApiUrl === "string" ? savedPlatformApiUrl : void 0));
|
|
7201
|
+
}
|
|
7202
|
+
function normalizeEmail(value) {
|
|
7203
|
+
return value?.trim().toLowerCase() ?? "";
|
|
7204
|
+
}
|
|
7205
|
+
function isShadowEmail(email) {
|
|
7206
|
+
return Boolean(email && SHADOW_EMAIL_PATTERN.test(email));
|
|
7207
|
+
}
|
|
7208
|
+
function assertFormalUser(user) {
|
|
7209
|
+
if (!user || user.emailVerified !== true || isShadowEmail(user.email)) throw new Error("Forgeway SEO provider access requires verified formal Forgeway credentials. Run `dineway deploy forgeway` and complete email verification first.");
|
|
7210
|
+
return user;
|
|
7211
|
+
}
|
|
7212
|
+
function normalizeForgewayUser(user, fallback) {
|
|
7213
|
+
if (!user?.id || !user.email) return fallback;
|
|
7214
|
+
return {
|
|
7215
|
+
id: user.id,
|
|
7216
|
+
name: user.profile?.name ?? user.name ?? user.email,
|
|
7217
|
+
email: user.email,
|
|
7218
|
+
avatarUrl: user.profile?.avatar_url ?? user.avatarUrl ?? user.avatar_url ?? null,
|
|
7219
|
+
emailVerified: user.emailVerified ?? user.email_verified ?? false
|
|
7220
|
+
};
|
|
7221
|
+
}
|
|
7222
|
+
async function parseJsonResponse(response) {
|
|
7223
|
+
const text = await response.text();
|
|
7224
|
+
if (!text) return {};
|
|
7225
|
+
try {
|
|
7226
|
+
return JSON.parse(text);
|
|
7227
|
+
} catch {
|
|
7228
|
+
return { message: text };
|
|
7229
|
+
}
|
|
7230
|
+
}
|
|
7231
|
+
function errorMessage(body, fallback) {
|
|
7232
|
+
if (typeof body !== "object" || body === null) return fallback;
|
|
7233
|
+
const record = body;
|
|
7234
|
+
if (typeof record.message === "string") return record.message;
|
|
7235
|
+
if (typeof record.error === "string") return record.error;
|
|
7236
|
+
const nestedError = record.error;
|
|
7237
|
+
if (typeof nestedError === "object" && nestedError !== null) {
|
|
7238
|
+
const message = nestedError.message;
|
|
7239
|
+
if (typeof message === "string") return message;
|
|
7240
|
+
}
|
|
7241
|
+
return fallback;
|
|
7242
|
+
}
|
|
7243
|
+
var ForgewaySeoGatewayClient = class {
|
|
7244
|
+
fetchImpl;
|
|
7245
|
+
readCredentials;
|
|
7246
|
+
writeCredentials;
|
|
7247
|
+
cwd;
|
|
7248
|
+
constructor(deps = {}) {
|
|
7249
|
+
this.fetchImpl = deps.fetch ?? fetch;
|
|
7250
|
+
this.readCredentials = deps.readCredentials ?? readForgewayCredentials;
|
|
7251
|
+
this.writeCredentials = deps.writeCredentials ?? writeForgewayCredentials;
|
|
7252
|
+
this.cwd = deps.cwd ?? process.cwd();
|
|
7253
|
+
}
|
|
7254
|
+
async loadCredentials() {
|
|
7255
|
+
const metadata = await readForgewayDeployMetadata(this.cwd).catch(() => ({}));
|
|
7256
|
+
const platformApiUrl = resolveForgewaySeoApiUrl(metadata.platformApiUrl, this.cwd);
|
|
7257
|
+
const credentials = await this.readCredentials({
|
|
7258
|
+
cwd: this.cwd,
|
|
7259
|
+
platformApiUrl,
|
|
7260
|
+
email: typeof metadata.publisherEmail === "string" ? metadata.publisherEmail : void 0
|
|
7261
|
+
});
|
|
7262
|
+
if (!credentials?.accessToken) throw new Error("Forgeway SEO provider access requires stored Forgeway credentials. Run `dineway deploy forgeway` first.");
|
|
7263
|
+
assertFormalUser(credentials.user);
|
|
7264
|
+
if (!credentials.refreshToken) throw new Error("Forgeway SEO provider access requires a stored formal-account refresh token. Run `dineway deploy forgeway` again.");
|
|
7265
|
+
return {
|
|
7266
|
+
...credentials,
|
|
7267
|
+
platformApiUrl: resolveForgewaySeoApiUrl(credentials.platformApiUrl, this.cwd)
|
|
7268
|
+
};
|
|
7269
|
+
}
|
|
7270
|
+
async refreshAccessToken(credentials) {
|
|
7271
|
+
const response = await this.fetchImpl(`${credentials.platformApiUrl}/api/auth/refresh?client_type=server`, {
|
|
7272
|
+
method: "POST",
|
|
7273
|
+
headers: { "Content-Type": "application/json" },
|
|
7274
|
+
body: JSON.stringify({ refreshToken: credentials.refreshToken })
|
|
7275
|
+
});
|
|
7276
|
+
const body = await parseJsonResponse(response);
|
|
7277
|
+
if (!response.ok) throw new ForgewaySeoApiError(errorMessage(body, "Failed to refresh Forgeway formal account credentials. Run `dineway deploy forgeway` again."), response.status, body);
|
|
7278
|
+
if (!body.accessToken) throw new Error("Forgeway refresh response was missing accessToken.");
|
|
7279
|
+
const user = assertFormalUser(normalizeForgewayUser(body.user, credentials.user));
|
|
7280
|
+
if (credentials.user?.email && normalizeEmail(user.email) !== normalizeEmail(credentials.user.email)) throw new Error("Forgeway refresh returned credentials for a different email.");
|
|
7281
|
+
const updated = {
|
|
7282
|
+
...credentials,
|
|
7283
|
+
accessToken: body.accessToken,
|
|
7284
|
+
refreshToken: body.refreshToken ?? credentials.refreshToken,
|
|
7285
|
+
user
|
|
7286
|
+
};
|
|
7287
|
+
await this.writeCredentials(updated, {
|
|
7288
|
+
cwd: this.cwd,
|
|
7289
|
+
platformApiUrl: updated.platformApiUrl,
|
|
7290
|
+
email: user.email
|
|
7291
|
+
});
|
|
7292
|
+
return updated;
|
|
7293
|
+
}
|
|
7294
|
+
async request(path, body, init) {
|
|
7295
|
+
const credentials = await this.refreshAccessToken(await this.loadCredentials());
|
|
7296
|
+
const response = await this.fetchImpl(`${credentials.platformApiUrl}${path}`, {
|
|
7297
|
+
method: init?.method ?? "POST",
|
|
7298
|
+
headers: {
|
|
7299
|
+
Authorization: `Bearer ${credentials.accessToken}`,
|
|
7300
|
+
"Content-Type": "application/json"
|
|
7301
|
+
},
|
|
7302
|
+
body: init?.method === "GET" ? void 0 : JSON.stringify(body ?? {})
|
|
7303
|
+
});
|
|
7304
|
+
const payload = await parseJsonResponse(response);
|
|
7305
|
+
if (!response.ok) throw new ForgewaySeoApiError(errorMessage(payload, `Forgeway SEO request failed with status ${response.status}.`), response.status, payload);
|
|
7306
|
+
return payload;
|
|
7307
|
+
}
|
|
7308
|
+
};
|
|
7309
|
+
|
|
7310
|
+
//#endregion
|
|
7311
|
+
//#region src/cli/commands/seo.ts
|
|
7312
|
+
const hostedProviderArgs = {
|
|
7313
|
+
json: {
|
|
7314
|
+
type: "boolean",
|
|
7315
|
+
description: "Output as JSON"
|
|
7316
|
+
},
|
|
7317
|
+
"force-refresh": {
|
|
7318
|
+
type: "boolean",
|
|
7319
|
+
description: "Bypass Forgeway SEO provider cache"
|
|
7320
|
+
}
|
|
7321
|
+
};
|
|
7322
|
+
const dataForSeoCommonArgs = {
|
|
7323
|
+
...hostedProviderArgs,
|
|
7324
|
+
"location-code": {
|
|
7325
|
+
type: "string",
|
|
7326
|
+
description: "DataForSEO location code",
|
|
7327
|
+
default: "2840"
|
|
7328
|
+
},
|
|
7329
|
+
"language-code": {
|
|
7330
|
+
type: "string",
|
|
7331
|
+
description: "DataForSEO language code",
|
|
7332
|
+
default: "en"
|
|
7333
|
+
},
|
|
7334
|
+
device: {
|
|
7335
|
+
type: "string",
|
|
7336
|
+
description: "Device type: desktop or mobile",
|
|
7337
|
+
default: "desktop"
|
|
7338
|
+
}
|
|
7339
|
+
};
|
|
7340
|
+
function toStringValue(value) {
|
|
7341
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
7342
|
+
}
|
|
7343
|
+
function toNumberValue(value, fallback) {
|
|
7344
|
+
const raw = toStringValue(value);
|
|
7345
|
+
if (!raw) return fallback;
|
|
7346
|
+
const parsed = Number(raw);
|
|
7347
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
7348
|
+
}
|
|
7349
|
+
function forceRefresh(args) {
|
|
7350
|
+
return args["force-refresh"] === true;
|
|
7351
|
+
}
|
|
7352
|
+
function formats(value) {
|
|
7353
|
+
const raw = toStringValue(value);
|
|
7354
|
+
if (!raw) return void 0;
|
|
7355
|
+
return raw.split(",").map((item) => item.trim()).filter(Boolean);
|
|
7356
|
+
}
|
|
7357
|
+
function requireArg(value, name) {
|
|
7358
|
+
const normalized = toStringValue(value);
|
|
7359
|
+
if (!normalized) throw new Error(`${name} is required.`);
|
|
7360
|
+
return normalized;
|
|
7361
|
+
}
|
|
7362
|
+
async function runSeoRequest(args, path, body) {
|
|
7363
|
+
configureOutputMode(args);
|
|
7364
|
+
try {
|
|
7365
|
+
output(await new ForgewaySeoGatewayClient().request(path, body), args);
|
|
7366
|
+
} catch (error) {
|
|
7367
|
+
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
7368
|
+
process.exit(1);
|
|
7369
|
+
}
|
|
7370
|
+
}
|
|
7371
|
+
const firecrawlCommand = defineCommand({
|
|
7372
|
+
meta: {
|
|
7373
|
+
name: "firecrawl",
|
|
7374
|
+
description: "Forgeway-hosted Firecrawl workflows"
|
|
7375
|
+
},
|
|
7376
|
+
subCommands: {
|
|
7377
|
+
scrape: defineCommand({
|
|
7378
|
+
meta: {
|
|
7379
|
+
name: "scrape",
|
|
7380
|
+
description: "Scrape one URL through Forgeway-hosted Firecrawl"
|
|
7381
|
+
},
|
|
7382
|
+
args: {
|
|
7383
|
+
url: {
|
|
7384
|
+
type: "positional",
|
|
7385
|
+
description: "URL to scrape",
|
|
7386
|
+
required: true
|
|
7387
|
+
},
|
|
7388
|
+
...hostedProviderArgs,
|
|
7389
|
+
formats: {
|
|
7390
|
+
type: "string",
|
|
7391
|
+
description: "Comma-separated Firecrawl formats",
|
|
7392
|
+
default: "markdown"
|
|
7393
|
+
},
|
|
7394
|
+
"only-main-content": {
|
|
7395
|
+
type: "boolean",
|
|
7396
|
+
description: "Return main content only",
|
|
7397
|
+
default: true
|
|
7398
|
+
},
|
|
7399
|
+
"timeout-ms": {
|
|
7400
|
+
type: "string",
|
|
7401
|
+
description: "Provider timeout in milliseconds",
|
|
7402
|
+
default: "60000"
|
|
7403
|
+
}
|
|
7404
|
+
},
|
|
7405
|
+
async run({ args }) {
|
|
7406
|
+
await runSeoRequest(args, "/api/firecrawl/scrape", {
|
|
7407
|
+
url: requireArg(args.url, "url"),
|
|
7408
|
+
formats: formats(args.formats),
|
|
7409
|
+
onlyMainContent: args["only-main-content"] !== false,
|
|
7410
|
+
timeoutMs: toNumberValue(args["timeout-ms"], 6e4),
|
|
7411
|
+
forceRefresh: forceRefresh(args)
|
|
7412
|
+
});
|
|
7413
|
+
}
|
|
7414
|
+
}),
|
|
7415
|
+
map: defineCommand({
|
|
7416
|
+
meta: {
|
|
7417
|
+
name: "map",
|
|
7418
|
+
description: "Map URLs through Forgeway-hosted Firecrawl"
|
|
7419
|
+
},
|
|
7420
|
+
args: {
|
|
7421
|
+
url: {
|
|
7422
|
+
type: "positional",
|
|
7423
|
+
description: "Base URL to map",
|
|
7424
|
+
required: true
|
|
7425
|
+
},
|
|
7426
|
+
...hostedProviderArgs,
|
|
7427
|
+
search: {
|
|
7428
|
+
type: "string",
|
|
7429
|
+
description: "Optional relevance search term"
|
|
7430
|
+
},
|
|
7431
|
+
sitemap: {
|
|
7432
|
+
type: "string",
|
|
7433
|
+
description: "Sitemap mode: skip, include, or only",
|
|
7434
|
+
default: "include"
|
|
7435
|
+
},
|
|
7436
|
+
limit: {
|
|
7437
|
+
type: "string",
|
|
7438
|
+
description: "Maximum URLs",
|
|
7439
|
+
default: "100"
|
|
7440
|
+
},
|
|
7441
|
+
"include-subdomains": {
|
|
7442
|
+
type: "boolean",
|
|
7443
|
+
description: "Include subdomains"
|
|
7444
|
+
},
|
|
7445
|
+
"ignore-query-parameters": {
|
|
7446
|
+
type: "boolean",
|
|
7447
|
+
description: "Ignore query parameters",
|
|
7448
|
+
default: true
|
|
7449
|
+
}
|
|
7450
|
+
},
|
|
7451
|
+
async run({ args }) {
|
|
7452
|
+
await runSeoRequest(args, "/api/firecrawl/map", {
|
|
7453
|
+
url: requireArg(args.url, "url"),
|
|
7454
|
+
search: toStringValue(args.search),
|
|
7455
|
+
sitemap: toStringValue(args.sitemap) ?? "include",
|
|
7456
|
+
limit: toNumberValue(args.limit, 100),
|
|
7457
|
+
includeSubdomains: args["include-subdomains"] === true,
|
|
7458
|
+
ignoreQueryParameters: args["ignore-query-parameters"] !== false,
|
|
7459
|
+
forceRefresh: forceRefresh(args)
|
|
7460
|
+
});
|
|
7461
|
+
}
|
|
7462
|
+
}),
|
|
7463
|
+
crawl: defineCommand({
|
|
7464
|
+
meta: {
|
|
7465
|
+
name: "crawl",
|
|
7466
|
+
description: "Start a bounded Firecrawl crawl, or check status with --id"
|
|
7467
|
+
},
|
|
7468
|
+
args: {
|
|
7469
|
+
url: {
|
|
7470
|
+
type: "positional",
|
|
7471
|
+
description: "Base URL to crawl"
|
|
7472
|
+
},
|
|
7473
|
+
...hostedProviderArgs,
|
|
7474
|
+
id: {
|
|
7475
|
+
type: "string",
|
|
7476
|
+
description: "Existing Firecrawl crawl id to check"
|
|
7477
|
+
},
|
|
7478
|
+
limit: {
|
|
7479
|
+
type: "string",
|
|
7480
|
+
description: "Maximum pages",
|
|
7481
|
+
default: "25"
|
|
7482
|
+
},
|
|
7483
|
+
"max-depth": {
|
|
7484
|
+
type: "string",
|
|
7485
|
+
description: "Maximum discovery depth",
|
|
7486
|
+
default: "3"
|
|
7487
|
+
},
|
|
7488
|
+
"allow-subdomains": {
|
|
7489
|
+
type: "boolean",
|
|
7490
|
+
description: "Allow subdomains"
|
|
7491
|
+
},
|
|
7492
|
+
"allow-external-links": {
|
|
7493
|
+
type: "boolean",
|
|
7494
|
+
description: "Allow external links"
|
|
7495
|
+
},
|
|
7496
|
+
formats: {
|
|
7497
|
+
type: "string",
|
|
7498
|
+
description: "Comma-separated scrape formats",
|
|
7499
|
+
default: "markdown"
|
|
7500
|
+
}
|
|
7501
|
+
},
|
|
7502
|
+
async run({ args }) {
|
|
7503
|
+
const crawlId = toStringValue(args.id);
|
|
7504
|
+
if (crawlId) {
|
|
7505
|
+
configureOutputMode(args);
|
|
7506
|
+
try {
|
|
7507
|
+
output(await new ForgewaySeoGatewayClient().request(`/api/firecrawl/crawl/${encodeURIComponent(crawlId)}`, void 0, { method: "GET" }), args);
|
|
7508
|
+
} catch (error) {
|
|
7509
|
+
consola$1.error(error instanceof Error ? error.message : "Unknown error");
|
|
7510
|
+
process.exit(1);
|
|
7511
|
+
}
|
|
7512
|
+
return;
|
|
7513
|
+
}
|
|
7514
|
+
await runSeoRequest(args, "/api/firecrawl/crawl", {
|
|
7515
|
+
url: requireArg(args.url, "url"),
|
|
7516
|
+
limit: toNumberValue(args.limit, 25),
|
|
7517
|
+
maxDiscoveryDepth: toNumberValue(args["max-depth"], 3),
|
|
7518
|
+
allowExternalLinks: args["allow-external-links"] === true,
|
|
7519
|
+
allowSubdomains: args["allow-subdomains"] === true,
|
|
7520
|
+
scrapeFormats: formats(args.formats),
|
|
7521
|
+
forceRefresh: forceRefresh(args)
|
|
7522
|
+
});
|
|
7523
|
+
}
|
|
7524
|
+
}),
|
|
7525
|
+
search: defineCommand({
|
|
7526
|
+
meta: {
|
|
7527
|
+
name: "search",
|
|
7528
|
+
description: "Search through Forgeway-hosted Firecrawl"
|
|
7529
|
+
},
|
|
7530
|
+
args: {
|
|
7531
|
+
query: {
|
|
7532
|
+
type: "positional",
|
|
7533
|
+
description: "Search query",
|
|
7534
|
+
required: true
|
|
7535
|
+
},
|
|
7536
|
+
...hostedProviderArgs,
|
|
7537
|
+
limit: {
|
|
7538
|
+
type: "string",
|
|
7539
|
+
description: "Maximum results",
|
|
7540
|
+
default: "10"
|
|
7541
|
+
},
|
|
7542
|
+
scrape: {
|
|
7543
|
+
type: "boolean",
|
|
7544
|
+
description: "Scrape result markdown"
|
|
7545
|
+
}
|
|
7546
|
+
},
|
|
7547
|
+
async run({ args }) {
|
|
7548
|
+
await runSeoRequest(args, "/api/firecrawl/search", {
|
|
7549
|
+
query: requireArg(args.query, "query"),
|
|
7550
|
+
limit: toNumberValue(args.limit, 10),
|
|
7551
|
+
scrape: args.scrape === true,
|
|
7552
|
+
forceRefresh: forceRefresh(args)
|
|
7553
|
+
});
|
|
7554
|
+
}
|
|
7555
|
+
})
|
|
7556
|
+
}
|
|
7557
|
+
});
|
|
7558
|
+
function dataForSeoBase(args) {
|
|
7559
|
+
return {
|
|
7560
|
+
locationCode: toNumberValue(args["location-code"], 2840),
|
|
7561
|
+
languageCode: toStringValue(args["language-code"]) ?? "en",
|
|
7562
|
+
device: toStringValue(args.device) ?? "desktop",
|
|
7563
|
+
forceRefresh: forceRefresh(args)
|
|
7564
|
+
};
|
|
7565
|
+
}
|
|
7566
|
+
const dataForSeoSerpCommand = defineCommand({
|
|
7567
|
+
meta: {
|
|
7568
|
+
name: "serp",
|
|
7569
|
+
description: "Fetch Google organic SERP data"
|
|
7570
|
+
},
|
|
7571
|
+
args: {
|
|
7572
|
+
keyword: {
|
|
7573
|
+
type: "positional",
|
|
7574
|
+
description: "Keyword",
|
|
7575
|
+
required: true
|
|
7576
|
+
},
|
|
7577
|
+
...dataForSeoCommonArgs,
|
|
7578
|
+
depth: {
|
|
7579
|
+
type: "string",
|
|
7580
|
+
description: "SERP depth",
|
|
7581
|
+
default: "10"
|
|
7582
|
+
}
|
|
7583
|
+
},
|
|
7584
|
+
async run({ args }) {
|
|
7585
|
+
await runSeoRequest(args, "/api/dataforseo/serp", {
|
|
7586
|
+
keyword: requireArg(args.keyword, "keyword"),
|
|
7587
|
+
depth: toNumberValue(args.depth, 10),
|
|
7588
|
+
...dataForSeoBase(args)
|
|
7589
|
+
});
|
|
7590
|
+
}
|
|
7591
|
+
});
|
|
7592
|
+
const dataForSeoMapsCommand = defineCommand({
|
|
7593
|
+
meta: {
|
|
7594
|
+
name: "maps",
|
|
7595
|
+
description: "Fetch Google Maps SERP data"
|
|
7596
|
+
},
|
|
7597
|
+
args: {
|
|
7598
|
+
keyword: {
|
|
7599
|
+
type: "positional",
|
|
7600
|
+
description: "Keyword",
|
|
7601
|
+
required: true
|
|
7602
|
+
},
|
|
7603
|
+
...dataForSeoCommonArgs,
|
|
7604
|
+
depth: {
|
|
7605
|
+
type: "string",
|
|
7606
|
+
description: "Maps depth",
|
|
7607
|
+
default: "10"
|
|
7608
|
+
}
|
|
7609
|
+
},
|
|
7610
|
+
async run({ args }) {
|
|
7611
|
+
await runSeoRequest(args, "/api/dataforseo/maps", {
|
|
7612
|
+
keyword: requireArg(args.keyword, "keyword"),
|
|
7613
|
+
depth: toNumberValue(args.depth, 10),
|
|
7614
|
+
...dataForSeoBase(args)
|
|
7615
|
+
});
|
|
7616
|
+
}
|
|
7617
|
+
});
|
|
7618
|
+
const dataForSeoKeywordsCommand = defineCommand({
|
|
7619
|
+
meta: {
|
|
7620
|
+
name: "keywords",
|
|
7621
|
+
description: "Fetch keyword suggestions"
|
|
7622
|
+
},
|
|
7623
|
+
args: {
|
|
7624
|
+
keyword: {
|
|
7625
|
+
type: "positional",
|
|
7626
|
+
description: "Seed keyword",
|
|
7627
|
+
required: true
|
|
7628
|
+
},
|
|
7629
|
+
...dataForSeoCommonArgs,
|
|
7630
|
+
limit: {
|
|
7631
|
+
type: "string",
|
|
7632
|
+
description: "Maximum suggestions",
|
|
7633
|
+
default: "20"
|
|
7634
|
+
}
|
|
7635
|
+
},
|
|
7636
|
+
async run({ args }) {
|
|
7637
|
+
await runSeoRequest(args, "/api/dataforseo/keywords", {
|
|
7638
|
+
keyword: requireArg(args.keyword, "keyword"),
|
|
7639
|
+
limit: toNumberValue(args.limit, 20),
|
|
7640
|
+
includeSerpInfo: true,
|
|
7641
|
+
includeSeedKeyword: true,
|
|
7642
|
+
...dataForSeoBase(args)
|
|
7643
|
+
});
|
|
7644
|
+
}
|
|
7645
|
+
});
|
|
7646
|
+
const dataForSeoCompetitorsCommand = defineCommand({
|
|
7647
|
+
meta: {
|
|
7648
|
+
name: "competitors",
|
|
7649
|
+
description: "Fetch competitor-domain data"
|
|
7650
|
+
},
|
|
7651
|
+
args: {
|
|
7652
|
+
domain: {
|
|
7653
|
+
type: "positional",
|
|
7654
|
+
description: "Target domain",
|
|
7655
|
+
required: true
|
|
7656
|
+
},
|
|
7657
|
+
...dataForSeoCommonArgs,
|
|
7658
|
+
limit: {
|
|
7659
|
+
type: "string",
|
|
7660
|
+
description: "Maximum competitors",
|
|
7661
|
+
default: "20"
|
|
7662
|
+
}
|
|
7663
|
+
},
|
|
7664
|
+
async run({ args }) {
|
|
7665
|
+
await runSeoRequest(args, "/api/dataforseo/competitors", {
|
|
7666
|
+
targetDomain: requireArg(args.domain, "domain"),
|
|
7667
|
+
limit: toNumberValue(args.limit, 20),
|
|
7668
|
+
...dataForSeoBase(args)
|
|
7669
|
+
});
|
|
7670
|
+
}
|
|
7671
|
+
});
|
|
7672
|
+
const dataForSeoAiScrapeCommand = defineCommand({
|
|
7673
|
+
meta: {
|
|
7674
|
+
name: "ai-scrape",
|
|
7675
|
+
description: "Fetch DataForSEO AI scraper response data"
|
|
7676
|
+
},
|
|
7677
|
+
args: {
|
|
7678
|
+
keyword: {
|
|
7679
|
+
type: "positional",
|
|
7680
|
+
description: "AI search keyword",
|
|
7681
|
+
required: true
|
|
7682
|
+
},
|
|
7683
|
+
...dataForSeoCommonArgs,
|
|
7684
|
+
platform: {
|
|
7685
|
+
type: "string",
|
|
7686
|
+
description: "AI platform: chat_gpt, gemini, or perplexity",
|
|
7687
|
+
default: "chat_gpt"
|
|
7688
|
+
}
|
|
7689
|
+
},
|
|
7690
|
+
async run({ args }) {
|
|
7691
|
+
await runSeoRequest(args, "/api/dataforseo/ai-scrape", {
|
|
7692
|
+
keyword: requireArg(args.keyword, "keyword"),
|
|
7693
|
+
platform: toStringValue(args.platform) ?? "chat_gpt",
|
|
7694
|
+
...dataForSeoBase(args)
|
|
7695
|
+
});
|
|
7696
|
+
}
|
|
7697
|
+
});
|
|
7698
|
+
const dataForSeoAiMentionsCommand = defineCommand({
|
|
7699
|
+
meta: {
|
|
7700
|
+
name: "ai-mentions",
|
|
7701
|
+
description: "Fetch DataForSEO LLM mention data"
|
|
7702
|
+
},
|
|
7703
|
+
args: {
|
|
7704
|
+
...dataForSeoCommonArgs,
|
|
7705
|
+
domain: {
|
|
7706
|
+
type: "string",
|
|
7707
|
+
description: "Target domain"
|
|
7708
|
+
},
|
|
7709
|
+
keyword: {
|
|
7710
|
+
type: "string",
|
|
7711
|
+
description: "Target keyword"
|
|
7712
|
+
},
|
|
7713
|
+
platform: {
|
|
7714
|
+
type: "string",
|
|
7715
|
+
description: "Mention platform: google or chat_gpt",
|
|
7716
|
+
default: "google"
|
|
7717
|
+
},
|
|
7718
|
+
limit: {
|
|
7719
|
+
type: "string",
|
|
7720
|
+
description: "Maximum mentions",
|
|
7721
|
+
default: "20"
|
|
7722
|
+
}
|
|
7723
|
+
},
|
|
7724
|
+
async run({ args }) {
|
|
7725
|
+
if (!toStringValue(args.domain) && !toStringValue(args.keyword)) {
|
|
7726
|
+
consola$1.error("domain or keyword is required.");
|
|
7727
|
+
process.exit(1);
|
|
7728
|
+
}
|
|
7729
|
+
await runSeoRequest(args, "/api/dataforseo/ai-mentions", {
|
|
7730
|
+
targetDomain: toStringValue(args.domain),
|
|
7731
|
+
keyword: toStringValue(args.keyword),
|
|
7732
|
+
platform: toStringValue(args.platform) ?? "google",
|
|
7733
|
+
limit: toNumberValue(args.limit, 20),
|
|
7734
|
+
...dataForSeoBase(args)
|
|
7735
|
+
});
|
|
7736
|
+
}
|
|
7737
|
+
});
|
|
7738
|
+
const dataForSeoCommand = defineCommand({
|
|
7739
|
+
meta: {
|
|
7740
|
+
name: "dataforseo",
|
|
7741
|
+
description: "Forgeway-hosted DataForSEO workflows"
|
|
7742
|
+
},
|
|
7743
|
+
subCommands: {
|
|
7744
|
+
serp: dataForSeoSerpCommand,
|
|
7745
|
+
maps: dataForSeoMapsCommand,
|
|
7746
|
+
keywords: dataForSeoKeywordsCommand,
|
|
7747
|
+
competitors: dataForSeoCompetitorsCommand,
|
|
7748
|
+
"ai-scrape": dataForSeoAiScrapeCommand,
|
|
7749
|
+
"ai-mentions": dataForSeoAiMentionsCommand
|
|
7750
|
+
}
|
|
7751
|
+
});
|
|
7752
|
+
const seoCommand = defineCommand({
|
|
7753
|
+
meta: {
|
|
7754
|
+
name: "seo",
|
|
7755
|
+
description: "Hosted SEO provider workflows through Forgeway"
|
|
7756
|
+
},
|
|
7757
|
+
subCommands: {
|
|
7758
|
+
firecrawl: firecrawlCommand,
|
|
7759
|
+
dataforseo: dataForSeoCommand
|
|
7760
|
+
}
|
|
7761
|
+
});
|
|
7762
|
+
|
|
6861
7763
|
//#endregion
|
|
6862
7764
|
//#region src/cli/commands/taxonomy.ts
|
|
6863
7765
|
/**
|
|
@@ -7074,6 +7976,7 @@ runMain(defineCommand({
|
|
|
7074
7976
|
schema: schemaCommand,
|
|
7075
7977
|
media: mediaCommand,
|
|
7076
7978
|
search: searchCommand,
|
|
7979
|
+
seo: seoCommand,
|
|
7077
7980
|
taxonomy: taxonomyCommand,
|
|
7078
7981
|
menu: menuCommand,
|
|
7079
7982
|
plugin: pluginCommand
|