@aglyn/plugins-marketplace 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/package.json +14 -14
  2. package/src/lib/components/listing-detail-editor.component.js +26 -26
  3. package/src/lib/components/listing-detail-editor.component.js.map +1 -1
  4. package/src/lib/components/plugin-review-detail.component.js +17 -3
  5. package/src/lib/components/plugin-review-detail.component.js.map +1 -1
  6. package/src/lib/components/plugin-reviews-queue.component.js +88 -12
  7. package/src/lib/components/plugin-reviews-queue.component.js.map +1 -1
  8. package/src/lib/components/site-starter-review-detail.component.d.ts +115 -0
  9. package/src/lib/components/site-starter-review-detail.component.js +785 -0
  10. package/src/lib/components/site-starter-review-detail.component.js.map +1 -0
  11. package/src/lib/components/starter-picker-shelf.component.d.ts +7 -0
  12. package/src/lib/components/starter-picker-shelf.component.js +75 -1
  13. package/src/lib/components/starter-picker-shelf.component.js.map +1 -1
  14. package/src/lib/hooks/use-starter-answers.d.ts +41 -0
  15. package/src/lib/hooks/use-starter-answers.js +75 -0
  16. package/src/lib/hooks/use-starter-answers.js.map +1 -0
  17. package/src/lib/model/listing-query.d.ts +20 -2
  18. package/src/lib/model/listing-query.js +55 -0
  19. package/src/lib/model/listing-query.js.map +1 -1
  20. package/src/lib/model/plugin-rejection-categories.d.ts +17 -2
  21. package/src/lib/model/plugin-rejection-categories.js +48 -4
  22. package/src/lib/model/plugin-rejection-categories.js.map +1 -1
  23. package/src/lib/model/plugin-review-checklist.d.ts +38 -8
  24. package/src/lib/model/plugin-review-checklist.js +60 -11
  25. package/src/lib/model/plugin-review-checklist.js.map +1 -1
  26. package/src/lib/model/plugin-review-status.d.ts +8 -0
  27. package/src/lib/model/plugin-review-status.js +34 -0
  28. package/src/lib/model/plugin-review-status.js.map +1 -1
  29. package/src/lib/model/starter-category.d.ts +58 -0
  30. package/src/lib/model/starter-category.js +79 -0
  31. package/src/lib/model/starter-category.js.map +1 -0
  32. package/src/lib/model/starter-query.d.ts +27 -0
  33. package/src/lib/model/starter-query.js +42 -0
  34. package/src/lib/model/starter-query.js.map +1 -1
  35. package/src/lib/server/admin-reviews.js +294 -45
  36. package/src/lib/server/admin-reviews.js.map +1 -1
  37. package/src/lib/server/publish-plugin.js +46 -4
  38. package/src/lib/server/publish-plugin.js.map +1 -1
  39. package/src/lib/server/publish-starter.js +4 -0
  40. package/src/lib/server/publish-starter.js.map +1 -1
  41. package/src/lib/server/publisher-review-email.d.ts +5 -0
  42. package/src/lib/server/publisher-review-email.js +2 -1
  43. package/src/lib/server/publisher-review-email.js.map +1 -1
  44. package/src/lib/server/starters.d.ts +4 -1
  45. package/src/lib/server/starters.js +128 -28
  46. package/src/lib/server/starters.js.map +1 -1
  47. package/src/lib/server.js +12 -1
  48. package/src/lib/server.js.map +1 -1
package/src/lib/server.js CHANGED
@@ -54,7 +54,7 @@ import { publishEmailStarterHandler } from "./server/publish-email-starter.js";
54
54
  import { publishEmailTemplateHandler } from "./server/publish-email-template.js";
55
55
  import { publishLayoutHandler } from "./server/publish-layout.js";
56
56
  import { publishStarterHandler } from "./server/publish-starter.js";
57
- import { marketplaceStarters } from "./server/starters.js";
57
+ import { marketplaceStarterAnswers, marketplaceStarters } from "./server/starters.js";
58
58
  import { publishTemplateHandler } from "./server/publish-template.js";
59
59
  import { publishThemeHandler } from "./server/publish-theme.js";
60
60
  import { updateArtifactHandler } from "./server/update-artifact.js";
@@ -191,6 +191,17 @@ import { updateArtifactHandler } from "./server/update-artifact.js";
191
191
  orgId: new URL(request.url).searchParams.get('orgId') || null
