@aglyn/plugins-marketplace 1.15.0 → 1.15.2

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 (107) hide show
  1. package/README.md +1 -0
  2. package/package.json +15 -14
  3. package/src/lib/components/editor-connections-provider.component.d.ts +37 -0
  4. package/src/lib/components/editor-connections-provider.component.js +161 -0
  5. package/src/lib/components/editor-connections-provider.component.js.map +1 -0
  6. package/src/lib/components/listing-connection-credentials-card.component.d.ts +33 -0
  7. package/src/lib/components/listing-connection-credentials-card.component.js +318 -0
  8. package/src/lib/components/listing-connection-credentials-card.component.js.map +1 -0
  9. package/src/lib/components/listing-detail-page.component.js +10 -2
  10. package/src/lib/components/listing-detail-page.component.js.map +1 -1
  11. package/src/lib/components/site-plugin-connections-card.component.d.ts +38 -0
  12. package/src/lib/components/site-plugin-connections-card.component.js +576 -0
  13. package/src/lib/components/site-plugin-connections-card.component.js.map +1 -0
  14. package/src/lib/declarations.console-server.d.ts +17 -0
  15. package/src/lib/declarations.console-server.js +41 -0
  16. package/src/lib/declarations.console-server.js.map +1 -0
  17. package/src/lib/declarations.js +11 -2
  18. package/src/lib/declarations.js.map +1 -1
  19. package/src/lib/declarations.server.js +68 -1
  20. package/src/lib/declarations.server.js.map +1 -1
  21. package/src/lib/hooks/use-plugin-connections-api.d.ts +89 -0
  22. package/src/lib/hooks/use-plugin-connections-api.js +132 -0
  23. package/src/lib/hooks/use-plugin-connections-api.js.map +1 -0
  24. package/src/lib/model/editor-connections.d.ts +46 -0
  25. package/src/lib/model/editor-connections.js +70 -0
  26. package/src/lib/model/editor-connections.js.map +1 -0
  27. package/src/lib/model/listing-price-floor.js +7 -4
  28. package/src/lib/model/listing-price-floor.js.map +1 -1
  29. package/src/lib/model/marketplace-publisher-permissions.d.ts +3 -1
  30. package/src/lib/model/marketplace-publisher-permissions.js +14 -0
  31. package/src/lib/model/marketplace-publisher-permissions.js.map +1 -1
  32. package/src/lib/model/marketplace-site-permissions.d.ts +9 -0
  33. package/src/lib/model/marketplace-site-permissions.js +29 -0
  34. package/src/lib/model/marketplace-site-permissions.js.map +1 -1
  35. package/src/lib/model/plugin-connection-card.d.ts +88 -0
  36. package/src/lib/model/plugin-connection-card.js +187 -0
  37. package/src/lib/model/plugin-connection-card.js.map +1 -0
  38. package/src/lib/model/plugin-connections.d.ts +172 -0
  39. package/src/lib/model/plugin-connections.js +119 -0
  40. package/src/lib/model/plugin-connections.js.map +1 -0
  41. package/src/lib/plugin.js +21 -1
  42. package/src/lib/plugin.js.map +1 -1
  43. package/src/lib/server/admin-reviews.js +18 -12
  44. package/src/lib/server/admin-reviews.js.map +1 -1
  45. package/src/lib/server/artifact-inventory.js +3 -1
  46. package/src/lib/server/artifact-inventory.js.map +1 -1
  47. package/src/lib/server/checkout.js +4 -0
  48. package/src/lib/server/checkout.js.map +1 -1
  49. package/src/lib/server/connections/cleanup.d.ts +84 -0
  50. package/src/lib/server/connections/cleanup.js +116 -0
  51. package/src/lib/server/connections/cleanup.js.map +1 -0
  52. package/src/lib/server/connections/config.d.ts +42 -0
  53. package/src/lib/server/connections/config.js +48 -0
  54. package/src/lib/server/connections/config.js.map +1 -0
  55. package/src/lib/server/connections/connection-store.d.ts +173 -0
  56. package/src/lib/server/connections/connection-store.js +331 -0
  57. package/src/lib/server/connections/connection-store.js.map +1 -0
  58. package/src/lib/server/connections/credentials-store.d.ts +71 -0
  59. package/src/lib/server/connections/credentials-store.js +78 -0
  60. package/src/lib/server/connections/credentials-store.js.map +1 -0
  61. package/src/lib/server/connections/erasure.d.ts +25 -0
  62. package/src/lib/server/connections/erasure.js +72 -0
  63. package/src/lib/server/connections/erasure.js.map +1 -0
  64. package/src/lib/server/connections/installed-connection.d.ts +64 -0
  65. package/src/lib/server/connections/installed-connection.js +92 -0
  66. package/src/lib/server/connections/installed-connection.js.map +1 -0
  67. package/src/lib/server/connections/oauth-state.d.ts +129 -0
  68. package/src/lib/server/connections/oauth-state.js +252 -0
  69. package/src/lib/server/connections/oauth-state.js.map +1 -0
  70. package/src/lib/server/connections/provider-http.d.ts +99 -0
  71. package/src/lib/server/connections/provider-http.js +253 -0
  72. package/src/lib/server/connections/provider-http.js.map +1 -0
  73. package/src/lib/server/connections/record-announce.d.ts +20 -0
  74. package/src/lib/server/connections/record-announce.js +53 -0
  75. package/src/lib/server/connections/record-announce.js.map +1 -0
  76. package/src/lib/server/connections/record-mapping.d.ts +63 -0
  77. package/src/lib/server/connections/record-mapping.js +151 -0
  78. package/src/lib/server/connections/record-mapping.js.map +1 -0
  79. package/src/lib/server/connections/record-routes.d.ts +17 -0
  80. package/src/lib/server/connections/record-routes.js +96 -0
  81. package/src/lib/server/connections/record-routes.js.map +1 -0
  82. package/src/lib/server/connections/revoke.d.ts +29 -0
  83. package/src/lib/server/connections/revoke.js +52 -0
  84. package/src/lib/server/connections/revoke.js.map +1 -0
  85. package/src/lib/server/connections/routes.d.ts +77 -0
  86. package/src/lib/server/connections/routes.js +706 -0
  87. package/src/lib/server/connections/routes.js.map +1 -0
  88. package/src/lib/server/connections/site-records-platform.d.ts +24 -0
  89. package/src/lib/server/connections/site-records-platform.js +94 -0
  90. package/src/lib/server/connections/site-records-platform.js.map +1 -0
  91. package/src/lib/server/connections/site-records.d.ts +95 -0
  92. package/src/lib/server/connections/site-records.js +221 -0
  93. package/src/lib/server/connections/site-records.js.map +1 -0
  94. package/src/lib/server/connections/sync.d.ts +110 -0
  95. package/src/lib/server/connections/sync.js +414 -0
  96. package/src/lib/server/connections/sync.js.map +1 -0
  97. package/src/lib/server/install-plugin.js +56 -6
  98. package/src/lib/server/install-plugin.js.map +1 -1
  99. package/src/lib/server/publish-plugin.js +5 -2
  100. package/src/lib/server/publish-plugin.js.map +1 -1
  101. package/src/lib/server/revenue-source.js +6 -5
  102. package/src/lib/server/revenue-source.js.map +1 -1
  103. package/src/lib/server.js +60 -0
  104. package/src/lib/server.js.map +1 -1
  105. package/src/lib/testing/memory-firestore.d.ts +34 -0
  106. package/src/lib/testing/memory-firestore.js +250 -0
  107. package/src/lib/testing/memory-firestore.js.map +1 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/plugin.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 * as Aglyn from '@aglyn/aglyn'\nimport { ICON_VARIANT_SYMBOL_FLAG } from '@aglyn/shared-data-enums'\nimport { mdiStorefrontOutline } from '@aglyn/shared-data-mdi'\nimport MarketplaceBrowse from './components/marketplace-browse.component'\nimport MarketplaceHub from './components/marketplace-hub.component'\nimport MarketplaceReportsPage from './components/marketplace-reports-page.component'\nimport PluginReviewsSurface from './components/plugin-reviews-surface.component'\nimport MarketplacePaymentsNotice from './components/marketplace-payments-notice.component'\nimport HostPluginsCard from './components/host-plugins-card.component'\nimport PluginSiteSetPanel from './components/plugin-site-set-panel.component'\nimport OrgPluginInstallsCard from './components/org-plugin-installs-card.component'\nimport PluginInstallStatus from './components/plugin-install-status.component'\nimport StaffMarketplaceOverview from './components/staff-marketplace-overview.component'\nimport StarterPickerShelf from './components/starter-picker-shelf.component'\nimport TemplateGalleryShelf from './components/template-gallery-shelf.component'\nimport TemplateInstallStatus from './components/template-install-status.component'\nimport PublishArtifactDialog from './components/publish-artifact-dialog.component'\nimport { MarketplaceListingContent } from './components/listing-content.component'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { MARKETPLACE_LICENSES_SECTION_ID } from './model/marketplace-section-ids'\nimport { RATING_FIELD } from './model/rating-field'\nimport RatingInput from './components/rating-input.component'\n\n/**\n * Marketplace feature plugin (AGL-395). Console-only — marketplace components\n * install into a host's own components collection and render through the\n * normal compose pipeline, so there is no separate canvas bundle.\n *\n * The marketplace moved to org scope (AGL-772/774): browse + install live at\n * `/[orgSlug]/marketplace`, so this plugin no longer contributes a per-site\n * `Marketplace` nav tab (AGL-775). It exposes its UI purely through widget\n * slots — `orgMarketplace` (browse), `marketplaceListing` (detail) and\n * `orgAddons` (installed) — which the app renders without importing the\n * plugin.\n */\nexport function registerMarketplaceConsole(): void {\n // Custom field type (AGL-434): rating rides int32 with a starred input.\n Aglyn.registerCustomFieldType({ ...RATING_FIELD, Input: RatingInput })\n Aglyn.registerConsoleExtension({\n /*\n * Four widgets fewer since AGL-3080 — the listing body, the capability\n * notice, browse, and installed add-ons. Their zones existed for one\n * reason: a CONSOLE ROUTE had to show them and an app may not import a\n * plugin. The hub is this plugin's own surface now, so those components\n * are plain imports and the four zones are gone from the catalog.\n *\n * What is left is what a console page OTHER than the marketplace draws.\n */\n widgets: [\n // The site set for one installation (AGL-1007): the same control the\n // listing page uses, exposed so the installation detail page can show\n // it without the app importing this plugin.\n {\n slot: 'pluginSiteSet',\n widgetId: 'marketplace-plugin-site-set',\n Component: PluginSiteSetPanel,\n },\n // Publishing something the console holds (AGL-3080). The page that\n // offers it keeps the control that opens it — a menu item is one entry\n // of a list the page builds, not a widget — and hands over what it has\n // in its own vocabulary. Where a layout or a theme GOES, what a listing\n // of it is called and what it may cost at the least are this plugin's.\n {\n slot: 'hostArtifactPublish',\n widgetId: 'marketplace-publish-artifact',\n Component: PublishArtifactDialog,\n },\n // The workspace's Plugins page and an installation's own page\n // (AGL-3080). The shell owns both pages and the built-in half of the\n // inventory; what this plugin installed — its pins, whether a newer\n // version may be installed, whether a kill switch is thrown — is read\n // from this plugin's own collections, so this plugin draws it.\n {\n slot: 'orgPluginInstalls',\n widgetId: 'marketplace-org-plugin-installs',\n Component: OrgPluginInstallsCard,\n },\n {\n slot: 'pluginInstallStatus',\n widgetId: 'marketplace-plugin-install-status',\n Component: PluginInstallStatus,\n },\n // The staff overview (AGL-3080): recent purchases and the\n // refund-reversal recovery queue, from this plugin's own purchases.\n {\n slot: 'staffOverview',\n widgetId: 'marketplace-staff-overview',\n Component: StaffMarketplaceOverview,\n },\n // A site's templates (AGL-3080). The gallery and the library are the\n // shell's; the site templates this plugin lists, the route that\n // installs one, and whether a template it installed has a newer\n // version are read from this plugin's listings, so this plugin draws\n // them: a shelf of the gallery, and a chip on the library's row.\n {\n slot: 'templateGallery',\n widgetId: 'marketplace-template-gallery',\n Component: TemplateGalleryShelf,\n },\n {\n slot: 'templateInstallStatus',\n widgetId: 'marketplace-template-install-status',\n Component: TemplateInstallStatus,\n },\n // \"Choose your starter\" in Create site (AGL-4049): the marketplace's\n // site starters, searched and picked before the site exists. It lists\n // and picks; the dialog creates. Searching is the first step of\n // creating a site, so it takes the create's permission, as its route\n // does; the route also answers the release flag.\n {\n slot: 'hostStarterPicker',\n widgetId: 'marketplace-starter-picker',\n permission: 'hosts.create',\n Component: StarterPickerShelf,\n },\n ],\n /**\n * THE MARKETPLACE HUB, as a declaration (AGL-3080).\n *\n * Seventeen hand-written console routes until now — the eight sections\n * below plus a listing, a publisher storefront and a publish form —\n * whose whole job was assembling chrome around bodies that already\n * belonged to this plugin. The shell's generic org plugin route does\n * that assembly for every other surface from exactly this.\n *\n * `ownsSubtree` is what keeps every URL the same. A segment naming a\n * section below resolves as that section; anything else beneath\n * `/marketplace` is handed to the page as `segments`, which is how\n * `/{org}/marketplace/{listingId}` still opens a listing. The cost is\n * stated where the flag is declared: this surface can no longer tell a\n * typo from an id, so it owns saying \"no such thing\" — which a listing\n * page has to do anyway for one deleted while a link to it was still in\n * someone's inbox.\n */\n orgNavItems: [\n {\n label: 'Marketplace',\n href: '/marketplace',\n navTabId: 'nav-tab-org-marketplace',\n icon: { path: mdiStorefrontOutline.path },\n /*\n * Last of the plugin tabs, so it sits directly before the shell's\n * Plugins tab (AGL-3294): shopping for plugins beside managing the\n * ones the workspace runs, the pair AGL-1011 split into two tabs.\n */\n tabOrder: 100,\n ownsSubtree: true,\n Component: MarketplaceHub,\n header: {\n title: 'Marketplace',\n icon: { path: mdiStorefrontOutline.path },\n docsTopic: 'plugins',\n },\n sections: [\n // \"Browse All\" (AGL-1024): the same grid also renders\n // publisher-filtered views, so the unqualified verb was ambiguous\n // about which you were getting.\n { id: 'browse', label: 'Browse All' },\n { id: 'installed', label: 'Installed' },\n /*\n * What this workspace OWNS (AGL-2331) — an org can hold a licence\n * nobody has installed, and a member can install something they\n * never bought. Buyer-side, so deliberately NOT gated like the\n * seller sections below: the person who needs it is often not a\n * publisher at all.\n *\n * `purchase` lands here: Stripe bakes it into the checkout session\n * and holds the URL, and a buyer coming back wants what they now\n * own.\n */\n {\n id: MARKETPLACE_LICENSES_SECTION_ID,\n label: 'Licenses',\n landsOnQuery: ['purchase'],\n },\n /*\n * The seller half. Each reads the organization's REVENUE or its\n * payout account, so each names the permission rather than relying\n * on a hidden tab — a URL can be typed whether or not a tab was\n * ever offered, and the shell applies this to the rail and to the\n * deep link as one verdict.\n */\n {\n id: 'upload',\n // Covers uploading a bundle as well as publishing an existing\n // artifact (AGL-1024).\n label: 'Upload / Publish',\n permission: 'publishToMarketplace',\n },\n {\n id: 'profile',\n // Whose profile (AGL-1024) — the console also has org and user\n // profiles.\n label: 'Publisher Profile',\n permission: 'publishToMarketplace',\n },\n {\n id: 'listings',\n label: 'Listings',\n permission: 'publishToMarketplace',\n },\n {\n id: 'payouts',\n label: 'Payouts',\n permission: 'publishToMarketplace',\n // Stripe Connect onboarding returns with this, from\n // `server/connect.ts`. A seller coming back wants Payouts.\n landsOnQuery: ['connect'],\n },\n {\n id: 'sales',\n label: 'Sales',\n permission: 'publishToMarketplace',\n },\n ],\n },\n ],\n /**\n * The report queue, in the staff area (AGL-2310, moved by AGL-3080).\n *\n * `marketplaceReports` is a collection only this plugin writes, and the\n * queue that triages it was a console staff route because the staff area\n * had no way for a plugin to own a page. It does (AGL-2939), and the\n * shell serves this at the same `/admin/marketplace-reports` it always\n * had — a staff page's id IS its URL segment.\n */\n staffPages: [\n {\n id: 'marketplace-reports',\n label: 'Marketplace reports',\n header: {\n title: 'Marketplace Reports',\n icon: { path: ICON_VARIANT_SYMBOL_FLAG.path },\n // The abuse queue's topic, for the reason the page's own help\n // gives. The page publishes the `#statuses` anchor itself, which a\n // `staffPages` entry cannot carry.\n docsTopic: 'abuseReports',\n },\n Component: MarketplaceReportsPage,\n },\n /**\n * The review queue (AGL-432, moved by AGL-3080).\n *\n * `ownsSubtree` is what makes the move possible at all: the queue is a\n * list and each row opens one submission at\n * `/admin/plugin-reviews/{listingId}`, and a staff page without it\n * could only ever BE the list. Same URLs as the console routes it\n * replaces — a staff page's id IS its segment under `/admin`.\n *\n * The queue carries no signing authority. Granting realm trust is a\n * separate super-only act on its own route; listing and verifying here\n * never signs anything.\n */\n {\n id: 'plugin-reviews',\n label: 'Plugin reviews',\n ownsSubtree: true,\n header: {\n title: 'Plugin reviews',\n icon: { path: ICON_VARIANT_SYMBOL_FLAG.path },\n docsTopic: 'staffConsole',\n },\n Component: PluginReviewsSurface,\n },\n ],\n pluginId: BUNDLE_ID,\n displayName: 'Marketplace',\n })\n}\n\n// Shared with the listing/publisher detail app-routes.\nexport { default as useMarketplaceActions } from './hooks/use-marketplace-actions'\nexport { default as MarketplaceBrowse } from './components/marketplace-browse.component'\nexport { default as HostPluginsCard } from './components/host-plugins-card.component'\nexport { default as PluginSiteSetPanel } from './components/plugin-site-set-panel.component'\n"],"names":["Aglyn","ICON_VARIANT_SYMBOL_FLAG","mdiStorefrontOutline","MarketplaceHub","MarketplaceReportsPage","PluginReviewsSurface","PluginSiteSetPanel","OrgPluginInstallsCard","PluginInstallStatus","StaffMarketplaceOverview","StarterPickerShelf","TemplateGalleryShelf","TemplateInstallStatus","PublishArtifactDialog","BUNDLE_ID","MARKETPLACE_LICENSES_SECTION_ID","RATING_FIELD","RatingInput","registerMarketplaceConsole","registerCustomFieldType","Input","registerConsoleExtension","widgets","slot","widgetId","Component","permission","orgNavItems","label","href","navTabId","icon","path","tabOrder","ownsSubtree","header","title","docsTopic","sections","id","landsOnQuery","staffPages","pluginId","displayName","default","useMarketplaceActions","MarketplaceBrowse","HostPluginsCard"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,YAAYA,WAAW,eAAc;AACrC,SAASC,wBAAwB,QAAQ,2BAA0B;AACnE,SAASC,oBAAoB,QAAQ,yBAAwB;AAE7D,OAAOC,oBAAoB,4CAAwC;AACnE,OAAOC,4BAA4B,qDAAiD;AACpF,OAAOC,0BAA0B,mDAA+C;AAGhF,OAAOC,wBAAwB,kDAA8C;AAC7E,OAAOC,2BAA2B,qDAAiD;AACnF,OAAOC,yBAAyB,kDAA8C;AAC9E,OAAOC,8BAA8B,uDAAmD;AACxF,OAAOC,wBAAwB,iDAA6C;AAC5E,OAAOC,0BAA0B,mDAA+C;AAChF,OAAOC,2BAA2B,oDAAgD;AAClF,OAAOC,2BAA2B,oDAAgD;AAElF,SAASC,SAAS,QAAQ,+BAA2B;AACrD,SAASC,+BAA+B,QAAQ,qCAAiC;AACjF,SAASC,YAAY,QAAQ,0BAAsB;AACnD,OAAOC,iBAAiB,yCAAqC;AAE7D;;;;;;;;;;;CAWC,GACD,OAAO,SAASC;IACd,wEAAwE;IACxElB,MAAMmB,uBAAuB,CAAC,aAAKH;QAAcI,OAAOH;;IACxDjB,MAAMqB,wBAAwB,CAAC;QAC7B;;;;;;;;KAQC,GACDC,SAAS;YACP,qEAAqE;YACrE,sEAAsE;YACtE,4CAA4C;YAC5C;gBACEC,MAAM;gBACNC,UAAU;gBACVC,WAAWnB;YACb;YACA,mEAAmE;YACnE,uEAAuE;YACvE,uEAAuE;YACvE,wEAAwE;YACxE,uEAAuE;YACvE;gBACEiB,MAAM;gBACNC,UAAU;gBACVC,WAAWZ;YACb;YACA,8DAA8D;YAC9D,qEAAqE;YACrE,oEAAoE;YACpE,sEAAsE;YACtE,+DAA+D;YAC/D;gBACEU,MAAM;gBACNC,UAAU;gBACVC,WAAWlB;YACb;YACA;gBACEgB,MAAM;gBACNC,UAAU;gBACVC,WAAWjB;YACb;YACA,0DAA0D;YAC1D,oEAAoE;YACpE;gBACEe,MAAM;gBACNC,UAAU;gBACVC,WAAWhB;YACb;YACA,qEAAqE;YACrE,gEAAgE;YAChE,gEAAgE;YAChE,qEAAqE;YACrE,iEAAiE;YACjE;gBACEc,MAAM;gBACNC,UAAU;gBACVC,WAAWd;YACb;YACA;gBACEY,MAAM;gBACNC,UAAU;gBACVC,WAAWb;YACb;YACA,qEAAqE;YACrE,sEAAsE;YACtE,gEAAgE;YAChE,qEAAqE;YACrE,iDAAiD;YACjD;gBACEW,MAAM;gBACNC,UAAU;gBACVE,YAAY;gBACZD,WAAWf;YACb;SACD;QACD;;;;;;;;;;;;;;;;;KAiBC,GACDiB,aAAa;YACX;gBACEC,OAAO;gBACPC,MAAM;gBACNC,UAAU;gBACVC,MAAM;oBAAEC,MAAM9B,qBAAqB8B,IAAI;gBAAC;gBACxC;;;;SAIC,GACDC,UAAU;gBACVC,aAAa;gBACbT,WAAWtB;gBACXgC,QAAQ;oBACNC,OAAO;oBACPL,MAAM;wBAAEC,MAAM9B,qBAAqB8B,IAAI;oBAAC;oBACxCK,WAAW;gBACb;gBACAC,UAAU;oBACR,sDAAsD;oBACtD,kEAAkE;oBAClE,gCAAgC;oBAChC;wBAAEC,IAAI;wBAAUX,OAAO;oBAAa;oBACpC;wBAAEW,IAAI;wBAAaX,OAAO;oBAAY;oBACtC;;;;;;;;;;WAUC,GACD;wBACEW,IAAIxB;wBACJa,OAAO;wBACPY,cAAc;4BAAC;yBAAW;oBAC5B;oBACA;;;;;;WAMC,GACD;wBACED,IAAI;wBACJ,8DAA8D;wBAC9D,uBAAuB;wBACvBX,OAAO;wBACPF,YAAY;oBACd;oBACA;wBACEa,IAAI;wBACJ,+DAA+D;wBAC/D,YAAY;wBACZX,OAAO;wBACPF,YAAY;oBACd;oBACA;wBACEa,IAAI;wBACJX,OAAO;wBACPF,YAAY;oBACd;oBACA;wBACEa,IAAI;wBACJX,OAAO;wBACPF,YAAY;wBACZ,oDAAoD;wBACpD,2DAA2D;wBAC3Dc,cAAc;4BAAC;yBAAU;oBAC3B;oBACA;wBACED,IAAI;wBACJX,OAAO;wBACPF,YAAY;oBACd;iBACD;YACH;SACD;QACD;;;;;;;;KAQC,GACDe,YAAY;YACV;gBACEF,IAAI;gBACJX,OAAO;gBACPO,QAAQ;oBACNC,OAAO;oBACPL,MAAM;wBAAEC,MAAM/B,yBAAyB+B,IAAI;oBAAC;oBAC5C,8DAA8D;oBAC9D,mEAAmE;oBACnE,mCAAmC;oBACnCK,WAAW;gBACb;gBACAZ,WAAWrB;YACb;YACA;;;;;;;;;;;;OAYC,GACD;gBACEmC,IAAI;gBACJX,OAAO;gBACPM,aAAa;gBACbC,QAAQ;oBACNC,OAAO;oBACPL,MAAM;wBAAEC,MAAM/B,yBAAyB+B,IAAI;oBAAC;oBAC5CK,WAAW;gBACb;gBACAZ,WAAWpB;YACb;SACD;QACDqC,UAAU5B;QACV6B,aAAa;IACf;AACF;AAEA,uDAAuD;AACvD,SAASC,WAAWC,qBAAqB,QAAQ,qCAAiC;AAClF,SAASD,WAAWE,iBAAiB,QAAQ,+CAA2C;AACxF,SAASF,WAAWG,eAAe,QAAQ,8CAA0C;AACrF,SAASH,WAAWtC,kBAAkB,QAAQ,kDAA8C"}
1
+ {"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/plugin.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 * as Aglyn from '@aglyn/aglyn'\nimport { ICON_VARIANT_SYMBOL_FLAG } from '@aglyn/shared-data-enums'\nimport { mdiStorefrontOutline } from '@aglyn/shared-data-mdi'\nimport MarketplaceBrowse from './components/marketplace-browse.component'\nimport MarketplaceHub from './components/marketplace-hub.component'\nimport MarketplaceReportsPage from './components/marketplace-reports-page.component'\nimport PluginReviewsSurface from './components/plugin-reviews-surface.component'\nimport MarketplacePaymentsNotice from './components/marketplace-payments-notice.component'\nimport HostPluginsCard from './components/host-plugins-card.component'\nimport PluginSiteSetPanel from './components/plugin-site-set-panel.component'\nimport OrgPluginInstallsCard from './components/org-plugin-installs-card.component'\nimport PluginInstallStatus from './components/plugin-install-status.component'\nimport EditorConnectionsProvider from './components/editor-connections-provider.component'\nimport StaffMarketplaceOverview from './components/staff-marketplace-overview.component'\nimport StarterPickerShelf from './components/starter-picker-shelf.component'\nimport TemplateGalleryShelf from './components/template-gallery-shelf.component'\nimport TemplateInstallStatus from './components/template-install-status.component'\nimport PublishArtifactDialog from './components/publish-artifact-dialog.component'\nimport { MarketplaceListingContent } from './components/listing-content.component'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { MARKETPLACE_LICENSES_SECTION_ID } from './model/marketplace-section-ids'\nimport { RATING_FIELD } from './model/rating-field'\nimport RatingInput from './components/rating-input.component'\nimport { lazy } from 'react'\n\n/** Drawn only on a site's page for a plugin that declares connections, so it loads when it is drawn. */\nconst SitePluginConnectionsCard = lazy(() => import('./components/site-plugin-connections-card.component'))\n\n/**\n * Marketplace feature plugin (AGL-395). Console-only — marketplace components\n * install into a host's own components collection and render through the\n * normal compose pipeline, so there is no separate canvas bundle.\n *\n * The marketplace moved to org scope (AGL-772/774): browse + install live at\n * `/[orgSlug]/marketplace`, so this plugin no longer contributes a per-site\n * `Marketplace` nav tab (AGL-775). It exposes its UI purely through widget\n * slots — `orgMarketplace` (browse), `marketplaceListing` (detail) and\n * `orgAddons` (installed) — which the app renders without importing the\n * plugin.\n */\nexport function registerMarketplaceConsole(): void {\n // Custom field type (AGL-434): rating rides int32 with a starred input.\n Aglyn.registerCustomFieldType({ ...RATING_FIELD, Input: RatingInput })\n Aglyn.registerConsoleExtension({\n /*\n * Four widgets fewer since AGL-3080 — the listing body, the capability\n * notice, browse, and installed add-ons. Their zones existed for one\n * reason: a CONSOLE ROUTE had to show them and an app may not import a\n * plugin. The hub is this plugin's own surface now, so those components\n * are plain imports and the four zones are gone from the catalog.\n *\n * What is left is what a console page OTHER than the marketplace draws.\n */\n widgets: [\n // The site set for one installation (AGL-1007): the same control the\n // listing page uses, exposed so the installation detail page can show\n // it without the app importing this plugin.\n {\n slot: 'pluginSiteSet',\n widgetId: 'marketplace-plugin-site-set',\n Component: PluginSiteSetPanel,\n },\n // Publishing something the console holds (AGL-3080). The page that\n // offers it keeps the control that opens it — a menu item is one entry\n // of a list the page builds, not a widget — and hands over what it has\n // in its own vocabulary. Where a layout or a theme GOES, what a listing\n // of it is called and what it may cost at the least are this plugin's.\n {\n slot: 'hostArtifactPublish',\n widgetId: 'marketplace-publish-artifact',\n Component: PublishArtifactDialog,\n },\n // The workspace's Plugins page and an installation's own page\n // (AGL-3080). The shell owns both pages and the built-in half of the\n // inventory; what this plugin installed — its pins, whether a newer\n // version may be installed, whether a kill switch is thrown — is read\n // from this plugin's own collections, so this plugin draws it.\n {\n slot: 'orgPluginInstalls',\n widgetId: 'marketplace-org-plugin-installs',\n Component: OrgPluginInstallsCard,\n },\n {\n slot: 'pluginInstallStatus',\n widgetId: 'marketplace-plugin-install-status',\n Component: PluginInstallStatus,\n },\n // A site's page for one installed plugin (AGL-4196): the services the\n // pinned manifest declares it connects to. This plugin runs the\n // connections, so it draws them; the card checks the site key itself\n // and keeps every control on screen with the reason when it is off.\n {\n slot: 'sitePluginConnections',\n widgetId: 'marketplace-site-plugin-connections',\n Component: SitePluginConnectionsCard,\n },\n // The staff overview (AGL-3080): recent purchases and the\n // refund-reversal recovery queue, from this plugin's own purchases.\n {\n slot: 'staffOverview',\n widgetId: 'marketplace-staff-overview',\n Component: StaffMarketplaceOverview,\n },\n // A site's templates (AGL-3080). The gallery and the library are the\n // shell's; the site templates this plugin lists, the route that\n // installs one, and whether a template it installed has a newer\n // version are read from this plugin's listings, so this plugin draws\n // them: a shelf of the gallery, and a chip on the library's row.\n {\n slot: 'templateGallery',\n widgetId: 'marketplace-template-gallery',\n Component: TemplateGalleryShelf,\n },\n {\n slot: 'templateInstallStatus',\n widgetId: 'marketplace-template-install-status',\n Component: TemplateInstallStatus,\n },\n // \"Choose your starter\" in Create site (AGL-4049): the marketplace's\n // site starters, searched and picked before the site exists. It lists\n // and picks; the dialog creates. Searching is the first step of\n // creating a site, so it takes the create's permission, as its route\n // does; the route also answers the release flag.\n {\n slot: 'hostStarterPicker',\n widgetId: 'marketplace-starter-picker',\n permission: 'hosts.create',\n Component: StarterPickerShelf,\n },\n ],\n /**\n * THE MARKETPLACE HUB, as a declaration (AGL-3080).\n *\n * Seventeen hand-written console routes until now — the eight sections\n * below plus a listing, a publisher storefront and a publish form —\n * whose whole job was assembling chrome around bodies that already\n * belonged to this plugin. The shell's generic org plugin route does\n * that assembly for every other surface from exactly this.\n *\n * `ownsSubtree` is what keeps every URL the same. A segment naming a\n * section below resolves as that section; anything else beneath\n * `/marketplace` is handed to the page as `segments`, which is how\n * `/{org}/marketplace/{listingId}` still opens a listing. The cost is\n * stated where the flag is declared: this surface can no longer tell a\n * typo from an id, so it owns saying \"no such thing\" — which a listing\n * page has to do anyway for one deleted while a link to it was still in\n * someone's inbox.\n */\n /*\n * The site's declared connections in the editor (AGL-4196): the records a\n * signed element reads, and the variables the binding picker lists, on\n * the Besigner and Preview only. Core declares the context; this plugin\n * runs the connections, so it fills it.\n */\n providers: [EditorConnectionsProvider],\n orgNavItems: [\n {\n label: 'Marketplace',\n href: '/marketplace',\n navTabId: 'nav-tab-org-marketplace',\n icon: { path: mdiStorefrontOutline.path },\n /*\n * Last of the plugin tabs, so it sits directly before the shell's\n * Plugins tab (AGL-3294): shopping for plugins beside managing the\n * ones the workspace runs, the pair AGL-1011 split into two tabs.\n */\n tabOrder: 100,\n ownsSubtree: true,\n Component: MarketplaceHub,\n header: {\n title: 'Marketplace',\n icon: { path: mdiStorefrontOutline.path },\n docsTopic: 'plugins',\n },\n sections: [\n // \"Browse All\" (AGL-1024): the same grid also renders\n // publisher-filtered views, so the unqualified verb was ambiguous\n // about which you were getting.\n { id: 'browse', label: 'Browse All' },\n { id: 'installed', label: 'Installed' },\n /*\n * What this workspace OWNS (AGL-2331) — an org can hold a licence\n * nobody has installed, and a member can install something they\n * never bought. Buyer-side, so deliberately NOT gated like the\n * seller sections below: the person who needs it is often not a\n * publisher at all.\n *\n * `purchase` lands here: Stripe bakes it into the checkout session\n * and holds the URL, and a buyer coming back wants what they now\n * own.\n */\n {\n id: MARKETPLACE_LICENSES_SECTION_ID,\n label: 'Licenses',\n landsOnQuery: ['purchase'],\n },\n /*\n * The seller half. Each reads the organization's REVENUE or its\n * payout account, so each names the permission rather than relying\n * on a hidden tab — a URL can be typed whether or not a tab was\n * ever offered, and the shell applies this to the rail and to the\n * deep link as one verdict.\n */\n {\n id: 'upload',\n // Covers uploading a bundle as well as publishing an existing\n // artifact (AGL-1024).\n label: 'Upload / Publish',\n permission: 'publishToMarketplace',\n },\n {\n id: 'profile',\n // Whose profile (AGL-1024) — the console also has org and user\n // profiles.\n label: 'Publisher Profile',\n permission: 'publishToMarketplace',\n },\n {\n id: 'listings',\n label: 'Listings',\n permission: 'publishToMarketplace',\n },\n {\n id: 'payouts',\n label: 'Payouts',\n permission: 'publishToMarketplace',\n // Stripe Connect onboarding returns with this, from\n // `server/connect.ts`. A seller coming back wants Payouts.\n landsOnQuery: ['connect'],\n },\n {\n id: 'sales',\n label: 'Sales',\n permission: 'publishToMarketplace',\n },\n ],\n },\n ],\n /**\n * The report queue, in the staff area (AGL-2310, moved by AGL-3080).\n *\n * `marketplaceReports` is a collection only this plugin writes, and the\n * queue that triages it was a console staff route because the staff area\n * had no way for a plugin to own a page. It does (AGL-2939), and the\n * shell serves this at the same `/admin/marketplace-reports` it always\n * had — a staff page's id IS its URL segment.\n */\n staffPages: [\n {\n id: 'marketplace-reports',\n label: 'Marketplace reports',\n header: {\n title: 'Marketplace Reports',\n icon: { path: ICON_VARIANT_SYMBOL_FLAG.path },\n // The abuse queue's topic, for the reason the page's own help\n // gives. The page publishes the `#statuses` anchor itself, which a\n // `staffPages` entry cannot carry.\n docsTopic: 'abuseReports',\n },\n Component: MarketplaceReportsPage,\n },\n /**\n * The review queue (AGL-432, moved by AGL-3080).\n *\n * `ownsSubtree` is what makes the move possible at all: the queue is a\n * list and each row opens one submission at\n * `/admin/plugin-reviews/{listingId}`, and a staff page without it\n * could only ever BE the list. Same URLs as the console routes it\n * replaces — a staff page's id IS its segment under `/admin`.\n *\n * The queue carries no signing authority. Granting realm trust is a\n * separate super-only act on its own route; listing and verifying here\n * never signs anything.\n */\n {\n id: 'plugin-reviews',\n label: 'Plugin reviews',\n ownsSubtree: true,\n header: {\n title: 'Plugin reviews',\n icon: { path: ICON_VARIANT_SYMBOL_FLAG.path },\n docsTopic: 'staffConsole',\n },\n Component: PluginReviewsSurface,\n },\n ],\n pluginId: BUNDLE_ID,\n displayName: 'Marketplace',\n })\n}\n\n// Shared with the listing/publisher detail app-routes.\nexport { default as useMarketplaceActions } from './hooks/use-marketplace-actions'\nexport { default as MarketplaceBrowse } from './components/marketplace-browse.component'\nexport { default as HostPluginsCard } from './components/host-plugins-card.component'\nexport { default as PluginSiteSetPanel } from './components/plugin-site-set-panel.component'\n"],"names":["Aglyn","ICON_VARIANT_SYMBOL_FLAG","mdiStorefrontOutline","MarketplaceHub","MarketplaceReportsPage","PluginReviewsSurface","PluginSiteSetPanel","OrgPluginInstallsCard","PluginInstallStatus","EditorConnectionsProvider","StaffMarketplaceOverview","StarterPickerShelf","TemplateGalleryShelf","TemplateInstallStatus","PublishArtifactDialog","BUNDLE_ID","MARKETPLACE_LICENSES_SECTION_ID","RATING_FIELD","RatingInput","lazy","SitePluginConnectionsCard","registerMarketplaceConsole","registerCustomFieldType","Input","registerConsoleExtension","widgets","slot","widgetId","Component","permission","providers","orgNavItems","label","href","navTabId","icon","path","tabOrder","ownsSubtree","header","title","docsTopic","sections","id","landsOnQuery","staffPages","pluginId","displayName","default","useMarketplaceActions","MarketplaceBrowse","HostPluginsCard"],"mappings":"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"}
@@ -344,7 +344,7 @@ const isRecord = (value)=>!!value && typeof value === 'object' && !Array.isArray
344
344
  }