192
192
  })
193
193
  });
194
+ /*
195
+ * And an AI starter's answers, once one is picked (AGL-4049 phase 4): what
196
+ * fills the AI start's questions, behind the same gates and the starter's
197
+ * purchase. The same shape and subject as the search.
198
+ */ registerPluginApiRoute('marketplace/starters/answers', {
199
+ web: marketplaceStarterAnswers
200
+ }, {
201
+ subject: (request)=>({
202
+ orgId: new URL(request.url).searchParams.get('orgId') || null
203
+ })
204
+ });
194
205
  registerPluginApiRoute('marketplace/publish-theme', publishThemeHandler);
195
206
  registerPluginApiRoute('marketplace/publish-dataset-schema', publishDatasetSchemaHandler);
196
207
  registerPluginApiRoute('marketplace/publish-email-starter', publishEmailStarterHandler);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n registerBillingWebhookHandler,\n registerPluginApiRoute,\n registerCustomFieldType,\n} from '@aglyn/aglyn/server'\n// Its own subpath, never the plugin-manager barrel: what a published page\n// does not need, it must not import.\nimport { registerPluginRouteMetadata } from '@aglyn/aglyn/plugin-manager/plugin-route-metadata'\nimport { registerPluginArtifactInventory } from '@aglyn/aglyn/plugin-manager/plugin-artifact-inventory'\nimport { registerTaxReturnSource } from '@aglyn/aglyn/plugin-manager/plugin-tax-return-sources'\nimport { registerRevenueSource } from '@aglyn/aglyn/plugin-manager/plugin-revenue-sources'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { marketplaceBillingWebhookHandler } from './server/billing-webhook'\nimport { registerMarketplaceLockdown } from './server/publisher-lockdown'\nimport { publishPluginHandler } from './server/publish-plugin'\nimport { verificationRequestHandler } from './server/verification-request'\nimport { checkoutHandler } from './server/checkout'\nimport { connectHandler } from './server/connect'\nimport { installHandler } from './server/install'\nimport { installPluginHandler } from './server/install-plugin'\nimport { listingVersionsHandler } from './server/listing-versions'\nimport { RATING_FIELD } from './model/rating-field'\nimport { installDatasetSchemaHandler } from './server/install-dataset-schema'\nimport { installEmailStarterHandler } from './server/install-email-starter'\nimport { installEmailTemplateHandler } from './server/install-email-template'\nimport { installLayoutHandler } from './server/install-layout'\nimport { installTemplateHandler } from './server/install-template'\nimport { installThemeHandler } from './server/install-theme'\nimport { previewImageHandler } from './server/preview-image'\nimport { publishHandler } from './server/publish'\nimport { marketplaceArtifactInventory } from './server/artifact-inventory'\nimport { marketplaceTaxReturnSource } from './server/tax-return-source'\nimport { marketplaceRevenueSource } from './server/revenue-source'\nimport { marketplaceAdminReports } from './server/admin-reports'\nimport { marketplaceAdminReviews } from './server/admin-reviews'\nimport { marketplaceAdminOverview } from './server/admin-overview'\nimport { marketplaceAdminTrust } from './server/admin-trust'\nimport { reportHandler } from './server/report'\nimport { reviewsHandler } from './server/reviews'\nimport { publisherProfileSaveHandler } from './server/publisher-profile-save'\nimport { publishDatasetSchemaHandler } from './server/publish-dataset-schema'\nimport { publishEmailStarterHandler } from './server/publish-email-starter'\nimport { publishEmailTemplateHandler } from './server/publish-email-template'\nimport { publishLayoutHandler } from './server/publish-layout'\nimport { publishStarterHandler } from './server/publish-starter'\nimport { marketplaceStarters } from './server/starters'\nimport { publishTemplateHandler } from './server/publish-template'\nimport { publishThemeHandler } from './server/publish-theme'\nimport { updateArtifactHandler } from './server/update-artifact'\n\n/**\n * Registers the marketplace plugin's console-side API routes (AGL-396):\n * marketplace publish/install of templates and plugins, and the Stripe\n * Connect + checkout flows for paid listings.\n *\n * Upload-bodied routes register here too. The note that used to sit here —\n * that they had to stay as named console routes because the dispatcher\n * \"can't grant per-route bodyParser limits\" — was a Pages Router leftover:\n * `runLegacyHandler` reads the request through the same\n * `pluginRequestFromWeb` a named App Router route would, and imposes no\n * limit of its own. publish-plugin's 8 MB bundle has been going through the\n * dispatcher the whole time.\n */\nexport function registerMarketplaceConsoleApi(): void {\n // Server side of the rating custom field (AGL-434): validators run\n // on import/write paths even when no client loaded the plugin.\n registerCustomFieldType(RATING_FIELD)\n /*\n * What a listing link unfurls as (AGL-876, handed to the platform by\n * AGL-3080).\n *\n * The card used to be built by a hand-written console route with a server\n * layout of its own, which is what kept that route out of the generic\n * plugin route — moving it would have dropped every listing's card with\n * nothing red. The shell asks this instead, so the card survives the move\n * and no console file reads `marketplaceListings` to build a head.\n *\n * One segment and one only: `/{org}/marketplace/{listingId}`. The hub, the\n * publish page and every other address under this route answer `null`,\n * which leaves the shell's own title exactly as it was.\n */\n registerPluginRouteMetadata(\n {\n route: 'marketplace',\n resolve: async (segments) => {\n if (segments.length !== 1) return null\n const { readListingForSocialCard } = await import(\n './server/listing-social-card.server'\n )\n const { listingSocialCard } = await import('./model/listing-social-card')\n return listingSocialCard(await readListingForSocialCard(segments[0]))\n },\n },\n // Named, because this registrar is called directly by the app's server\n // loader rather than from inside a plugin `register` fn, where the\n // loader's owner marker would be set.\n { pluginId: BUNDLE_ID },\n )\n /*\n * Who claims the bytes in the artifacts bucket (AGL-3080).\n *\n * The platform's two scheduled sweeps run from `/api/admin` routes that\n * used to walk `pluginVersions` and `marketplaceListings` themselves. They\n * ask here now — and an unregistered inventory REFUSES both runs rather\n * than reporting an empty bucket, which is the whole point of the\n * contract's shape.\n */\n registerPluginArtifactInventory(marketplaceArtifactInventory, {\n pluginId: BUNDLE_ID,\n })\n /*\n * Its sales on the operator's own sales tax return (AGL-3080): the tax a\n * marketplace charge adds on the platform's own account. The staff return\n * awaits this surface before it asks, and refuses to be filed without this\n * source — the marketplace declares `taxReturnSource`.\n */\n registerTaxReturnSource(marketplaceTaxReturnSource, { pluginId: BUNDLE_ID })\n // …and the commission its sales earn the operator, on the staff revenue\n // report — declared `revenueSource`, so a missing registration is named as\n // unread there rather than counted as zero.\n registerRevenueSource(marketplaceRevenueSource, { pluginId: BUNDLE_ID })\n registerPluginApiRoute('marketplace/checkout', checkoutHandler)\n registerPluginApiRoute('marketplace/connect', connectHandler)\n registerPluginApiRoute('marketplace/install', installHandler)\n registerPluginApiRoute('marketplace/install-plugin', installPluginHandler)\n registerPluginApiRoute('marketplace/install-layout', installLayoutHandler)\n registerPluginApiRoute('marketplace/install-template', installTemplateHandler)\n // A theme install DOES change the running site (AGL-1020) — it is the site's\n // appearance — so this route also owns the ways back: `revert` and `reset`.\n registerPluginApiRoute('marketplace/install-theme', installThemeHandler)\n registerPluginApiRoute(\n 'marketplace/install-dataset-schema',\n installDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-starter',\n installEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-template',\n installEmailTemplateHandler,\n )\n // Updating a copied artifact is its own route (AGL-1018), not a flag on\n // install: install writes the publisher's version, this one reconciles it\n // with a copy that has diverged and refuses to overwrite silently.\n registerPluginApiRoute('marketplace/update-artifact', updateArtifactHandler)\n registerPluginApiRoute('marketplace/listing-versions', listingVersionsHandler)\n registerPluginApiRoute('marketplace/preview-image', previewImageHandler)\n registerPluginApiRoute('marketplace/publish', publishHandler)\n registerPluginApiRoute('marketplace/report', reportHandler)\n /*\n * The staff end of that button (AGL-2310), moved out of\n * `apps/console/app/api/admin/` by AGL-3080. `web:` because it is a plain\n * fetch from this plugin's own staff page, not a plugin-request handler —\n * the same shape the AI plugin's `ai/admin/*` routes use, and for the same\n * reason: a staff route names no host, so there is no subject to resolve.\n */\n registerPluginApiRoute('marketplace/admin/reports', {\n web: marketplaceAdminReports,\n })\n // The review queue (AGL-432, moved by AGL-3080). Same shape and the same\n // reason: a staff route names no host, so there is no subject to resolve.\n registerPluginApiRoute('marketplace/admin/reviews', {\n web: marketplaceAdminReviews,\n })\n // Realm trust (AGL-420, moved by AGL-3080). Super-staff only, and the\n // SIGNATURE comes from the shell — the key is the console's and stays\n // there. See `server/admin-trust.ts`.\n registerPluginApiRoute('marketplace/admin/trust', {\n web: marketplaceAdminTrust,\n })\n // The staff overview's marketplace cards (AGL-3080): purchases and the\n // refund-reversal recovery queue. Staff-gated like the queues above.\n registerPluginApiRoute('marketplace/admin/overview', {\n web: marketplaceAdminOverview,\n })\n registerPluginApiRoute('marketplace/reviews', reviewsHandler)\n registerPluginApiRoute(\n 'marketplace/publisher-profile',\n publisherProfileSaveHandler,\n )\n registerPluginApiRoute(\n 'marketplace/verification-request',\n verificationRequestHandler,\n )\n registerPluginApiRoute('marketplace/publish-layout', publishLayoutHandler)\n registerPluginApiRoute('marketplace/publish-template', publishTemplateHandler)\n // A whole site as a site starter, picked in \"Create site\" (AGL-4049).\n registerPluginApiRoute('marketplace/publish-starter', publishStarterHandler)\n /*\n * And the search \"Choose your starter\" lists them from (AGL-4049):\n * summaries only, behind `hosts.create` and `release_site_starters`. `web:`\n * because it is a plain GET from this plugin's own widget that names a\n * workspace rather than a site; the subject is that workspace, so the\n * release gate in front asks about the right organization.\n */\n registerPluginApiRoute(\n 'marketplace/starters',\n { web: marketplaceStarters },\n { subject: (request) => ({ orgId: new URL(request.url).searchParams.get('orgId') || null }) },\n )\n registerPluginApiRoute('marketplace/publish-theme', publishThemeHandler)\n registerPluginApiRoute(\n 'marketplace/publish-dataset-schema',\n publishDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-starter',\n publishEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-template',\n publishEmailTemplateHandler,\n )\n // Relocated console routes (AGL-418): URLs preserved via the dispatcher.\n registerPluginApiRoute('marketplace/publish-plugin', publishPluginHandler)\n // Marketplace purchases ride the platform Stripe webhook (AGL-418).\n registerBillingWebhookHandler(marketplaceBillingWebhookHandler)\n // A workspace lock reaches the publisher's payout account and its\n // listings (AGL-3365).\n registerMarketplaceLockdown()\n}\n\n// Type-only (AGL-3080): the plugin's entitlement keys, declared by module\n// augmentation, for every program that loads this entry point.\nexport type { marketplacePlanEntitlements } from './plan-entitlements'\n"],"names":["registerBillingWebhookHandler","registerPluginApiRoute","registerCustomFieldType","registerPluginRouteMetadata","registerPluginArtifactInventory","registerTaxReturnSource","registerRevenueSource","BUNDLE_ID","marketplaceBillingWebhookHandler","registerMarketplaceLockdown","publishPluginHandler","verificationRequestHandler","checkoutHandler","connectHandler","installHandler","installPluginHandler","listingVersionsHandler","RATING_FIELD","installDatasetSchemaHandler","installEmailStarterHandler","installEmailTemplateHandler","installLayoutHandler","installTemplateHandler","installThemeHandler","previewImageHandler","publishHandler","marketplaceArtifactInventory","marketplaceTaxReturnSource","marketplaceRevenueSource","marketplaceAdminReports","marketplaceAdminReviews","marketplaceAdminOverview","marketplaceAdminTrust","reportHandler","reviewsHandler","publisherProfileSaveHandler","publishDatasetSchemaHandler","publishEmailStarterHandler","publishEmailTemplateHandler","publishLayoutHandler","publishStarterHandler","marketplaceStarters","publishTemplateHandler","publishThemeHandler","updateArtifactHandler","registerMarketplaceConsoleApi","route","resolve","segments","length","readListingForSocialCard","listingSocialCard","pluginId","web","subject","request","orgId","URL","url","searchParams","get"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n registerBillingWebhookHandler,\n registerPluginApiRoute,\n registerCustomFieldType,\n} from '@aglyn/aglyn/server'\n// Its own subpath, never the plugin-manager barrel: what a published page\n// does not need, it must not import.\nimport { registerPluginRouteMetadata } from '@aglyn/aglyn/plugin-manager/plugin-route-metadata'\nimport { registerPluginArtifactInventory } from '@aglyn/aglyn/plugin-manager/plugin-artifact-inventory'\nimport { registerTaxReturnSource } from '@aglyn/aglyn/plugin-manager/plugin-tax-return-sources'\nimport { registerRevenueSource } from '@aglyn/aglyn/plugin-manager/plugin-revenue-sources'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { marketplaceBillingWebhookHandler } from './server/billing-webhook'\nimport { registerMarketplaceLockdown } from './server/publisher-lockdown'\nimport { publishPluginHandler } from './server/publish-plugin'\nimport { verificationRequestHandler } from './server/verification-request'\nimport { checkoutHandler } from './server/checkout'\nimport { connectHandler } from './server/connect'\nimport { installHandler } from './server/install'\nimport { installPluginHandler } from './server/install-plugin'\nimport { listingVersionsHandler } from './server/listing-versions'\nimport { RATING_FIELD } from './model/rating-field'\nimport { installDatasetSchemaHandler } from './server/install-dataset-schema'\nimport { installEmailStarterHandler } from './server/install-email-starter'\nimport { installEmailTemplateHandler } from './server/install-email-template'\nimport { installLayoutHandler } from './server/install-layout'\nimport { installTemplateHandler } from './server/install-template'\nimport { installThemeHandler } from './server/install-theme'\nimport { previewImageHandler } from './server/preview-image'\nimport { publishHandler } from './server/publish'\nimport { marketplaceArtifactInventory } from './server/artifact-inventory'\nimport { marketplaceTaxReturnSource } from './server/tax-return-source'\nimport { marketplaceRevenueSource } from './server/revenue-source'\nimport { marketplaceAdminReports } from './server/admin-reports'\nimport { marketplaceAdminReviews } from './server/admin-reviews'\nimport { marketplaceAdminOverview } from './server/admin-overview'\nimport { marketplaceAdminTrust } from './server/admin-trust'\nimport { reportHandler } from './server/report'\nimport { reviewsHandler } from './server/reviews'\nimport { publisherProfileSaveHandler } from './server/publisher-profile-save'\nimport { publishDatasetSchemaHandler } from './server/publish-dataset-schema'\nimport { publishEmailStarterHandler } from './server/publish-email-starter'\nimport { publishEmailTemplateHandler } from './server/publish-email-template'\nimport { publishLayoutHandler } from './server/publish-layout'\nimport { publishStarterHandler } from './server/publish-starter'\nimport { marketplaceStarterAnswers, marketplaceStarters } from './server/starters'\nimport { publishTemplateHandler } from './server/publish-template'\nimport { publishThemeHandler } from './server/publish-theme'\nimport { updateArtifactHandler } from './server/update-artifact'\n\n/**\n * Registers the marketplace plugin's console-side API routes (AGL-396):\n * marketplace publish/install of templates and plugins, and the Stripe\n * Connect + checkout flows for paid listings.\n *\n * Upload-bodied routes register here too. The note that used to sit here —\n * that they had to stay as named console routes because the dispatcher\n * \"can't grant per-route bodyParser limits\" — was a Pages Router leftover:\n * `runLegacyHandler` reads the request through the same\n * `pluginRequestFromWeb` a named App Router route would, and imposes no\n * limit of its own. publish-plugin's 8 MB bundle has been going through the\n * dispatcher the whole time.\n */\nexport function registerMarketplaceConsoleApi(): void {\n // Server side of the rating custom field (AGL-434): validators run\n // on import/write paths even when no client loaded the plugin.\n registerCustomFieldType(RATING_FIELD)\n /*\n * What a listing link unfurls as (AGL-876, handed to the platform by\n * AGL-3080).\n *\n * The card used to be built by a hand-written console route with a server\n * layout of its own, which is what kept that route out of the generic\n * plugin route — moving it would have dropped every listing's card with\n * nothing red. The shell asks this instead, so the card survives the move\n * and no console file reads `marketplaceListings` to build a head.\n *\n * One segment and one only: `/{org}/marketplace/{listingId}`. The hub, the\n * publish page and every other address under this route answer `null`,\n * which leaves the shell's own title exactly as it was.\n */\n registerPluginRouteMetadata(\n {\n route: 'marketplace',\n resolve: async (segments) => {\n if (segments.length !== 1) return null\n const { readListingForSocialCard } = await import(\n './server/listing-social-card.server'\n )\n const { listingSocialCard } = await import('./model/listing-social-card')\n return listingSocialCard(await readListingForSocialCard(segments[0]))\n },\n },\n // Named, because this registrar is called directly by the app's server\n // loader rather than from inside a plugin `register` fn, where the\n // loader's owner marker would be set.\n { pluginId: BUNDLE_ID },\n )\n /*\n * Who claims the bytes in the artifacts bucket (AGL-3080).\n *\n * The platform's two scheduled sweeps run from `/api/admin` routes that\n * used to walk `pluginVersions` and `marketplaceListings` themselves. They\n * ask here now — and an unregistered inventory REFUSES both runs rather\n * than reporting an empty bucket, which is the whole point of the\n * contract's shape.\n */\n registerPluginArtifactInventory(marketplaceArtifactInventory, {\n pluginId: BUNDLE_ID,\n })\n /*\n * Its sales on the operator's own sales tax return (AGL-3080): the tax a\n * marketplace charge adds on the platform's own account. The staff return\n * awaits this surface before it asks, and refuses to be filed without this\n * source — the marketplace declares `taxReturnSource`.\n */\n registerTaxReturnSource(marketplaceTaxReturnSource, { pluginId: BUNDLE_ID })\n // …and the commission its sales earn the operator, on the staff revenue\n // report — declared `revenueSource`, so a missing registration is named as\n // unread there rather than counted as zero.\n registerRevenueSource(marketplaceRevenueSource, { pluginId: BUNDLE_ID })\n registerPluginApiRoute('marketplace/checkout', checkoutHandler)\n registerPluginApiRoute('marketplace/connect', connectHandler)\n registerPluginApiRoute('marketplace/install', installHandler)\n registerPluginApiRoute('marketplace/install-plugin', installPluginHandler)\n registerPluginApiRoute('marketplace/install-layout', installLayoutHandler)\n registerPluginApiRoute('marketplace/install-template', installTemplateHandler)\n // A theme install DOES change the running site (AGL-1020) — it is the site's\n // appearance — so this route also owns the ways back: `revert` and `reset`.\n registerPluginApiRoute('marketplace/install-theme', installThemeHandler)\n registerPluginApiRoute(\n 'marketplace/install-dataset-schema',\n installDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-starter',\n installEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-template',\n installEmailTemplateHandler,\n )\n // Updating a copied artifact is its own route (AGL-1018), not a flag on\n // install: install writes the publisher's version, this one reconciles it\n // with a copy that has diverged and refuses to overwrite silently.\n registerPluginApiRoute('marketplace/update-artifact', updateArtifactHandler)\n registerPluginApiRoute('marketplace/listing-versions', listingVersionsHandler)\n registerPluginApiRoute('marketplace/preview-image', previewImageHandler)\n registerPluginApiRoute('marketplace/publish', publishHandler)\n registerPluginApiRoute('marketplace/report', reportHandler)\n /*\n * The staff end of that button (AGL-2310), moved out of\n * `apps/console/app/api/admin/` by AGL-3080. `web:` because it is a plain\n * fetch from this plugin's own staff page, not a plugin-request handler —\n * the same shape the AI plugin's `ai/admin/*` routes use, and for the same\n * reason: a staff route names no host, so there is no subject to resolve.\n */\n registerPluginApiRoute('marketplace/admin/reports', {\n web: marketplaceAdminReports,\n })\n // The review queue (AGL-432, moved by AGL-3080). Same shape and the same\n // reason: a staff route names no host, so there is no subject to resolve.\n registerPluginApiRoute('marketplace/admin/reviews', {\n web: marketplaceAdminReviews,\n })\n // Realm trust (AGL-420, moved by AGL-3080). Super-staff only, and the\n // SIGNATURE comes from the shell — the key is the console's and stays\n // there. See `server/admin-trust.ts`.\n registerPluginApiRoute('marketplace/admin/trust', {\n web: marketplaceAdminTrust,\n })\n // The staff overview's marketplace cards (AGL-3080): purchases and the\n // refund-reversal recovery queue. Staff-gated like the queues above.\n registerPluginApiRoute('marketplace/admin/overview', {\n web: marketplaceAdminOverview,\n })\n registerPluginApiRoute('marketplace/reviews', reviewsHandler)\n registerPluginApiRoute(\n 'marketplace/publisher-profile',\n publisherProfileSaveHandler,\n )\n registerPluginApiRoute(\n 'marketplace/verification-request',\n verificationRequestHandler,\n )\n registerPluginApiRoute('marketplace/publish-layout', publishLayoutHandler)\n registerPluginApiRoute('marketplace/publish-template', publishTemplateHandler)\n // A whole site as a site starter, picked in \"Create site\" (AGL-4049).\n registerPluginApiRoute('marketplace/publish-starter', publishStarterHandler)\n /*\n * And the search \"Choose your starter\" lists them from (AGL-4049):\n * summaries only, behind `hosts.create` and `release_site_starters`. `web:`\n * because it is a plain GET from this plugin's own widget that names a\n * workspace rather than a site; the subject is that workspace, so the\n * release gate in front asks about the right organization.\n */\n registerPluginApiRoute(\n 'marketplace/starters',\n { web: marketplaceStarters },\n { subject: (request) => ({ orgId: new URL(request.url).searchParams.get('orgId') || null }) },\n )\n /*\n * And an AI starter's answers, once one is picked (AGL-4049 phase 4): what\n * fills the AI start's questions, behind the same gates and the starter's\n * purchase. The same shape and subject as the search.\n */\n registerPluginApiRoute(\n 'marketplace/starters/answers',\n { web: marketplaceStarterAnswers },\n { subject: (request) => ({ orgId: new URL(request.url).searchParams.get('orgId') || null }) },\n )\n registerPluginApiRoute('marketplace/publish-theme', publishThemeHandler)\n registerPluginApiRoute(\n 'marketplace/publish-dataset-schema',\n publishDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-starter',\n publishEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-template',\n publishEmailTemplateHandler,\n )\n // Relocated console routes (AGL-418): URLs preserved via the dispatcher.\n registerPluginApiRoute('marketplace/publish-plugin', publishPluginHandler)\n // Marketplace purchases ride the platform Stripe webhook (AGL-418).\n registerBillingWebhookHandler(marketplaceBillingWebhookHandler)\n // A workspace lock reaches the publisher's payout account and its\n // listings (AGL-3365).\n registerMarketplaceLockdown()\n}\n\n// Type-only (AGL-3080): the plugin's entitlement keys, declared by module\n// augmentation, for every program that loads this entry point.\nexport type { marketplacePlanEntitlements } from './plan-entitlements'\n"],"names":["registerBillingWebhookHandler","registerPluginApiRoute","registerCustomFieldType","registerPluginRouteMetadata","registerPluginArtifactInventory","registerTaxReturnSource","registerRevenueSource","BUNDLE_ID","marketplaceBillingWebhookHandler","registerMarketplaceLockdown","publishPluginHandler","verificationRequestHandler","checkoutHandler","connectHandler","installHandler","installPluginHandler","listingVersionsHandler","RATING_FIELD","installDatasetSchemaHandler","installEmailStarterHandler","installEmailTemplateHandler","installLayoutHandler","installTemplateHandler","installThemeHandler","previewImageHandler","publishHandler","marketplaceArtifactInventory","marketplaceTaxReturnSource","marketplaceRevenueSource","marketplaceAdminReports","marketplaceAdminReviews","marketplaceAdminOverview","marketplaceAdminTrust","reportHandler","reviewsHandler","publisherProfileSaveHandler","publishDatasetSchemaHandler","publishEmailStarterHandler","publishEmailTemplateHandler","publishLayoutHandler","publishStarterHandler","marketplaceStarterAnswers","marketplaceStarters","publishTemplateHandler","publishThemeHandler","updateArtifactHandler","registerMarketplaceConsoleApi","route","resolve","segments","length","readListingForSocialCard","listingSocialCard","pluginId","web","subject","request","orgId","URL","url","searchParams","get"],"mappings":"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"}