345
345
  const versionsSnapshot = await listingRef.collection('pluginVersions').orderBy('publishedAt', 'desc').limit(25).get();
346
346
  const versions = versionsSnapshot.docs.map((doc)=>{
347
- var _doc_get, _doc_get1, _doc_get2, _doc_get3, _readPluginContributions, _doc_get4, _ref, _doc_get5, _doc_get6, _doc_get7, _doc_get8, _doc_get9, _doc_get10, _doc_get11;
347
+ var _doc_get, _doc_get1, _doc_get2, _doc_get3, _readPluginContributions, _doc_get4, _doc_get5, _ref, _doc_get6, _doc_get7, _doc_get8, _doc_get9, _doc_get10, _doc_get11, _doc_get12;
348
348
  var _publishedAt_toDate, _publishedAt_toDate1;
349
349
  const publishedAt = doc.get('publishedAt');
350
350
  return {
@@ -361,23 +361,27 @@ const isRecord = (value)=>!!value && typeof value === 'object' && !Array.isArray
361
361
  // listing page — so without it here, the `element-metadata` criterion
362
362
  // asks a reviewer to check text this page never shows (AGL-2486).
363
363
  elements: (_doc_get4 = doc.get('manifest.elements')) != null ? _doc_get4 : [],
364
+ // Declared connections (AGL-4193) for THESE bytes: the OAuth provider,
365
+ // the hosts the platform calls with the grant and the public record a
366
+ // sync writes, answered beside the version's other declarations.
367
+ connections: (_doc_get5 = doc.get('manifest.connections')) != null ? _doc_get5 : [],
364
368
  publishedAt: (_ref = publishedAt == null ? void 0 : (_publishedAt_toDate1 = publishedAt.toDate) == null ? void 0 : (_publishedAt_toDate = _publishedAt_toDate1.call(publishedAt)) == null ? void 0 : _publishedAt_toDate.toISOString()) != null ? _ref : null,
365
369
  // Per-version installs (AGL-1036). "How many workspaces would a revoke
366
370
  // actually hit" is a per-version question, and the listing total shown
367
371
  // elsewhere on this page answers a different one.
368
- installCount: Number((_doc_get5 = doc.get('installCount')) != null ? _doc_get5 : 0),
369
- activeInstalls: Number((_doc_get6 = doc.get('activeInstalls')) != null ? _doc_get6 : 0),
372
+ installCount: Number((_doc_get6 = doc.get('installCount')) != null ? _doc_get6 : 0),
373
+ activeInstalls: Number((_doc_get7 = doc.get('activeInstalls')) != null ? _doc_get7 : 0),
370
374
  signed: Boolean(doc.get('signature')),
371
375
  // The repo as declared for THESE bytes (AGL-1076); absent on versions
372
376
  // published before it was collected.
373
- repositoryUrl: String((_doc_get7 = doc.get('repositoryUrl')) != null ? _doc_get7 : ''),
374
- reviewState: String((_doc_get8 = doc.get('reviewState')) != null ? _doc_get8 : 'pending'),
377
+ repositoryUrl: String((_doc_get8 = doc.get('repositoryUrl')) != null ? _doc_get8 : ''),
378
+ reviewState: String((_doc_get9 = doc.get('reviewState')) != null ? _doc_get9 : 'pending'),
375
379
  grandfathered: Boolean(doc.get('grandfathered')),
376
380
  // Server-side only — used to decide whether the verdict below needs
377
381
  // recomputing; stripped before the payload goes out.
378
- verification: (_doc_get9 = doc.get('verification')) != null ? _doc_get9 : null,
379
- reviewChecklist: (_doc_get10 = doc.get('reviewChecklist')) != null ? _doc_get10 : null,
380
- publisherAttestation: (_doc_get11 = doc.get('publisherAttestation')) != null ? _doc_get11 : null
382
+ verification: (_doc_get10 = doc.get('verification')) != null ? _doc_get10 : null,
383
+ reviewChecklist: (_doc_get11 = doc.get('reviewChecklist')) != null ? _doc_get11 : null,
384
+ publisherAttestation: (_doc_get12 = doc.get('publisherAttestation')) != null ? _doc_get12 : null
381
385
  };
382
386
  });
383
387
  // Publisher is an ORG since AGL-652 — show the name, not the raw id.
@@ -425,7 +429,7 @@ const isRecord = (value)=>!!value && typeof value === 'object' && !Array.isArray
425
429
  let verifierCached = storedIsCurrent;
426
430
  if (!storedIsCurrent && artifactsBucket && reviewSha) {
427
431
  try {
428
- var _ref11;
432
+ var _ref11, _ref12;
429
433
  var _reviewEntry_capabilities;
430
434
  const [bytes] = await firebaseAdmin.app().storage().bucket(artifactsBucket).file(pluginArtifactPath(listingId, reviewVersion, reviewSha)).download();
431
435
  // The manifest for THESE bytes, so an undeclared network call is a
@@ -436,7 +440,9 @@ const isRecord = (value)=>!!value && typeof value === 'object' && !Array.isArray
436
440
  // Compared, never required: a version published before the contract
437
441
  // loads under its default, and review must not refuse it for a rule
438
442
  // it was never held to.
439
- declaredContributions: (_ref11 = reviewEntry == null ? void 0 : reviewEntry.contributes) != null ? _ref11 : null
443
+ declaredContributions: (_ref11 = reviewEntry == null ? void 0 : reviewEntry.contributes) != null ? _ref11 : null,
444
+ // A version published before connections declares none (AGL-4193).
445
+ declaredConnections: (_ref12 = reviewEntry == null ? void 0 : reviewEntry.connections) != null ? _ref12 : null
440
446
  });
441
447
  verifier = result;
442
448
  // Write it back so this sha is verified at most once platform-wide —
@@ -477,8 +483,8 @@ const isRecord = (value)=>!!value && typeof value === 'object' && !Array.isArray
477
483
  // the attester by raw uid — indistinguishable from "account deleted".
478
484
  const found = await findUserByUidAcrossPools(attesterUid);
479
485
  if (found) {
480
- var _ref12, _found_record_email;
481
- attestedBy = (_ref12 = (_found_record_email = found.record.email) != null ? _found_record_email : found.record.displayName) != null ? _ref12 : attesterUid;
486
+ var _ref13, _found_record_email;
487
+ attestedBy = (_ref13 = (_found_record_email = found.record.email) != null ? _found_record_email : found.record.displayName) != null ? _ref13 : attesterUid;
482
488
  }
483
489
  } catch (unused) {
484
490
  // Account gone — the uid still identifies the statement.