@aglyn/plugins-marketplace 1.0.0-beta.291 → 1.0.0-beta.293
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/package.json +14 -14
- package/src/lib/components/listing-detail-editor.component.js +32 -10
- package/src/lib/components/listing-detail-editor.component.js.map +1 -1
- package/src/lib/components/listing-verification-request.component.js +32 -11
- package/src/lib/components/listing-verification-request.component.js.map +1 -1
- package/src/lib/components/org-seller-panel.component.js +121 -143
- package/src/lib/components/org-seller-panel.component.js.map +1 -1
- package/src/lib/components/publish-artifact-dialog.component.js +115 -115
- package/src/lib/components/publish-artifact-dialog.component.js.map +1 -1
- package/src/lib/components/publish-plugin-form.component.js +32 -36
- package/src/lib/components/publish-plugin-form.component.js.map +1 -1
- package/src/lib/components/publisher-agreement-checkbox.component.d.ts +56 -0
- package/src/lib/components/publisher-agreement-checkbox.component.js +121 -0
- package/src/lib/components/publisher-agreement-checkbox.component.js.map +1 -0
- package/src/lib/components/publisher-agreement-confirm-dialog.component.d.ts +45 -0
- package/src/lib/components/publisher-agreement-confirm-dialog.component.js +109 -0
- package/src/lib/components/publisher-agreement-confirm-dialog.component.js.map +1 -0
- package/src/lib/components/publisher-agreement-summary.component.d.ts +4 -3
- package/src/lib/components/publisher-agreement-summary.component.js +4 -3
- package/src/lib/components/publisher-agreement-summary.component.js.map +1 -1
- package/src/lib/components/starter-picker-shelf.component.d.ts +29 -0
- package/src/lib/components/starter-picker-shelf.component.js +317 -0
- package/src/lib/components/starter-picker-shelf.component.js.map +1 -0
- package/src/lib/declarations.server.js +2 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/hooks/use-starter-purchase.d.ts +31 -0
- package/src/lib/hooks/use-starter-purchase.js +101 -0
- package/src/lib/hooks/use-starter-purchase.js.map +1 -0
- package/src/lib/hooks/use-starter-search.d.ts +42 -0
- package/src/lib/hooks/use-starter-search.js +137 -0
- package/src/lib/hooks/use-starter-search.js.map +1 -0
- package/src/lib/model/listing-visibility.d.ts +17 -9
- package/src/lib/model/listing-visibility.js +18 -32
- package/src/lib/model/listing-visibility.js.map +1 -1
- package/src/lib/model/publisher-agreement.d.ts +105 -8
- package/src/lib/model/publisher-agreement.js +131 -24
- package/src/lib/model/publisher-agreement.js.map +1 -1
- package/src/lib/model/site-starter-listing.js +4 -1
- package/src/lib/model/site-starter-listing.js.map +1 -1
- package/src/lib/model/starter-query.d.ts +159 -0
- package/src/lib/model/starter-query.js +267 -0
- package/src/lib/model/starter-query.js.map +1 -0
- package/src/lib/plugin.js +12 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/checkout.js +45 -12
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/preview-image.js +38 -8
- package/src/lib/server/preview-image.js.map +1 -1
- package/src/lib/server/publish-dataset-schema.js +27 -2
- package/src/lib/server/publish-dataset-schema.js.map +1 -1
- package/src/lib/server/publish-email-starter.js +27 -2
- package/src/lib/server/publish-email-starter.js.map +1 -1
- package/src/lib/server/publish-email-template.js +27 -2
- package/src/lib/server/publish-email-template.js.map +1 -1
- package/src/lib/server/publish-layout.js +27 -2
- package/src/lib/server/publish-layout.js.map +1 -1
- package/src/lib/server/publish-plugin.js +120 -14
- package/src/lib/server/publish-plugin.js.map +1 -1
- package/src/lib/server/publish-preconditions.d.ts +13 -9
- package/src/lib/server/publish-preconditions.js +19 -45
- package/src/lib/server/publish-preconditions.js.map +1 -1
- package/src/lib/server/publish-starter.js +27 -2
- package/src/lib/server/publish-starter.js.map +1 -1
- package/src/lib/server/publish-template.js +27 -2
- package/src/lib/server/publish-template.js.map +1 -1
- package/src/lib/server/publish-theme.js +27 -2
- package/src/lib/server/publish-theme.js.map +1 -1
- package/src/lib/server/publish.js +27 -2
- package/src/lib/server/publish.js.map +1 -1
- package/src/lib/server/publisher-agreement-acceptance.d.ts +49 -0
- package/src/lib/server/publisher-agreement-acceptance.js +97 -0
- package/src/lib/server/publisher-agreement-acceptance.js.map +1 -0
- package/src/lib/server/publisher-profile-save.js +46 -97
- package/src/lib/server/publisher-profile-save.js.map +1 -1
- package/src/lib/server/site-starter-source.js +97 -25
- package/src/lib/server/site-starter-source.js.map +1 -1
- package/src/lib/server/starters.d.ts +31 -0
- package/src/lib/server/starters.js +170 -0
- package/src/lib/server/starters.js.map +1 -0
- package/src/lib/server/verification-request.js +33 -8
- package/src/lib/server/verification-request.js.map +1 -1
- package/src/lib/server.js +14 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/components/publisher-agreement-client.d.ts +0 -48
- package/src/lib/components/publisher-agreement-client.js +0 -93
- package/src/lib/components/publisher-agreement-client.js.map +0 -1
- package/src/lib/components/publisher-agreement-dialog.component.d.ts +0 -47
- package/src/lib/components/publisher-agreement-dialog.component.js +0 -222
- package/src/lib/components/publisher-agreement-dialog.component.js.map +0 -1
- package/src/lib/components/use-publisher-agreement-gate.d.ts +0 -58
- package/src/lib/components/use-publisher-agreement-gate.js +0 -166
- package/src/lib/components/use-publisher-agreement-gate.js.map +0 -1
- package/src/lib/model/publisher-agreement-refusal.d.ts +0 -46
- package/src/lib/model/publisher-agreement-refusal.js +0 -41
- package/src/lib/model/publisher-agreement-refusal.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/marketplace/src/lib/components/publish-plugin-form.component.tsx"],"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'use client'\n\nimport {\n formatMediaRef,\n offeredPluginVersion,\n useMediaPicker,\n type PluginRevocation,\n} from '@aglyn/aglyn'\nimport {\n isBelowMarketplacePriceFloor,\n marketplacePriceCostNote,\n marketplacePriceFloorHint,\n} from '../model/listing-price-floor'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n FormControlLabel,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useRouter } from 'next/navigation'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n missingAttestationSubjects,\n PUBLISHER_ATTESTATION,\n requiredAttestationIds,\n} from '../model/publisher-attestation'\nimport {\n MarkdownField,\n type MarkdownFieldHandle,\n} from '@aglyn/aglyn-markdown-editor'\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { inheritedMediaAlt } from '@aglyn/aglyn/app-utils/media-metadata'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { listingPath } from '../model/marketplace-paths'\nimport usePublisherAgreementGate from './use-publisher-agreement-gate'\n\n// Mirrors the server taxonomy; the server re-validates (the console cannot\n// import the marketplace plugin's model — scope:app may not reach aglyn:addons).\nconst LISTING_CATEGORIES = [\n 'analytics',\n 'automation',\n 'commerce',\n 'communication',\n 'content',\n 'design',\n 'forms',\n 'integrations',\n 'marketing',\n 'productivity',\n 'seo',\n 'security',\n] as const\n\n// Mirrors `validateListingContent`'s URL rule, which is what the publish\n// route enforces — this only saves a round trip (AGL-1076).\nconst isHttpsUrl = (value: string) =>\n /^https:\\/\\/[^\\s]+$/.test(value.trim()) && value.trim().length <= 500\n\n/** Base64-encode file bytes without a data: prefix. */\nasync function fileToBase64(file: File): Promise<string> {\n const buffer = await file.arrayBuffer()\n let binary = ''\n const bytes = new Uint8Array(buffer)\n for (let i = 0; i < bytes.length; i += 1)\n binary += String.fromCharCode(bytes[i])\n return btoa(binary)\n}\n\n/**\n * Everything the draft can hold.\n *\n * The bundle File is deliberately absent. A File cannot be serialized, and\n * a draft that silently restores every field except the one that decides\n * what actually ships is worse than no draft — the publisher would believe\n * they were republishing the bytes they left with. It is re-chosen, and the\n * page says so rather than pretending otherwise.\n */\ninterface PublishDraft {\n manifestText: string\n displayName: string\n description: string\n category: string\n changelog: string\n priceUsd: string\n readme: string\n license: string\n repositoryUrl: string\n visibility: 'public' | 'private'\n attested: string[]\n}\n\n/**\n * One verifier finding as the publish API returns it (AGL-1091). Declared\n * locally rather than imported: the shared type lives in the server barrel,\n * which carries the parser this form must never ship to a browser.\n */\ninterface PublishProblem {\n level?: string\n message: string\n /** Which check produced it (AGL-1087) — absent on older responses. */\n check?: string\n}\n\nconst EMPTY_DRAFT: PublishDraft = {\n manifestText: '',\n displayName: '',\n description: '',\n category: '',\n changelog: '',\n priceUsd: '0',\n readme: '',\n license: '',\n repositoryUrl: '',\n visibility: 'public',\n attested: [],\n}\n\n// Scoped per listing (AGL-1008): an update draft and a new-listing draft\n// are different submissions, and sharing one key would let a half-written\n// update reappear on top of a first publish.\nconst draftKey = (orgId: string, listingId?: string) =>\n `aglyn.publish-plugin.draft.${orgId}${listingId ? `.${listingId}` : ''}`\n\n/**\n * Read the stored draft, during render.\n *\n * Deliberately NOT an effect. Restoring in one effect while a second effect\n * persists on every change is a race that Strict Mode wins: React\n * double-invokes effects in development, so the persist pass writes the\n * still-empty state back over storage BEFORE the restore's `setDraft` has\n * applied, and the re-run then restores the emptiness it just wrote. The\n * draft looked correct in jsdom (no Strict Mode) and silently vanished in\n * the browser. A read during initialization has no ordering to lose.\n */\nfunction readDraft(orgId: string, listingId?: string): PublishDraft {\n if (typeof window === 'undefined' || !orgId) return EMPTY_DRAFT\n try {\n const stored = window.localStorage.getItem(draftKey(orgId, listingId))\n if (!stored) return EMPTY_DRAFT\n return { ...EMPTY_DRAFT, ...(JSON.parse(stored) as Partial<PublishDraft>) }\n } catch {\n // A corrupt draft is not worth failing the page over.\n return EMPTY_DRAFT\n }\n}\n\n/**\n * Fill an update's form from the listing it is bound to (AGL-1008).\n *\n * A saved draft wins over the listing on every field: the listing is where\n * you START from, and overwriting an edit someone made and reloaded away\n * from would be the same data loss the draft exists to prevent.\n *\n * `changelog` is deliberately never seeded. It is the one field that\n * describes THIS version, and carrying the previous version's text forward\n * is how a changelog ends up describing a release it has nothing to do\n * with — which the AGL-969 attestation then asks the publisher to confirm.\n */\nfunction seedDraft(\n draft: PublishDraft,\n listing: UpdateTargetListing | null | undefined,\n): PublishDraft {\n if (!listing?.$id) return draft\n const seeded = { ...draft }\n const carry = <K extends keyof PublishDraft>(\n key: K,\n value: string | undefined,\n ) => {\n if (seeded[key] === EMPTY_DRAFT[key] && value) {\n seeded[key] = value as PublishDraft[K]\n }\n }\n carry('displayName', listing.displayName)\n carry('description', listing.description)\n carry('category', listing.categories?.[0] ?? listing.category)\n carry('readme', listing.readme)\n carry('license', listing.license)\n carry('repositoryUrl', listing.repositoryUrl)\n if (seeded.priceUsd === EMPTY_DRAFT.priceUsd && listing.priceUsd) {\n seeded.priceUsd = String(listing.priceUsd)\n }\n // Visibility is set on FIRST publish only — the server ignores it on a\n // version bump — so reflect what the listing actually is rather than\n // offering a choice that would be silently discarded.\n if (listing.visibility === 'private') seeded.visibility = 'private'\n return seeded\n}\n\n/**\n * Whether a stored draft is worth telling anyone about.\n *\n * The persist effect runs on mount, so an untouched form writes its\n * starting state straight back — and without this the NEXT first visit\n * would announce \"picked up where you left off\" over a form nobody had\n * typed in. A restore notice that fires when nothing was restored is how a\n * publisher learns to ignore it, which is expensive on the one visit it\n * matters.\n *\n * Compared against the BASELINE rather than the empty draft: on an update\n * the baseline is the listing's own content (AGL-1008), so an untouched\n * update form is not a resumed one.\n */\nfunction draftDiffersFrom(\n draft: Partial<PublishDraft>,\n baseline: PublishDraft,\n): boolean {\n return (Object.keys(EMPTY_DRAFT) as Array<keyof PublishDraft>).some((key) => {\n const value = draft[key]\n if (value === undefined) return false\n if (Array.isArray(value)) {\n const other = baseline[key]\n return (\n !Array.isArray(other) ||\n value.length !== other.length ||\n value.some((entry, index) => entry !== other[index])\n )\n }\n return value !== baseline[key]\n })\n}\n\n/** The listing an update is bound to (AGL-1008), as the console reads it. */\nexport interface UpdateTargetListing {\n $id: string\n displayName?: string\n pluginId?: string\n latestVersion?: string | number\n latestApprovedVersion?: string | number\n description?: string\n category?: string\n categories?: string[]\n readme?: string\n license?: string\n repositoryUrl?: string\n priceUsd?: number\n visibility?: string\n}\n\nexport interface PublishPluginFormProps {\n orgId: string\n /**\n * Where the marketplace hub is mounted under this organization, from the\n * shell (AGL-3080). The listing the publish lands on hangs beneath it; it\n * replaced an org slug and the console's route table, which a plugin may\n * not import.\n */\n basePath: string\n /**\n * Set when publishing a NEW VERSION of an existing listing (AGL-1008).\n * The server still decides whether a submission is an update, from\n * `profileId` + the manifest id — this only pre-binds the form so the\n * publisher is not retyping a listing they already own, and so the page\n * can say what is about to happen.\n */\n listing?: UpdateTargetListing | null\n /**\n * The listing's kill switch (AGL-2368), so `liveVersion` below can answer\n * \"what installs today\" rather than \"what review last approved\". Those are\n * different questions and `latestApprovedVersion` only answers the second.\n */\n revocation?: PluginRevocation | null\n}\n\n/**\n * The plugin publish form (AGL-1078), as a page.\n *\n * It was a modal. A publish is the most consequential thing a publisher\n * does — it puts executable code in front of every workspace that installs\n * it — and it had no URL to link or resume, no draft, and no room, which is\n * why the AGL-969 checklist ended up below the publish button where it had\n * to be scrolled past to be read.\n *\n * Same server contract: this posts the identical body to\n * `/api/marketplace/publish-plugin`. What changed is the container, and what\n * the container makes possible — sections, a draft that survives a reload,\n * server problems shown against the field that caused them, and somewhere\n * to go afterwards.\n */\nexport function PublishPluginForm(props: PublishPluginFormProps) {\n const { orgId, basePath, listing, revocation } = props\n const isUpdate = Boolean(listing?.$id)\n const { data: user } = useUser()\n const router = useRouter()\n const { enqueueSnackbar } = useSnackbar()\n const [busy, setBusy] = useState(false)\n\n const bundleRef = useRef<HTMLInputElement>(null)\n const manifestRef = useRef<HTMLInputElement>(null)\n const [bundleFile, setBundleFile] = useState<File | null>(null)\n const [manifestFile, setManifestFile] = useState<File | null>(null)\n // Inline README images come from the shared DAM, like everywhere else.\n const readmeEditorRef = useRef<MarkdownFieldHandle | null>(null)\n /*\n * The console's media library, opened through the picker context rather\n * than by mounting its dialog (AGL-3080): the library is coupled to the\n * org and the session, which a plugin has no way to reach, and the console\n * provides `pickMedia` around every plugin page for exactly this.\n */\n const { pickMedia } = useMediaPicker()\n const insertReadmeImage = useCallback(async () => {\n const media = await pickMedia?.({ kind: 'image' })\n if (!media) return\n // A reference, not the origin-absolute CDN URL (AGL-1705) — the same\n // switch the listing detail editor's README body makes, and for the\n // reason established there: this markdown renders only in the console,\n // through the one `marketplaceListing` slot, so nothing was relying on\n // the baked-in origin. The URL stays the fallback for a free-tier asset,\n // which is minted no `cdnPath` and so has no reference to name.\n const src = formatMediaRef(media.mediaScope, media.mediaId) ?? media.url\n // The alt was a hardcoded '' (AGL-1896). Same reasoning as the listing\n // detail editor: no alt prompt exists on this surface, and a\n // markdown-lite image row's alt is fixed at insert time — so the asset's\n // own alt is the only description that could ever land here, and '' was\n // otherwise permanent.\n if (src)\n readmeEditorRef.current?.insertImage(\n inheritedMediaAlt({ assetAlt: media.alt }) ?? '',\n src,\n )\n }, [pickMedia])\n // What an untouched form looks like: empty for a first publish, the\n // listing's own content for an update (AGL-1008).\n const baseline = seedDraft(EMPTY_DRAFT, listing)\n const [draft, setDraft] = useState<PublishDraft>(() =>\n seedDraft(readDraft(orgId, listing?.$id), listing),\n )\n const [draftRestored, setDraftRestored] = useState(() =>\n draftDiffersFrom(\n seedDraft(readDraft(orgId, listing?.$id), listing),\n seedDraft(EMPTY_DRAFT, listing),\n ),\n )\n\n // Server-side problems, held against the field that caused them (AGL-1078)\n // instead of thrown at a snackbar that is gone before it is read. Cleared\n // on every submit so a fixed problem stops being shown as one.\n //\n // Objects, not strings (AGL-1091): the verifier has always answered with\n // `{level, message, check}` and this held `string[]`, so rendering a\n // rejection threw \"objects are not valid as a React child\" and the error\n // boundary ate the very card that was supposed to explain the rejection.\n // Normalized on arrival so a plain string from anywhere else still reads.\n const [problems, setProblems] = useState<PublishProblem[]>([])\n const [missingAttestations, setMissingAttestations] = useState<string[]>([])\n const [agreementProblem, setAgreementProblem] = useState('')\n // The publisher agreement (AGL-3407), asked for HERE rather than on the\n // Publisher Profile tab: offered as the form opens when the org's\n // acceptance is missing or stale, and presented again if the publish is\n // refused for it — accepting sends the same bundle and fields again.\n const agreement = usePublisherAgreementGate({ orgId, offer: true })\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({})\n\n const set = <K extends keyof PublishDraft>(key: K) =>\n (value: PublishDraft[K]) =>\n setDraft((current) => ({ ...current, [key]: value }))\n\n // Written back on every change — one small JSON blob, and the only thing\n // that makes a reload safe. Safe to run on the first pass now that the\n // restore happens during initialization: the value it writes IS the\n // restored one, so there is nothing left to clobber.\n useEffect(() => {\n if (!orgId) return\n try {\n window.localStorage.setItem(\n draftKey(orgId, listing?.$id),\n JSON.stringify(draft),\n )\n } catch {\n // Storage full or blocked — the form still works, it just won't survive.\n }\n }, [orgId, listing?.$id, draft])\n\n const clearDraft = useCallback(() => {\n try {\n window.localStorage.removeItem(draftKey(orgId, listing?.$id))\n } catch {\n // Nothing to do; the next publish overwrites it anyway.\n }\n }, [orgId, listing?.$id])\n\n const toggleAttestation = (id: string) =>\n setDraft((current) => ({\n ...current,\n attested: current.attested.includes(id)\n ? current.attested.filter((entry) => entry !== id)\n : [...current.attested, id],\n }))\n\n /**\n * What this page blocks on locally.\n *\n * On a first publish the changelog item is `updateOnly` and this form\n * genuinely cannot know whether the manifest id already has a listing —\n * the server answers that and names it in a 428. Demanding a changelog\n * attestation from a first-time publisher would be the worse failure: an\n * item that does not apply teaches people to tick without reading.\n *\n * Bound to a listing (AGL-1008) we DO know, so the update-only item is\n * asked here rather than arriving as a refusal after the upload.\n */\n const unattested = requiredAttestationIds(isUpdate).filter(\n (id) => !draft.attested.includes(id),\n )\n const unfilledSubjects = missingAttestationSubjects(\n { repositoryUrl: draft.repositoryUrl },\n isUpdate,\n )\n const repositoryInvalid =\n Boolean(draft.repositoryUrl.trim()) && !isHttpsUrl(draft.repositoryUrl)\n\n /**\n * The manifest id typed or pasted so far, if it parses.\n *\n * Only used to catch the one way a pre-bound update silently isn't one:\n * the server decides update-vs-new from `profileId` + the manifest id, so\n * a bundle whose id does not match this listing creates a SECOND listing\n * while the page says \"new version\". Cheap to notice here; impossible to\n * undo afterwards, because a published version is immutable.\n */\n const typedManifestId = (() => {\n const raw = draft.manifestText.trim()\n if (!raw) return ''\n try {\n const parsed = JSON.parse(raw) as { id?: unknown }\n return typeof parsed?.id === 'string' ? parsed.id : ''\n } catch {\n return ''\n }\n })()\n const manifestIdMismatch = Boolean(\n isUpdate && typedManifestId && listing?.pluginId &&\n typedManifestId !== listing.pluginId,\n )\n\n /**\n * What is serving customers right now (AGL-2368).\n *\n * This prints as \"v{X} is what installs today\", which is an INSTALL claim,\n * and it was reading a REVIEW verdict — the kill switch does not clear\n * `latestApprovedVersion`, so a publisher whose live version had been\n * stopped was told it was still installing, on the page they had come to\n * to ship its replacement.\n *\n * Falls through to nothing rather than to `latestVersion` when the offer is\n * revoked: the alert's other branch already says \"nothing installs until a\n * reviewer approves it\", which is the truth in that state.\n */\n const liveVersion = String(\n offeredPluginVersion(listing, revocation) ?? listing?.latestVersion ?? '',\n )\n\n const readManifest = async (): Promise<Record<string, unknown> | null> => {\n // A pasted manifest wins; otherwise read the chosen file.\n const raw = draft.manifestText.trim()\n ? draft.manifestText\n : manifestFile\n ? await manifestFile.text()\n : ''\n if (!raw) return null\n try {\n const parsed = JSON.parse(raw)\n return parsed && typeof parsed === 'object' ? parsed : null\n } catch {\n return null\n }\n }\n\n const submit = async () => {\n setProblems([])\n setMissingAttestations([])\n setAgreementProblem('')\n setFieldErrors({})\n if (!bundleFile) {\n setFieldErrors({ bundle: 'Choose a plugin bundle (.js) to upload.' })\n return\n }\n const manifest = await readManifest()\n if (!manifest) {\n setFieldErrors({\n manifest: 'Add a valid manifest (JSON) — id, name, version and entry.',\n })\n return\n }\n setBusy(true)\n try {\n const bundle = await fileToBase64(bundleFile)\n // Serialized once: a retry after the agreement is accepted sends the\n // bytes this attempt did, not whatever the form holds by then.\n const body = JSON.stringify({\n orgId,\n bundle,\n manifest,\n displayName:\n draft.displayName.trim() ||\n String((manifest as { name?: unknown }).name ?? '').trim(),\n description: draft.description.trim(),\n category: draft.category || undefined,\n changelog: draft.changelog.trim(),\n // A private plugin has no buyers — its only audience already owns\n // it — so it publishes free regardless of what the field held\n // before the publisher switched visibility.\n priceUsd:\n draft.visibility === 'private'\n ? 0\n : Math.max(0, Math.round(Number(draft.priceUsd) || 0)),\n visibility: draft.visibility,\n attestation: draft.attested,\n ...(draft.readme.trim() ? { readme: draft.readme.trim() } : {}),\n ...(draft.license.trim() ? { license: draft.license.trim() } : {}),\n ...(draft.repositoryUrl.trim()\n ? { repositoryUrl: draft.repositoryUrl.trim() }\n : {}),\n })\n const { response, payload, declined } = await agreement.send(() =>\n authorizedFetch(user, '/api/marketplace/publish-plugin', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body,\n }),\n )\n if (!response.ok) {\n if (Array.isArray(payload?.problems)) {\n setProblems(\n payload.problems.map((problem: unknown) =>\n typeof problem === 'string'\n ? { message: problem }\n : {\n level: String(\n (problem as PublishProblem)?.level ?? 'error',\n ),\n message: String((problem as PublishProblem)?.message ?? ''),\n check: (problem as PublishProblem)?.check\n ? String((problem as PublishProblem).check)\n : undefined,\n },\n ),\n )\n }\n if (Array.isArray(payload?.missingAttestations)) {\n setMissingAttestations(payload.missingAttestations)\n }\n // The agreement was presented and closed without accepting\n // (AGL-3407). Held as an alert with the way back to it, not a toast:\n // the dialog already said why, and the form keeps everything.\n if (declined) {\n return void setAgreementProblem(String(payload.error ?? ''))\n }\n // A rejected subject names its field (AGL-1076), so put the message\n // where the value is rather than in a banner about a form.\n if (Array.isArray(payload?.missingAttestationSubjects)) {\n setFieldErrors(\n Object.fromEntries(\n payload.missingAttestationSubjects.map((field: string) => [\n field,\n String(payload.error ?? 'Required'),\n ]),\n ),\n )\n }\n return void enqueueSnackbar(payload?.error ?? 'Publish failed', {\n variant: response.status === 501 ? 'info' : 'error',\n allowDuplicate: true,\n })\n }\n // Somewhere to go (AGL-1078). The dialog closed onto the panel it\n // opened from, which said nothing about what had just happened; the\n // listing shows the version now queued for review.\n clearDraft()\n enqueueSnackbar(\n `Published v${payload?.version ?? '1'} — it is queued for review`,\n { variant: 'success' },\n )\n router.push(listingPath(basePath, String(payload?.listingId ?? '')))\n } catch (error) {\n console.error(error)\n enqueueSnackbar('An error has occurred', {\n variant: 'error',\n allowDuplicate: true,\n })\n } finally {\n setBusy(false)\n }\n }\n\n // A price under the floor is refused by the publish route (AGL-2343), so the\n // button holds rather than letting a publisher upload a bundle and read the\n // minimum off a 400. A private plugin has no price at all — its field is\n // disabled and sends 0 — so it can never be blocked by this.\n const priceBelowFloor =\n draft.visibility !== 'private' &&\n isBelowMarketplacePriceFloor(draft.priceUsd)\n\n const blocked =\n busy ||\n !bundleFile ||\n unattested.length > 0 ||\n unfilledSubjects.length > 0 ||\n repositoryInvalid ||\n manifestIdMismatch ||\n priceBelowFloor\n\n return (\n <Stack spacing={2}>\n {isUpdate ? (\n /* AGL-1008. The mechanism was always right — same profileId plus\n manifest id bumps the listing, the new version enters review as\n pending, and the approved one keeps installing (AGL-966). The UI\n never told that story, so updating read like creating a second\n listing. */\n <Alert severity=\"info\">\n <Typography variant=\"subtitle2\">\n {`New version of ${listing?.displayName ?? 'your plugin'}`}\n </Typography>\n <Typography variant=\"caption\" component=\"div\">\n {liveVersion\n ? `v${liveVersion} is what installs today. It keeps installing ` +\n 'until a reviewer approves this one — nobody is upgraded ' +\n 'onto unreviewed code, and nothing you publish here can ' +\n 'change a version already installed.'\n : 'This version enters review. Nothing installs until a ' +\n 'reviewer approves it.'}\n </Typography>\n </Alert>\n ) : (\n <Alert severity=\"info\">\n {'Plugins publish sandboxed — they run isolated and can’t touch ' +\n 'site data directly. A reviewer verifies and signs yours before ' +\n 'it can run trusted.'}\n </Alert>\n )}\n\n {manifestIdMismatch ? (\n <Alert severity=\"warning\">\n {`This manifest says \"${typedManifestId}\", but ${\n listing?.displayName ?? 'this listing'\n } publishes \"${listing?.pluginId}\". Publishing it would create a ` +\n 'separate new listing rather than a new version of this one.'}\n </Alert>\n ) : null}\n\n {draftRestored ? (\n <Alert severity=\"info\" onClose={() => setDraftRestored(false)}>\n {'Picked up where you left off. Your bundle and manifest file are ' +\n 'not saved — choose them again before publishing.'}\n </Alert>\n ) : null}\n\n {agreementProblem ? (\n <Alert\n severity=\"warning\"\n action={\n <Button color=\"inherit\" size=\"small\" onClick={agreement.review}>\n {'Review the agreement'}\n </Button>\n }\n >\n {agreementProblem}\n </Alert>\n ) : null}\n {agreement.dialog}\n\n <CardDisplay\n header={isUpdate ? 'The new bundle and manifest' : 'Bundle and manifest'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#bundle-and-manifest',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <Stack spacing={0.5}>\n <Typography variant=\"subtitle2\">{'Bundle (.js)'}</Typography>\n <input\n ref={bundleRef}\n type=\"file\"\n accept=\".js,text/javascript,application/javascript\"\n hidden\n onChange={(event) =>\n setBundleFile(event.target.files?.[0] ?? null)\n }\n />\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button size=\"small\" onClick={() => bundleRef.current?.click()}>\n {'Choose bundle'}\n </Button>\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>\n {bundleFile?.name ?? 'No file chosen'}\n </Typography>\n </Stack>\n <Typography\n variant=\"caption\"\n color={fieldErrors['bundle'] ? 'error.main' : 'text.secondary'}\n >\n {fieldErrors['bundle'] ??\n 'One self-contained bundle. It’s parsed and checked before ' +\n 'publishing — forbidden APIs, size, and every network ' +\n 'call against the origins your manifest declares.'}\n </Typography>\n </Stack>\n\n <Stack spacing={0.5}>\n <Typography variant=\"subtitle2\">\n {'Manifest (JSON: id, name, version, entry)'}\n </Typography>\n <input\n ref={manifestRef}\n type=\"file\"\n accept=\".json,application/json\"\n hidden\n onChange={(event) =>\n setManifestFile(event.target.files?.[0] ?? null)\n }\n />\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button size=\"small\" onClick={() => manifestRef.current?.click()}>\n {'Choose manifest.json'}\n </Button>\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>\n {manifestFile?.name ?? 'or paste below'}\n </Typography>\n </Stack>\n <TextField\n placeholder='{ \"id\": \"acme-widget\", \"name\": \"Widget\", \"version\": \"1.0.0\", \"entry\": \"index.js\" }'\n value={draft.manifestText}\n onChange={(event) => set('manifestText')(event.target.value)}\n size=\"small\"\n multiline\n minRows={4}\n fullWidth\n error={Boolean(fieldErrors['manifest'])}\n helperText={fieldErrors['manifest'] ?? ' '}\n />\n </Stack>\n\n {problems.length ? (\n <Alert\n severity={\n problems.some((problem) => problem.level !== 'warning')\n ? 'error'\n : 'warning'\n }\n >\n <Typography variant=\"subtitle2\">\n {problems.some((problem) => problem.level !== 'warning')\n ? 'Bundle failed verification'\n : 'Bundle verified, with things to check'}\n </Typography>\n <ul style={{ margin: '4px 0 0', paddingLeft: 18 }}>\n {problems.map((problem, index) => (\n <li key={`${problem.check ?? 'problem'}-${index}`}>\n <Typography variant=\"caption\">\n {problem.check ? `${problem.check}: ` : ''}\n {problem.message}\n </Typography>\n </li>\n ))}\n </ul>\n </Alert>\n ) : null}\n </Stack>\n </CardDisplay>\n\n <CardDisplay\n header={'Listing'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#authoring-your-listing',\n excerpt:\n 'What a reviewer reads first and a buyer reads before running ' +\n 'third-party code.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <TextField\n label=\"Listing name\"\n helperText=\"Defaults to the manifest name\"\n value={draft.displayName}\n onChange={(event) => set('displayName')(event.target.value)}\n size=\"small\"\n />\n <TextField\n label=\"Description\"\n helperText=\"The one-line summary on browse cards\"\n value={draft.description}\n onChange={(event) => set('description')(event.target.value)}\n size=\"small\"\n multiline\n minRows={2}\n />\n <TextField\n select\n label=\"Category\"\n value={draft.category}\n onChange={(event) => set('category')(event.target.value)}\n size=\"small\"\n >\n <MenuItem value=\"\">{'None'}</MenuItem>\n {LISTING_CATEGORIES.map((entry) => (\n <MenuItem key={entry} value={entry}>\n {entry}\n </MenuItem>\n ))}\n </TextField>\n {/* The same editor the listing detail page uses (AGL-1080). The\n first time a publisher writes the document reviewers read\n first used to get the worst tool we have, and the second time\n the good one — for the same field. The AGL-969 attestation\n made that worse by asking them to confirm the README\n documents what data the plugin handles, in a box too small to\n see whether it does. */}\n <MarkdownField\n label=\"README\"\n value={draft.readme}\n onChange={set('readme')}\n onPickImageFromMedia={insertReadmeImage}\n editorRef={(handle) => {\n readmeEditorRef.current = handle\n }}\n helperText={\n 'Shown on your listing page — what it does, how to configure ' +\n 'it, and what it reads, stores or sends. Reviewers and ' +\n 'cautious buyers read this first.'\n }\n />\n {/* The only field that exclusively concerns updates (AGL-1080).\n It was a single line labelled `Changelog` and nothing else,\n presented as an equal peer of Category — while AGL-969 attests\n to it and AGL-976 builds the listing's changelog tab out of\n it. The helper names both audiences, because \"what changed\"\n means something different to each. */}\n <TextField\n label=\"Changelog\"\n placeholder=\"Fixed the timer drift on Safari; added a compact layout\"\n helperText={\n isUpdate\n ? 'The field that matters most on an update. Two audiences: ' +\n 'the reviewer, comparing these bytes against ' +\n (liveVersion ? `v${liveVersion}` : 'the last approved ' +\n 'version') +\n ', and every installer deciding whether to move off the ' +\n 'version they are running.'\n : 'Two audiences: the reviewer, comparing this version ' +\n 'against the last approved one, and every installer who ' +\n 'reads it on your listing’s changelog tab before ' +\n 'updating. On a first version there is nothing to compare ' +\n 'against — say what the plugin does instead, or leave it.'\n }\n value={draft.changelog}\n onChange={(event) => set('changelog')(event.target.value)}\n size=\"small\"\n multiline\n minRows={3}\n />\n {/* AGL-1076: the subject of the repository attestation below. */}\n <TextField\n label=\"Repository URL\"\n placeholder=\"https://github.com/acme/widget\"\n required\n error={repositoryInvalid || Boolean(fieldErrors['repositoryUrl'])}\n helperText={\n repositoryInvalid\n ? 'Must be an https URL.'\n : (fieldErrors['repositoryUrl'] ??\n 'The source for this bundle. A reviewer opens it first — ' +\n 'it is what the repository confirmation below is about.')\n }\n value={draft.repositoryUrl}\n onChange={(event) => set('repositoryUrl')(event.target.value)}\n size=\"small\"\n />\n <TextField\n label=\"License\"\n placeholder=\"MIT\"\n helperText=\"Short label, e.g. MIT or Apache-2.0\"\n value={draft.license}\n onChange={(event) => set('license')(event.target.value)}\n size=\"small\"\n />\n </Stack>\n </CardDisplay>\n\n <CardDisplay\n header={'Who can install it, and for how much'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#private-plugins',\n excerpt:\n 'Private is a choice about audience, not about trust — it takes ' +\n 'the identical review path.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n {/* Private plugins (AGL-968/992): deliberately worded as an\n AUDIENCE choice — private is not a faster lane, and the caption\n says so, because \"skip the queue\" is the reading it would\n otherwise invite. */}\n <TextField\n select\n label=\"Who can install this\"\n value={draft.visibility}\n // Set on FIRST publish only — the server ignores it on a version\n // bump (AGL-968), so offering the choice here would be a control\n // that silently does nothing. Change it from the listing.\n disabled={isUpdate}\n onChange={(event) =>\n set('visibility')(event.target.value as 'public' | 'private')\n }\n size=\"small\"\n helperText={\n isUpdate\n ? 'Set when the listing was created. Change it from the ' +\n 'listing — a new version never changes who can install it.'\n :\n draft.visibility === 'private'\n ? 'Private plugins take the same review path — same ' +\n 'queue, same checklist, same verifier, same signature ' +\n 'for realm trust. They are never listed in the ' +\n 'marketplace, and only your sites can install them.'\n : 'Listed in the marketplace for every workspace once a ' +\n 'reviewer approves it.'\n }\n >\n <MenuItem value=\"public\">\n {'Anyone — publish to the marketplace'}\n </MenuItem>\n <MenuItem value=\"private\">\n {'Only this organization — private plugin'}\n </MenuItem>\n </TextField>\n <TextField\n label=\"Price (USD)\"\n // A private plugin has no buyers, and a price on one would only\n // send the publisher through Stripe onboarding to sell to\n // themselves.\n disabled={draft.visibility === 'private'}\n // The minimum price (AGL-2343), from the same functions every other\n // publish form reads, so no two forms can quote different figures\n // at a publisher — and stated up front rather than only on refusal.\n error={priceBelowFloor}\n helperText={\n draft.visibility === 'private'\n ? 'Private plugins are free — nobody else can install them.'\n : (marketplacePriceCostNote(draft.priceUsd) ??\n marketplacePriceFloorHint(\n 'Paid listings need payouts set up.',\n ))\n }\n type=\"number\"\n value={draft.visibility === 'private' ? '0' : draft.priceUsd}\n onChange={(event) => set('priceUsd')(event.target.value)}\n size=\"small\"\n />\n </Stack>\n </CardDisplay>\n\n {/* The checklist last, in full view of the publish button (AGL-969 /\n AGL-1078). In the dialog it sat below the button and had to be\n scrolled past to be seen at all. Every item is a statement only the\n publisher can make. */}\n <CardDisplay\n header={'Before you publish'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#before-you-publish',\n excerpt:\n 'Recorded against this exact bundle, with your name and the ' +\n 'date, and shown to the reviewer.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Recorded against this exact bundle, with your name and the ' +\n 'date, and shown to the reviewer. Republishing the same ' +\n 'version number asks again — the bytes changed.'}\n </Typography>\n {missingAttestations.length ? (\n <Alert severity=\"warning\">\n {'This plugin already has a published version, so the ' +\n 'highlighted item applies too.'}\n </Alert>\n ) : null}\n {PUBLISHER_ATTESTATION.map((item) => {\n const flagged = missingAttestations.includes(item.id)\n return (\n <Stack key={item.id} spacing={0.25}>\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={draft.attested.includes(item.id)}\n disabled={busy}\n onChange={() => toggleAttestation(item.id)}\n />\n }\n label={\n <Stack\n useFlexGap\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flexWrap: 'wrap' }}\n >\n <Typography\n variant=\"body2\"\n color={flagged ? 'warning.main' : undefined}\n >\n {item.label}\n </Typography>\n {item.updateOnly ? (\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label=\"Updates only\"\n />\n ) : null}\n </Stack>\n }\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ pl: 4 }}\n >\n {item.detail}\n </Typography>\n </Stack>\n )\n })}\n </Stack>\n </CardDisplay>\n\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => void submit()}\n disabled={blocked}\n >\n {busy\n ? 'Publishing…'\n : !bundleFile\n ? 'Choose a bundle'\n : unattested.length\n ? `Confirm ${unattested.length} more`\n : unfilledSubjects.length || repositoryInvalid\n ? 'Add a repository URL'\n : isUpdate\n ? 'Publish new version'\n : draft.visibility === 'private'\n ? 'Publish privately'\n : 'Publish plugin'}\n </Button>\n <Button\n disabled={busy}\n onClick={() => {\n clearDraft()\n setDraft(baseline)\n setBundleFile(null)\n setManifestFile(null)\n setDraftRestored(false)\n }}\n >\n {'Discard draft'}\n </Button>\n </Stack>\n\n </Stack>\n )\n}\n\nPublishPluginForm.displayName = 'PublishPluginForm'\n\nexport default PublishPluginForm\n"],"names":["formatMediaRef","offeredPluginVersion","useMediaPicker","isBelowMarketplacePriceFloor","marketplacePriceCostNote","marketplacePriceFloorHint","CardDisplay","useSnackbar","Alert","Button","Checkbox","Chip","FormControlLabel","MenuItem","Stack","TextField","Typography","useRouter","useCallback","useEffect","useRef","useState","useUser","missingAttestationSubjects","PUBLISHER_ATTESTATION","requiredAttestationIds","MarkdownField","pluginDocsHelp","inheritedMediaAlt","authorizedFetch","listingPath","usePublisherAgreementGate","LISTING_CATEGORIES","isHttpsUrl","value","test","trim","length","fileToBase64","file","buffer","arrayBuffer","binary","bytes","Uint8Array","i","String","fromCharCode","btoa","EMPTY_DRAFT","manifestText","displayName","description","category","changelog","priceUsd","readme","license","repositoryUrl","visibility","attested","draftKey","orgId","listingId","readDraft","window","stored","localStorage","getItem","JSON","parse","seedDraft","draft","listing","$id","seeded","carry","key","categories","draftDiffersFrom","baseline","Object","keys","some","undefined","Array","isArray","other","entry","index","PublishPluginForm","props","fieldErrors","basePath","revocation","isUpdate","Boolean","data","user","router","enqueueSnackbar","busy","setBusy","bundleRef","manifestRef","bundleFile","setBundleFile","manifestFile","setManifestFile","readmeEditorRef","pickMedia","insertReadmeImage","media","kind","src","mediaScope","mediaId","url","current","insertImage","assetAlt","alt","setDraft","draftRestored","setDraftRestored","problems","setProblems","missingAttestations","setMissingAttestations","agreementProblem","setAgreementProblem","agreement","offer","setFieldErrors","set","setItem","stringify","clearDraft","removeItem","toggleAttestation","id","includes","filter","unattested","unfilledSubjects","repositoryInvalid","typedManifestId","raw","parsed","manifestIdMismatch","pluginId","liveVersion","latestVersion","readManifest","text","submit","bundle","manifest","body","name","Math","max","round","Number","attestation","response","payload","declined","send","method","headers","ok","map","problem","message","level","check","error","fromEntries","field","variant","status","allowDuplicate","version","push","console","priceBelowFloor","blocked","spacing","severity","component","onClose","action","color","size","onClick","review","dialog","header","help","anchor","contentGutterX","contentGutterY","input","ref","type","accept","hidden","onChange","event","target","files","direction","sx","alignItems","click","noWrap","placeholder","multiline","minRows","fullWidth","helperText","ul","style","margin","paddingLeft","li","excerpt","label","select","onPickImageFromMedia","editorRef","handle","required","disabled","item","flagged","control","checked","useFlexGap","flexWrap","updateOnly","pl","detail"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/marketplace/src/lib/components/publish-plugin-form.component.tsx"],"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'use client'\n\nimport {\n formatMediaRef,\n offeredPluginVersion,\n useMediaPicker,\n type PluginRevocation,\n} from '@aglyn/aglyn'\nimport {\n isBelowMarketplacePriceFloor,\n marketplacePriceCostNote,\n marketplacePriceFloorHint,\n} from '../model/listing-price-floor'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n FormControlLabel,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useRouter } from 'next/navigation'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n missingAttestationSubjects,\n PUBLISHER_ATTESTATION,\n requiredAttestationIds,\n} from '../model/publisher-attestation'\nimport {\n MarkdownField,\n type MarkdownFieldHandle,\n} from '@aglyn/aglyn-markdown-editor'\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { inheritedMediaAlt } from '@aglyn/aglyn/app-utils/media-metadata'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { listingPath } from '../model/marketplace-paths'\nimport {\n PublisherAgreementCheckbox,\n usePublisherAgreementConsent,\n} from './publisher-agreement-checkbox.component'\n\n// Mirrors the server taxonomy; the server re-validates (the console cannot\n// import the marketplace plugin's model — scope:app may not reach aglyn:addons).\nconst LISTING_CATEGORIES = [\n 'analytics',\n 'automation',\n 'commerce',\n 'communication',\n 'content',\n 'design',\n 'forms',\n 'integrations',\n 'marketing',\n 'productivity',\n 'seo',\n 'security',\n] as const\n\n// Mirrors `validateListingContent`'s URL rule, which is what the publish\n// route enforces — this only saves a round trip (AGL-1076).\nconst isHttpsUrl = (value: string) =>\n /^https:\\/\\/[^\\s]+$/.test(value.trim()) && value.trim().length <= 500\n\n/** Base64-encode file bytes without a data: prefix. */\nasync function fileToBase64(file: File): Promise<string> {\n const buffer = await file.arrayBuffer()\n let binary = ''\n const bytes = new Uint8Array(buffer)\n for (let i = 0; i < bytes.length; i += 1)\n binary += String.fromCharCode(bytes[i])\n return btoa(binary)\n}\n\n/**\n * Everything the draft can hold.\n *\n * The bundle File is deliberately absent. A File cannot be serialized, and\n * a draft that silently restores every field except the one that decides\n * what actually ships is worse than no draft — the publisher would believe\n * they were republishing the bytes they left with. It is re-chosen, and the\n * page says so rather than pretending otherwise.\n */\ninterface PublishDraft {\n manifestText: string\n displayName: string\n description: string\n category: string\n changelog: string\n priceUsd: string\n readme: string\n license: string\n repositoryUrl: string\n visibility: 'public' | 'private'\n attested: string[]\n}\n\n/**\n * One verifier finding as the publish API returns it (AGL-1091). Declared\n * locally rather than imported: the shared type lives in the server barrel,\n * which carries the parser this form must never ship to a browser.\n */\ninterface PublishProblem {\n level?: string\n message: string\n /** Which check produced it (AGL-1087) — absent on older responses. */\n check?: string\n}\n\nconst EMPTY_DRAFT: PublishDraft = {\n manifestText: '',\n displayName: '',\n description: '',\n category: '',\n changelog: '',\n priceUsd: '0',\n readme: '',\n license: '',\n repositoryUrl: '',\n visibility: 'public',\n attested: [],\n}\n\n// Scoped per listing (AGL-1008): an update draft and a new-listing draft\n// are different submissions, and sharing one key would let a half-written\n// update reappear on top of a first publish.\nconst draftKey = (orgId: string, listingId?: string) =>\n `aglyn.publish-plugin.draft.${orgId}${listingId ? `.${listingId}` : ''}`\n\n/**\n * Read the stored draft, during render.\n *\n * Deliberately NOT an effect. Restoring in one effect while a second effect\n * persists on every change is a race that Strict Mode wins: React\n * double-invokes effects in development, so the persist pass writes the\n * still-empty state back over storage BEFORE the restore's `setDraft` has\n * applied, and the re-run then restores the emptiness it just wrote. The\n * draft looked correct in jsdom (no Strict Mode) and silently vanished in\n * the browser. A read during initialization has no ordering to lose.\n */\nfunction readDraft(orgId: string, listingId?: string): PublishDraft {\n if (typeof window === 'undefined' || !orgId) return EMPTY_DRAFT\n try {\n const stored = window.localStorage.getItem(draftKey(orgId, listingId))\n if (!stored) return EMPTY_DRAFT\n return { ...EMPTY_DRAFT, ...(JSON.parse(stored) as Partial<PublishDraft>) }\n } catch {\n // A corrupt draft is not worth failing the page over.\n return EMPTY_DRAFT\n }\n}\n\n/**\n * Fill an update's form from the listing it is bound to (AGL-1008).\n *\n * A saved draft wins over the listing on every field: the listing is where\n * you START from, and overwriting an edit someone made and reloaded away\n * from would be the same data loss the draft exists to prevent.\n *\n * `changelog` is deliberately never seeded. It is the one field that\n * describes THIS version, and carrying the previous version's text forward\n * is how a changelog ends up describing a release it has nothing to do\n * with — which the AGL-969 attestation then asks the publisher to confirm.\n */\nfunction seedDraft(\n draft: PublishDraft,\n listing: UpdateTargetListing | null | undefined,\n): PublishDraft {\n if (!listing?.$id) return draft\n const seeded = { ...draft }\n const carry = <K extends keyof PublishDraft>(\n key: K,\n value: string | undefined,\n ) => {\n if (seeded[key] === EMPTY_DRAFT[key] && value) {\n seeded[key] = value as PublishDraft[K]\n }\n }\n carry('displayName', listing.displayName)\n carry('description', listing.description)\n carry('category', listing.categories?.[0] ?? listing.category)\n carry('readme', listing.readme)\n carry('license', listing.license)\n carry('repositoryUrl', listing.repositoryUrl)\n if (seeded.priceUsd === EMPTY_DRAFT.priceUsd && listing.priceUsd) {\n seeded.priceUsd = String(listing.priceUsd)\n }\n // Visibility is set on FIRST publish only — the server ignores it on a\n // version bump — so reflect what the listing actually is rather than\n // offering a choice that would be silently discarded.\n if (listing.visibility === 'private') seeded.visibility = 'private'\n return seeded\n}\n\n/**\n * Whether a stored draft is worth telling anyone about.\n *\n * The persist effect runs on mount, so an untouched form writes its\n * starting state straight back — and without this the NEXT first visit\n * would announce \"picked up where you left off\" over a form nobody had\n * typed in. A restore notice that fires when nothing was restored is how a\n * publisher learns to ignore it, which is expensive on the one visit it\n * matters.\n *\n * Compared against the BASELINE rather than the empty draft: on an update\n * the baseline is the listing's own content (AGL-1008), so an untouched\n * update form is not a resumed one.\n */\nfunction draftDiffersFrom(\n draft: Partial<PublishDraft>,\n baseline: PublishDraft,\n): boolean {\n return (Object.keys(EMPTY_DRAFT) as Array<keyof PublishDraft>).some((key) => {\n const value = draft[key]\n if (value === undefined) return false\n if (Array.isArray(value)) {\n const other = baseline[key]\n return (\n !Array.isArray(other) ||\n value.length !== other.length ||\n value.some((entry, index) => entry !== other[index])\n )\n }\n return value !== baseline[key]\n })\n}\n\n/** The listing an update is bound to (AGL-1008), as the console reads it. */\nexport interface UpdateTargetListing {\n $id: string\n displayName?: string\n pluginId?: string\n latestVersion?: string | number\n latestApprovedVersion?: string | number\n description?: string\n category?: string\n categories?: string[]\n readme?: string\n license?: string\n repositoryUrl?: string\n priceUsd?: number\n visibility?: string\n}\n\nexport interface PublishPluginFormProps {\n orgId: string\n /**\n * Where the marketplace hub is mounted under this organization, from the\n * shell (AGL-3080). The listing the publish lands on hangs beneath it; it\n * replaced an org slug and the console's route table, which a plugin may\n * not import.\n */\n basePath: string\n /**\n * Set when publishing a NEW VERSION of an existing listing (AGL-1008).\n * The server still decides whether a submission is an update, from\n * `profileId` + the manifest id — this only pre-binds the form so the\n * publisher is not retyping a listing they already own, and so the page\n * can say what is about to happen.\n */\n listing?: UpdateTargetListing | null\n /**\n * The listing's kill switch (AGL-2368), so `liveVersion` below can answer\n * \"what installs today\" rather than \"what review last approved\". Those are\n * different questions and `latestApprovedVersion` only answers the second.\n */\n revocation?: PluginRevocation | null\n}\n\n/**\n * The plugin publish form (AGL-1078), as a page.\n *\n * It was a modal. A publish is the most consequential thing a publisher\n * does — it puts executable code in front of every workspace that installs\n * it — and it had no URL to link or resume, no draft, and no room, which is\n * why the AGL-969 checklist ended up below the publish button where it had\n * to be scrolled past to be read.\n *\n * Same server contract: this posts the identical body to\n * `/api/marketplace/publish-plugin`. What changed is the container, and what\n * the container makes possible — sections, a draft that survives a reload,\n * server problems shown against the field that caused them, and somewhere\n * to go afterwards.\n */\nexport function PublishPluginForm(props: PublishPluginFormProps) {\n const { orgId, basePath, listing, revocation } = props\n const isUpdate = Boolean(listing?.$id)\n const { data: user } = useUser()\n const router = useRouter()\n const { enqueueSnackbar } = useSnackbar()\n const [busy, setBusy] = useState(false)\n\n const bundleRef = useRef<HTMLInputElement>(null)\n const manifestRef = useRef<HTMLInputElement>(null)\n const [bundleFile, setBundleFile] = useState<File | null>(null)\n const [manifestFile, setManifestFile] = useState<File | null>(null)\n // Inline README images come from the shared DAM, like everywhere else.\n const readmeEditorRef = useRef<MarkdownFieldHandle | null>(null)\n /*\n * The console's media library, opened through the picker context rather\n * than by mounting its dialog (AGL-3080): the library is coupled to the\n * org and the session, which a plugin has no way to reach, and the console\n * provides `pickMedia` around every plugin page for exactly this.\n */\n const { pickMedia } = useMediaPicker()\n const insertReadmeImage = useCallback(async () => {\n const media = await pickMedia?.({ kind: 'image' })\n if (!media) return\n // A reference, not the origin-absolute CDN URL (AGL-1705) — the same\n // switch the listing detail editor's README body makes, and for the\n // reason established there: this markdown renders only in the console,\n // through the one `marketplaceListing` slot, so nothing was relying on\n // the baked-in origin. The URL stays the fallback for a free-tier asset,\n // which is minted no `cdnPath` and so has no reference to name.\n const src = formatMediaRef(media.mediaScope, media.mediaId) ?? media.url\n // The alt was a hardcoded '' (AGL-1896). Same reasoning as the listing\n // detail editor: no alt prompt exists on this surface, and a\n // markdown-lite image row's alt is fixed at insert time — so the asset's\n // own alt is the only description that could ever land here, and '' was\n // otherwise permanent.\n if (src)\n readmeEditorRef.current?.insertImage(\n inheritedMediaAlt({ assetAlt: media.alt }) ?? '',\n src,\n )\n }, [pickMedia])\n // What an untouched form looks like: empty for a first publish, the\n // listing's own content for an update (AGL-1008).\n const baseline = seedDraft(EMPTY_DRAFT, listing)\n const [draft, setDraft] = useState<PublishDraft>(() =>\n seedDraft(readDraft(orgId, listing?.$id), listing),\n )\n const [draftRestored, setDraftRestored] = useState(() =>\n draftDiffersFrom(\n seedDraft(readDraft(orgId, listing?.$id), listing),\n seedDraft(EMPTY_DRAFT, listing),\n ),\n )\n\n // Server-side problems, held against the field that caused them (AGL-1078)\n // instead of thrown at a snackbar that is gone before it is read. Cleared\n // on every submit so a fixed problem stops being shown as one.\n //\n // Objects, not strings (AGL-1091): the verifier has always answered with\n // `{level, message, check}` and this held `string[]`, so rendering a\n // rejection threw \"objects are not valid as a React child\" and the error\n // boundary ate the very card that was supposed to explain the rejection.\n // Normalized on arrival so a plain string from anywhere else still reads.\n const [problems, setProblems] = useState<PublishProblem[]>([])\n const [missingAttestations, setMissingAttestations] = useState<string[]>([])\n // The publisher agreement, agreed to on this publish (AGL-4105): the box\n // above the button. Never part of the draft — a draft restored after a\n // reload asks again, as every publish does.\n const agreement = usePublisherAgreementConsent()\n const [agreementProblem, setAgreementProblem] = useState('')\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({})\n\n const set = <K extends keyof PublishDraft>(key: K) =>\n (value: PublishDraft[K]) =>\n setDraft((current) => ({ ...current, [key]: value }))\n\n // Written back on every change — one small JSON blob, and the only thing\n // that makes a reload safe. Safe to run on the first pass now that the\n // restore happens during initialization: the value it writes IS the\n // restored one, so there is nothing left to clobber.\n useEffect(() => {\n if (!orgId) return\n try {\n window.localStorage.setItem(\n draftKey(orgId, listing?.$id),\n JSON.stringify(draft),\n )\n } catch {\n // Storage full or blocked — the form still works, it just won't survive.\n }\n }, [orgId, listing?.$id, draft])\n\n const clearDraft = useCallback(() => {\n try {\n window.localStorage.removeItem(draftKey(orgId, listing?.$id))\n } catch {\n // Nothing to do; the next publish overwrites it anyway.\n }\n }, [orgId, listing?.$id])\n\n const toggleAttestation = (id: string) =>\n setDraft((current) => ({\n ...current,\n attested: current.attested.includes(id)\n ? current.attested.filter((entry) => entry !== id)\n : [...current.attested, id],\n }))\n\n /**\n * What this page blocks on locally.\n *\n * On a first publish the changelog item is `updateOnly` and this form\n * genuinely cannot know whether the manifest id already has a listing —\n * the server answers that and names it in a 428. Demanding a changelog\n * attestation from a first-time publisher would be the worse failure: an\n * item that does not apply teaches people to tick without reading.\n *\n * Bound to a listing (AGL-1008) we DO know, so the update-only item is\n * asked here rather than arriving as a refusal after the upload.\n */\n const unattested = requiredAttestationIds(isUpdate).filter(\n (id) => !draft.attested.includes(id),\n )\n const unfilledSubjects = missingAttestationSubjects(\n { repositoryUrl: draft.repositoryUrl },\n isUpdate,\n )\n const repositoryInvalid =\n Boolean(draft.repositoryUrl.trim()) && !isHttpsUrl(draft.repositoryUrl)\n\n /**\n * The manifest id typed or pasted so far, if it parses.\n *\n * Only used to catch the one way a pre-bound update silently isn't one:\n * the server decides update-vs-new from `profileId` + the manifest id, so\n * a bundle whose id does not match this listing creates a SECOND listing\n * while the page says \"new version\". Cheap to notice here; impossible to\n * undo afterwards, because a published version is immutable.\n */\n const typedManifestId = (() => {\n const raw = draft.manifestText.trim()\n if (!raw) return ''\n try {\n const parsed = JSON.parse(raw) as { id?: unknown }\n return typeof parsed?.id === 'string' ? parsed.id : ''\n } catch {\n return ''\n }\n })()\n const manifestIdMismatch = Boolean(\n isUpdate && typedManifestId && listing?.pluginId &&\n typedManifestId !== listing.pluginId,\n )\n\n /**\n * What is serving customers right now (AGL-2368).\n *\n * This prints as \"v{X} is what installs today\", which is an INSTALL claim,\n * and it was reading a REVIEW verdict — the kill switch does not clear\n * `latestApprovedVersion`, so a publisher whose live version had been\n * stopped was told it was still installing, on the page they had come to\n * to ship its replacement.\n *\n * Falls through to nothing rather than to `latestVersion` when the offer is\n * revoked: the alert's other branch already says \"nothing installs until a\n * reviewer approves it\", which is the truth in that state.\n */\n const liveVersion = String(\n offeredPluginVersion(listing, revocation) ?? listing?.latestVersion ?? '',\n )\n\n const readManifest = async (): Promise<Record<string, unknown> | null> => {\n // A pasted manifest wins; otherwise read the chosen file.\n const raw = draft.manifestText.trim()\n ? draft.manifestText\n : manifestFile\n ? await manifestFile.text()\n : ''\n if (!raw) return null\n try {\n const parsed = JSON.parse(raw)\n return parsed && typeof parsed === 'object' ? parsed : null\n } catch {\n return null\n }\n }\n\n const submit = async () => {\n setProblems([])\n setMissingAttestations([])\n setAgreementProblem('')\n setFieldErrors({})\n if (!agreement.consent) return\n if (!bundleFile) {\n setFieldErrors({ bundle: 'Choose a plugin bundle (.js) to upload.' })\n return\n }\n const manifest = await readManifest()\n if (!manifest) {\n setFieldErrors({\n manifest: 'Add a valid manifest (JSON) — id, name, version and entry.',\n })\n return\n }\n setBusy(true)\n try {\n const bundle = await fileToBase64(bundleFile)\n const body = JSON.stringify({\n orgId,\n bundle,\n manifest,\n displayName:\n draft.displayName.trim() ||\n String((manifest as { name?: unknown }).name ?? '').trim(),\n description: draft.description.trim(),\n category: draft.category || undefined,\n changelog: draft.changelog.trim(),\n // A private plugin has no buyers — its only audience already owns\n // it — so it publishes free regardless of what the field held\n // before the publisher switched visibility.\n priceUsd:\n draft.visibility === 'private'\n ? 0\n : Math.max(0, Math.round(Number(draft.priceUsd) || 0)),\n visibility: draft.visibility,\n attestation: draft.attested,\n ...(draft.readme.trim() ? { readme: draft.readme.trim() } : {}),\n ...(draft.license.trim() ? { license: draft.license.trim() } : {}),\n ...(draft.repositoryUrl.trim()\n ? { repositoryUrl: draft.repositoryUrl.trim() }\n : {}),\n agreement: agreement.consent,\n })\n const response = await authorizedFetch(user, '/api/marketplace/publish-plugin', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body,\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n if (Array.isArray(payload?.problems)) {\n setProblems(\n payload.problems.map((problem: unknown) =>\n typeof problem === 'string'\n ? { message: problem }\n : {\n level: String(\n (problem as PublishProblem)?.level ?? 'error',\n ),\n message: String((problem as PublishProblem)?.message ?? ''),\n check: (problem as PublishProblem)?.check\n ? String((problem as PublishProblem).check)\n : undefined,\n },\n ),\n )\n }\n if (Array.isArray(payload?.missingAttestations)) {\n setMissingAttestations(payload.missingAttestations)\n }\n // Refused for the agreement (AGL-4105): said under the box it is\n // about, not in a toast, and the form keeps everything.\n if (payload?.agreement) {\n return void setAgreementProblem(String(payload.error ?? ''))\n }\n // A rejected subject names its field (AGL-1076), so put the message\n // where the value is rather than in a banner about a form.\n if (Array.isArray(payload?.missingAttestationSubjects)) {\n setFieldErrors(\n Object.fromEntries(\n payload.missingAttestationSubjects.map((field: string) => [\n field,\n String(payload.error ?? 'Required'),\n ]),\n ),\n )\n }\n return void enqueueSnackbar(payload?.error ?? 'Publish failed', {\n variant: response.status === 501 ? 'info' : 'error',\n allowDuplicate: true,\n })\n }\n // Somewhere to go (AGL-1078). The dialog closed onto the panel it\n // opened from, which said nothing about what had just happened; the\n // listing shows the version now queued for review.\n clearDraft()\n agreement.reset()\n enqueueSnackbar(\n `Published v${payload?.version ?? '1'} — it is queued for review`,\n { variant: 'success' },\n )\n router.push(listingPath(basePath, String(payload?.listingId ?? '')))\n } catch (error) {\n console.error(error)\n enqueueSnackbar('An error has occurred', {\n variant: 'error',\n allowDuplicate: true,\n })\n } finally {\n setBusy(false)\n }\n }\n\n // A price under the floor is refused by the publish route (AGL-2343), so the\n // button holds rather than letting a publisher upload a bundle and read the\n // minimum off a 400. A private plugin has no price at all — its field is\n // disabled and sends 0 — so it can never be blocked by this.\n const priceBelowFloor =\n draft.visibility !== 'private' &&\n isBelowMarketplacePriceFloor(draft.priceUsd)\n\n const blocked =\n busy ||\n !bundleFile ||\n unattested.length > 0 ||\n unfilledSubjects.length > 0 ||\n repositoryInvalid ||\n manifestIdMismatch ||\n priceBelowFloor ||\n !agreement.agreed\n\n return (\n <Stack spacing={2}>\n {isUpdate ? (\n /* AGL-1008. The mechanism was always right — same profileId plus\n manifest id bumps the listing, the new version enters review as\n pending, and the approved one keeps installing (AGL-966). The UI\n never told that story, so updating read like creating a second\n listing. */\n <Alert severity=\"info\">\n <Typography variant=\"subtitle2\">\n {`New version of ${listing?.displayName ?? 'your plugin'}`}\n </Typography>\n <Typography variant=\"caption\" component=\"div\">\n {liveVersion\n ? `v${liveVersion} is what installs today. It keeps installing ` +\n 'until a reviewer approves this one — nobody is upgraded ' +\n 'onto unreviewed code, and nothing you publish here can ' +\n 'change a version already installed.'\n : 'This version enters review. Nothing installs until a ' +\n 'reviewer approves it.'}\n </Typography>\n </Alert>\n ) : (\n <Alert severity=\"info\">\n {'Plugins publish sandboxed — they run isolated and can’t touch ' +\n 'site data directly. A reviewer verifies and signs yours before ' +\n 'it can run trusted.'}\n </Alert>\n )}\n\n {manifestIdMismatch ? (\n <Alert severity=\"warning\">\n {`This manifest says \"${typedManifestId}\", but ${\n listing?.displayName ?? 'this listing'\n } publishes \"${listing?.pluginId}\". Publishing it would create a ` +\n 'separate new listing rather than a new version of this one.'}\n </Alert>\n ) : null}\n\n {draftRestored ? (\n <Alert severity=\"info\" onClose={() => setDraftRestored(false)}>\n {'Picked up where you left off. Your bundle and manifest file are ' +\n 'not saved — choose them again before publishing.'}\n </Alert>\n ) : null}\n\n\n <CardDisplay\n header={isUpdate ? 'The new bundle and manifest' : 'Bundle and manifest'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#bundle-and-manifest',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <Stack spacing={0.5}>\n <Typography variant=\"subtitle2\">{'Bundle (.js)'}</Typography>\n <input\n ref={bundleRef}\n type=\"file\"\n accept=\".js,text/javascript,application/javascript\"\n hidden\n onChange={(event) =>\n setBundleFile(event.target.files?.[0] ?? null)\n }\n />\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button size=\"small\" onClick={() => bundleRef.current?.click()}>\n {'Choose bundle'}\n </Button>\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>\n {bundleFile?.name ?? 'No file chosen'}\n </Typography>\n </Stack>\n <Typography\n variant=\"caption\"\n color={fieldErrors['bundle'] ? 'error.main' : 'text.secondary'}\n >\n {fieldErrors['bundle'] ??\n 'One self-contained bundle. It’s parsed and checked before ' +\n 'publishing — forbidden APIs, size, and every network ' +\n 'call against the origins your manifest declares.'}\n </Typography>\n </Stack>\n\n <Stack spacing={0.5}>\n <Typography variant=\"subtitle2\">\n {'Manifest (JSON: id, name, version, entry)'}\n </Typography>\n <input\n ref={manifestRef}\n type=\"file\"\n accept=\".json,application/json\"\n hidden\n onChange={(event) =>\n setManifestFile(event.target.files?.[0] ?? null)\n }\n />\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button size=\"small\" onClick={() => manifestRef.current?.click()}>\n {'Choose manifest.json'}\n </Button>\n <Typography variant=\"body2\" color=\"text.secondary\" noWrap>\n {manifestFile?.name ?? 'or paste below'}\n </Typography>\n </Stack>\n <TextField\n placeholder='{ \"id\": \"acme-widget\", \"name\": \"Widget\", \"version\": \"1.0.0\", \"entry\": \"index.js\" }'\n value={draft.manifestText}\n onChange={(event) => set('manifestText')(event.target.value)}\n size=\"small\"\n multiline\n minRows={4}\n fullWidth\n error={Boolean(fieldErrors['manifest'])}\n helperText={fieldErrors['manifest'] ?? ' '}\n />\n </Stack>\n\n {problems.length ? (\n <Alert\n severity={\n problems.some((problem) => problem.level !== 'warning')\n ? 'error'\n : 'warning'\n }\n >\n <Typography variant=\"subtitle2\">\n {problems.some((problem) => problem.level !== 'warning')\n ? 'Bundle failed verification'\n : 'Bundle verified, with things to check'}\n </Typography>\n <ul style={{ margin: '4px 0 0', paddingLeft: 18 }}>\n {problems.map((problem, index) => (\n <li key={`${problem.check ?? 'problem'}-${index}`}>\n <Typography variant=\"caption\">\n {problem.check ? `${problem.check}: ` : ''}\n {problem.message}\n </Typography>\n </li>\n ))}\n </ul>\n </Alert>\n ) : null}\n </Stack>\n </CardDisplay>\n\n <CardDisplay\n header={'Listing'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#authoring-your-listing',\n excerpt:\n 'What a reviewer reads first and a buyer reads before running ' +\n 'third-party code.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <TextField\n label=\"Listing name\"\n helperText=\"Defaults to the manifest name\"\n value={draft.displayName}\n onChange={(event) => set('displayName')(event.target.value)}\n size=\"small\"\n />\n <TextField\n label=\"Description\"\n helperText=\"The one-line summary on browse cards\"\n value={draft.description}\n onChange={(event) => set('description')(event.target.value)}\n size=\"small\"\n multiline\n minRows={2}\n />\n <TextField\n select\n label=\"Category\"\n value={draft.category}\n onChange={(event) => set('category')(event.target.value)}\n size=\"small\"\n >\n <MenuItem value=\"\">{'None'}</MenuItem>\n {LISTING_CATEGORIES.map((entry) => (\n <MenuItem key={entry} value={entry}>\n {entry}\n </MenuItem>\n ))}\n </TextField>\n {/* The same editor the listing detail page uses (AGL-1080). The\n first time a publisher writes the document reviewers read\n first used to get the worst tool we have, and the second time\n the good one — for the same field. The AGL-969 attestation\n made that worse by asking them to confirm the README\n documents what data the plugin handles, in a box too small to\n see whether it does. */}\n <MarkdownField\n label=\"README\"\n value={draft.readme}\n onChange={set('readme')}\n onPickImageFromMedia={insertReadmeImage}\n editorRef={(handle) => {\n readmeEditorRef.current = handle\n }}\n helperText={\n 'Shown on your listing page — what it does, how to configure ' +\n 'it, and what it reads, stores or sends. Reviewers and ' +\n 'cautious buyers read this first.'\n }\n />\n {/* The only field that exclusively concerns updates (AGL-1080).\n It was a single line labelled `Changelog` and nothing else,\n presented as an equal peer of Category — while AGL-969 attests\n to it and AGL-976 builds the listing's changelog tab out of\n it. The helper names both audiences, because \"what changed\"\n means something different to each. */}\n <TextField\n label=\"Changelog\"\n placeholder=\"Fixed the timer drift on Safari; added a compact layout\"\n helperText={\n isUpdate\n ? 'The field that matters most on an update. Two audiences: ' +\n 'the reviewer, comparing these bytes against ' +\n (liveVersion ? `v${liveVersion}` : 'the last approved ' +\n 'version') +\n ', and every installer deciding whether to move off the ' +\n 'version they are running.'\n : 'Two audiences: the reviewer, comparing this version ' +\n 'against the last approved one, and every installer who ' +\n 'reads it on your listing’s changelog tab before ' +\n 'updating. On a first version there is nothing to compare ' +\n 'against — say what the plugin does instead, or leave it.'\n }\n value={draft.changelog}\n onChange={(event) => set('changelog')(event.target.value)}\n size=\"small\"\n multiline\n minRows={3}\n />\n {/* AGL-1076: the subject of the repository attestation below. */}\n <TextField\n label=\"Repository URL\"\n placeholder=\"https://github.com/acme/widget\"\n required\n error={repositoryInvalid || Boolean(fieldErrors['repositoryUrl'])}\n helperText={\n repositoryInvalid\n ? 'Must be an https URL.'\n : (fieldErrors['repositoryUrl'] ??\n 'The source for this bundle. A reviewer opens it first — ' +\n 'it is what the repository confirmation below is about.')\n }\n value={draft.repositoryUrl}\n onChange={(event) => set('repositoryUrl')(event.target.value)}\n size=\"small\"\n />\n <TextField\n label=\"License\"\n placeholder=\"MIT\"\n helperText=\"Short label, e.g. MIT or Apache-2.0\"\n value={draft.license}\n onChange={(event) => set('license')(event.target.value)}\n size=\"small\"\n />\n </Stack>\n </CardDisplay>\n\n <CardDisplay\n header={'Who can install it, and for how much'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#private-plugins',\n excerpt:\n 'Private is a choice about audience, not about trust — it takes ' +\n 'the identical review path.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n {/* Private plugins (AGL-968/992): deliberately worded as an\n AUDIENCE choice — private is not a faster lane, and the caption\n says so, because \"skip the queue\" is the reading it would\n otherwise invite. */}\n <TextField\n select\n label=\"Who can install this\"\n value={draft.visibility}\n // Set on FIRST publish only — the server ignores it on a version\n // bump (AGL-968), so offering the choice here would be a control\n // that silently does nothing. Change it from the listing.\n disabled={isUpdate}\n onChange={(event) =>\n set('visibility')(event.target.value as 'public' | 'private')\n }\n size=\"small\"\n helperText={\n isUpdate\n ? 'Set when the listing was created. Change it from the ' +\n 'listing — a new version never changes who can install it.'\n :\n draft.visibility === 'private'\n ? 'Private plugins take the same review path — same ' +\n 'queue, same checklist, same verifier, same signature ' +\n 'for realm trust. They are never listed in the ' +\n 'marketplace, and only your sites can install them.'\n : 'Listed in the marketplace for every workspace once a ' +\n 'reviewer approves it.'\n }\n >\n <MenuItem value=\"public\">\n {'Anyone — publish to the marketplace'}\n </MenuItem>\n <MenuItem value=\"private\">\n {'Only this organization — private plugin'}\n </MenuItem>\n </TextField>\n <TextField\n label=\"Price (USD)\"\n // A private plugin has no buyers, and a price on one would only\n // send the publisher through Stripe onboarding to sell to\n // themselves.\n disabled={draft.visibility === 'private'}\n // The minimum price (AGL-2343), from the same functions every other\n // publish form reads, so no two forms can quote different figures\n // at a publisher — and stated up front rather than only on refusal.\n error={priceBelowFloor}\n helperText={\n draft.visibility === 'private'\n ? 'Private plugins are free — nobody else can install them.'\n : (marketplacePriceCostNote(draft.priceUsd) ??\n marketplacePriceFloorHint(\n 'Paid listings need payouts set up.',\n ))\n }\n type=\"number\"\n value={draft.visibility === 'private' ? '0' : draft.priceUsd}\n onChange={(event) => set('priceUsd')(event.target.value)}\n size=\"small\"\n />\n </Stack>\n </CardDisplay>\n\n {/* The checklist last, in full view of the publish button (AGL-969 /\n AGL-1078). In the dialog it sat below the button and had to be\n scrolled past to be seen at all. Every item is a statement only the\n publisher can make. */}\n <CardDisplay\n header={'Before you publish'}\n help={pluginDocsHelp('publisherHandbook', {\n anchor: '#before-you-publish',\n excerpt:\n 'Recorded against this exact bundle, with your name and the ' +\n 'date, and shown to the reviewer.',\n })}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Recorded against this exact bundle, with your name and the ' +\n 'date, and shown to the reviewer. Republishing the same ' +\n 'version number asks again — the bytes changed.'}\n </Typography>\n {missingAttestations.length ? (\n <Alert severity=\"warning\">\n {'This plugin already has a published version, so the ' +\n 'highlighted item applies too.'}\n </Alert>\n ) : null}\n {PUBLISHER_ATTESTATION.map((item) => {\n const flagged = missingAttestations.includes(item.id)\n return (\n <Stack key={item.id} spacing={0.25}>\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={draft.attested.includes(item.id)}\n disabled={busy}\n onChange={() => toggleAttestation(item.id)}\n />\n }\n label={\n <Stack\n useFlexGap\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flexWrap: 'wrap' }}\n >\n <Typography\n variant=\"body2\"\n color={flagged ? 'warning.main' : undefined}\n >\n {item.label}\n </Typography>\n {item.updateOnly ? (\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label=\"Updates only\"\n />\n ) : null}\n </Stack>\n }\n />\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ pl: 4 }}\n >\n {item.detail}\n </Typography>\n </Stack>\n )\n })}\n </Stack>\n </CardDisplay>\n\n {/* Directly above the button (AGL-4105), which waits for it. */}\n <PublisherAgreementCheckbox\n checked={agreement.agreed}\n onChange={(checked) => {\n agreement.setAgreed(checked)\n setAgreementProblem('')\n }}\n disabled={busy}\n error={agreementProblem || null}\n />\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => void submit()}\n disabled={blocked}\n >\n {busy\n ? 'Publishing…'\n : !bundleFile\n ? 'Choose a bundle'\n : unattested.length\n ? `Confirm ${unattested.length} more`\n : unfilledSubjects.length || repositoryInvalid\n ? 'Add a repository URL'\n : !agreement.agreed\n ? 'Agree to publish'\n : isUpdate\n ? 'Publish new version'\n : draft.visibility === 'private'\n ? 'Publish privately'\n : 'Publish plugin'}\n </Button>\n <Button\n disabled={busy}\n onClick={() => {\n clearDraft()\n setDraft(baseline)\n setBundleFile(null)\n setManifestFile(null)\n setDraftRestored(false)\n }}\n >\n {'Discard draft'}\n </Button>\n </Stack>\n\n </Stack>\n )\n}\n\nPublishPluginForm.displayName = 'PublishPluginForm'\n\nexport default PublishPluginForm\n"],"names":["formatMediaRef","offeredPluginVersion","useMediaPicker","isBelowMarketplacePriceFloor","marketplacePriceCostNote","marketplacePriceFloorHint","CardDisplay","useSnackbar","Alert","Button","Checkbox","Chip","FormControlLabel","MenuItem","Stack","TextField","Typography","useRouter","useCallback","useEffect","useRef","useState","useUser","missingAttestationSubjects","PUBLISHER_ATTESTATION","requiredAttestationIds","MarkdownField","pluginDocsHelp","inheritedMediaAlt","authorizedFetch","listingPath","PublisherAgreementCheckbox","usePublisherAgreementConsent","LISTING_CATEGORIES","isHttpsUrl","value","test","trim","length","fileToBase64","file","buffer","arrayBuffer","binary","bytes","Uint8Array","i","String","fromCharCode","btoa","EMPTY_DRAFT","manifestText","displayName","description","category","changelog","priceUsd","readme","license","repositoryUrl","visibility","attested","draftKey","orgId","listingId","readDraft","window","stored","localStorage","getItem","JSON","parse","seedDraft","draft","listing","$id","seeded","carry","key","categories","draftDiffersFrom","baseline","Object","keys","some","undefined","Array","isArray","other","entry","index","PublishPluginForm","props","fieldErrors","basePath","revocation","isUpdate","Boolean","data","user","router","enqueueSnackbar","busy","setBusy","bundleRef","manifestRef","bundleFile","setBundleFile","manifestFile","setManifestFile","readmeEditorRef","pickMedia","insertReadmeImage","media","kind","src","mediaScope","mediaId","url","current","insertImage","assetAlt","alt","setDraft","draftRestored","setDraftRestored","problems","setProblems","missingAttestations","setMissingAttestations","agreement","agreementProblem","setAgreementProblem","setFieldErrors","set","setItem","stringify","clearDraft","removeItem","toggleAttestation","id","includes","filter","unattested","unfilledSubjects","repositoryInvalid","typedManifestId","raw","parsed","manifestIdMismatch","pluginId","liveVersion","latestVersion","readManifest","text","submit","consent","bundle","manifest","body","name","Math","max","round","Number","attestation","response","method","headers","payload","json","catch","ok","map","problem","message","level","check","error","fromEntries","field","variant","status","allowDuplicate","reset","version","push","console","priceBelowFloor","blocked","agreed","spacing","severity","component","onClose","header","help","anchor","contentGutterX","contentGutterY","input","ref","type","accept","hidden","onChange","event","target","files","direction","sx","alignItems","size","onClick","click","color","noWrap","placeholder","multiline","minRows","fullWidth","helperText","ul","style","margin","paddingLeft","li","excerpt","label","select","onPickImageFromMedia","editorRef","handle","required","disabled","item","flagged","control","checked","useFlexGap","flexWrap","updateOnly","pl","detail","setAgreed"],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type PublisherAgreementConsent } from '../model/publisher-agreement';
|
|
18
|
+
export interface PublisherAgreementCheckboxProps {
|
|
19
|
+
checked: boolean;
|
|
20
|
+
onChange: (checked: boolean) => void;
|
|
21
|
+
/** Held still while the save it belongs to is running. */
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
/** Why the last save was refused for the box, when it was. */
|
|
24
|
+
error?: string | null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* "I agree to the Marketplace Publisher Agreement" (AGL-4105): the box every
|
|
28
|
+
* publisher save carries, directly above its button.
|
|
29
|
+
*
|
|
30
|
+
* Unticked until the person ticks it, and unticked again after each save, so
|
|
31
|
+
* each save is its own agreement; the button it sits above stays disabled
|
|
32
|
+
* until it is ticked. The agreement's title is the link to the document, read
|
|
33
|
+
* from `publisherAgreementConsentPresentation` and never from the URL
|
|
34
|
+
* constant: while the document has no published page there is no link, the
|
|
35
|
+
* box cannot be ticked, and the reason is said in its place (AGL-1660).
|
|
36
|
+
*
|
|
37
|
+
* One component for every publisher form and dialog in the console, the
|
|
38
|
+
* publish dialog drawn through the `hostArtifactPublish` zone included, so
|
|
39
|
+
* the sentence and the link never differ between them.
|
|
40
|
+
*/
|
|
41
|
+
export declare function PublisherAgreementCheckbox(props: PublisherAgreementCheckboxProps): import("react").JSX.Element;
|
|
42
|
+
export declare namespace PublisherAgreementCheckbox {
|
|
43
|
+
var displayName: string;
|
|
44
|
+
}
|
|
45
|
+
/** One save form's box: its state, what the save sends, and the reset after it. */
|
|
46
|
+
export interface PublisherAgreementConsentState {
|
|
47
|
+
agreed: boolean;
|
|
48
|
+
setAgreed: (agreed: boolean) => void;
|
|
49
|
+
/** The `agreement` the save sends: present only while the box is ticked. */
|
|
50
|
+
consent: PublisherAgreementConsent | undefined;
|
|
51
|
+
/** Unticks the box. Called after every save, so the next save asks again. */
|
|
52
|
+
reset: () => void;
|
|
53
|
+
}
|
|
54
|
+
/** The state behind one {@link PublisherAgreementCheckbox}, unticked to start. */
|
|
55
|
+
export declare function usePublisherAgreementConsent(): PublisherAgreementConsentState;
|
|
56
|
+
export default PublisherAgreementCheckbox;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
import { Alert, Checkbox, FormControlLabel, FormHelperText, Link, Stack, Typography } from "@mui/material";
|
|
20
|
+
import { useCallback, useId, useMemo, useState } from "react";
|
|
21
|
+
import { PUBLISHER_AGREEMENT_TITLE, publisherAgreementConsent, publisherAgreementConsentPresentation } from "../model/publisher-agreement.js";
|
|
22
|
+
/**
|
|
23
|
+
* "I agree to the Marketplace Publisher Agreement" (AGL-4105): the box every
|
|
24
|
+
* publisher save carries, directly above its button.
|
|
25
|
+
*
|
|
26
|
+
* Unticked until the person ticks it, and unticked again after each save, so
|
|
27
|
+
* each save is its own agreement; the button it sits above stays disabled
|
|
28
|
+
* until it is ticked. The agreement's title is the link to the document, read
|
|
29
|
+
* from `publisherAgreementConsentPresentation` and never from the URL
|
|
30
|
+
* constant: while the document has no published page there is no link, the
|
|
31
|
+
* box cannot be ticked, and the reason is said in its place (AGL-1660).
|
|
32
|
+
*
|
|
33
|
+
* One component for every publisher form and dialog in the console, the
|
|
34
|
+
* publish dialog drawn through the `hostArtifactPublish` zone included, so
|
|
35
|
+
* the sentence and the link never differ between them.
|
|
36
|
+
*/ export function PublisherAgreementCheckbox(props) {
|
|
37
|
+
var _presentation_documentUrl;
|
|
38
|
+
const { checked, onChange, disabled = false, error } = props;
|
|
39
|
+
const errorId = useId();
|
|
40
|
+
const presentation = publisherAgreementConsentPresentation();
|
|
41
|
+
if (!presentation.canAgree) {
|
|
42
|
+
return /*#__PURE__*/ _jsx(Alert, {
|
|
43
|
+
severity: "warning",
|
|
44
|
+
children: presentation.unavailableNotice
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
48
|
+
spacing: 0.5,
|
|
49
|
+
children: [
|
|
50
|
+
/*#__PURE__*/ _jsx(FormControlLabel, {
|
|
51
|
+
disableTypography: true,
|
|
52
|
+
disabled: disabled,
|
|
53
|
+
sx: {
|
|
54
|
+
alignItems: 'flex-start',
|
|
55
|
+
mr: 0
|
|
56
|
+
},
|
|
57
|
+
control: /*#__PURE__*/ _jsx(Checkbox, {
|
|
58
|
+
checked: checked,
|
|
59
|
+
onChange: (event)=>onChange(event.target.checked),
|
|
60
|
+
size: "small",
|
|
61
|
+
color: "primary",
|
|
62
|
+
sx: [
|
|
63
|
+
{
|
|
64
|
+
mt: -0.75
|
|
65
|
+
},
|
|
66
|
+
Boolean(error) && !checked && {
|
|
67
|
+
color: 'error.main'
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
slotProps: {
|
|
71
|
+
input: _extends({
|
|
72
|
+
'aria-label': `Agree to the ${PUBLISHER_AGREEMENT_TITLE}`
|
|
73
|
+
}, error ? {
|
|
74
|
+
'aria-invalid': true,
|
|
75
|
+
'aria-describedby': errorId
|
|
76
|
+
} : {})
|
|
77
|
+
}
|
|
78
|
+
}),
|
|
79
|
+
label: /*#__PURE__*/ _jsxs(Typography, {
|
|
80
|
+
component: "span",
|
|
81
|
+
variant: "body2",
|
|
82
|
+
children: [
|
|
83
|
+
'I agree to the ',
|
|
84
|
+
/*#__PURE__*/ _jsx(Link, {
|
|
85
|
+
href: (_presentation_documentUrl = presentation.documentUrl) != null ? _presentation_documentUrl : undefined,
|
|
86
|
+
target: "_blank",
|
|
87
|
+
rel: "noopener noreferrer",
|
|
88
|
+
underline: "always",
|
|
89
|
+
children: PUBLISHER_AGREEMENT_TITLE
|
|
90
|
+
})
|
|
91
|
+
]
|
|
92
|
+
})
|
|
93
|
+
}),
|
|
94
|
+
error ? /*#__PURE__*/ _jsx(FormHelperText, {
|
|
95
|
+
id: errorId,
|
|
96
|
+
error: true,
|
|
97
|
+
sx: {
|
|
98
|
+
m: 0
|
|
99
|
+
},
|
|
100
|
+
children: error
|
|
101
|
+
}) : null
|
|
102
|
+
]
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
PublisherAgreementCheckbox.displayName = 'PublisherAgreementCheckbox';
|
|
106
|
+
/** The state behind one {@link PublisherAgreementCheckbox}, unticked to start. */ export function usePublisherAgreementConsent() {
|
|
107
|
+
const [agreed, setAgreed] = useState(false);
|
|
108
|
+
const reset = useCallback(()=>setAgreed(false), []);
|
|
109
|
+
return useMemo(()=>({
|
|
110
|
+
agreed,
|
|
111
|
+
setAgreed,
|
|
112
|
+
consent: agreed ? publisherAgreementConsent() : undefined,
|
|
113
|
+
reset
|
|
114
|
+
}), [
|
|
115
|
+
agreed,
|
|
116
|
+
reset
|
|
117
|
+
]);
|
|
118
|
+
}
|
|
119
|
+
export default PublisherAgreementCheckbox;
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=publisher-agreement-checkbox.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/marketplace/src/lib/components/publisher-agreement-checkbox.component.tsx"],"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\n'use client'\n\nimport {\n Alert,\n Checkbox,\n FormControlLabel,\n FormHelperText,\n Link,\n Stack,\n Typography,\n} from '@mui/material'\nimport { useCallback, useId, useMemo, useState } from 'react'\nimport {\n PUBLISHER_AGREEMENT_TITLE,\n publisherAgreementConsent,\n publisherAgreementConsentPresentation,\n type PublisherAgreementConsent,\n} from '../model/publisher-agreement'\n\nexport interface PublisherAgreementCheckboxProps {\n checked: boolean\n onChange: (checked: boolean) => void\n /** Held still while the save it belongs to is running. */\n disabled?: boolean\n /** Why the last save was refused for the box, when it was. */\n error?: string | null\n}\n\n/**\n * \"I agree to the Marketplace Publisher Agreement\" (AGL-4105): the box every\n * publisher save carries, directly above its button.\n *\n * Unticked until the person ticks it, and unticked again after each save, so\n * each save is its own agreement; the button it sits above stays disabled\n * until it is ticked. The agreement's title is the link to the document, read\n * from `publisherAgreementConsentPresentation` and never from the URL\n * constant: while the document has no published page there is no link, the\n * box cannot be ticked, and the reason is said in its place (AGL-1660).\n *\n * One component for every publisher form and dialog in the console, the\n * publish dialog drawn through the `hostArtifactPublish` zone included, so\n * the sentence and the link never differ between them.\n */\nexport function PublisherAgreementCheckbox(props: PublisherAgreementCheckboxProps) {\n const { checked, onChange, disabled = false, error } = props\n const errorId = useId()\n const presentation = publisherAgreementConsentPresentation()\n if (!presentation.canAgree) {\n return <Alert severity=\"warning\">{presentation.unavailableNotice}</Alert>\n }\n return (\n <Stack spacing={0.5}>\n <FormControlLabel\n disableTypography\n disabled={disabled}\n sx={{ alignItems: 'flex-start', mr: 0 }}\n control={\n <Checkbox\n checked={checked}\n onChange={(event) => onChange(event.target.checked)}\n size=\"small\"\n color=\"primary\"\n sx={[\n { mt: -0.75 },\n Boolean(error) && !checked && { color: 'error.main' },\n ]}\n slotProps={{\n input: {\n 'aria-label': `Agree to the ${PUBLISHER_AGREEMENT_TITLE}`,\n ...(error ? { 'aria-invalid': true, 'aria-describedby': errorId } : {}),\n },\n }}\n />\n }\n label={\n <Typography component=\"span\" variant=\"body2\">\n {'I agree to the '}\n <Link\n href={presentation.documentUrl ?? undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n underline=\"always\"\n >\n {PUBLISHER_AGREEMENT_TITLE}\n </Link>\n </Typography>\n }\n />\n {error ? (\n <FormHelperText id={errorId} error sx={{ m: 0 }}>\n {error}\n </FormHelperText>\n ) : null}\n </Stack>\n )\n}\n\nPublisherAgreementCheckbox.displayName = 'PublisherAgreementCheckbox'\n\n/** One save form's box: its state, what the save sends, and the reset after it. */\nexport interface PublisherAgreementConsentState {\n agreed: boolean\n setAgreed: (agreed: boolean) => void\n /** The `agreement` the save sends: present only while the box is ticked. */\n consent: PublisherAgreementConsent | undefined\n /** Unticks the box. Called after every save, so the next save asks again. */\n reset: () => void\n}\n\n/** The state behind one {@link PublisherAgreementCheckbox}, unticked to start. */\nexport function usePublisherAgreementConsent(): PublisherAgreementConsentState {\n const [agreed, setAgreed] = useState(false)\n const reset = useCallback(() => setAgreed(false), [])\n return useMemo(\n () => ({\n agreed,\n setAgreed,\n consent: agreed ? publisherAgreementConsent() : undefined,\n reset,\n }),\n [agreed, reset],\n )\n}\n\nexport default PublisherAgreementCheckbox\n"],"names":["Alert","Checkbox","FormControlLabel","FormHelperText","Link","Stack","Typography","useCallback","useId","useMemo","useState","PUBLISHER_AGREEMENT_TITLE","publisherAgreementConsent","publisherAgreementConsentPresentation","PublisherAgreementCheckbox","props","presentation","checked","onChange","disabled","error","errorId","canAgree","severity","unavailableNotice","spacing","disableTypography","sx","alignItems","mr","control","event","target","size","color","mt","Boolean","slotProps","input","label","component","variant","href","documentUrl","undefined","rel","underline","id","m","displayName","usePublisherAgreementConsent","agreed","setAgreed","reset","consent"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;AAEA,SACEA,KAAK,EACLC,QAAQ,EACRC,gBAAgB,EAChBC,cAAc,EACdC,IAAI,EACJC,KAAK,EACLC,UAAU,QACL,gBAAe;AACtB,SAASC,WAAW,EAAEC,KAAK,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AAC7D,SACEC,yBAAyB,EACzBC,yBAAyB,EACzBC,qCAAqC,QAEhC,kCAA8B;AAWrC;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,2BAA2BC,KAAsC;QAmC7DC;IAlClB,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,WAAW,KAAK,EAAEC,KAAK,EAAE,GAAGL;IACvD,MAAMM,UAAUb;IAChB,MAAMQ,eAAeH;IACrB,IAAI,CAACG,aAAaM,QAAQ,EAAE;QAC1B,qBAAO,KAACtB;YAAMuB,UAAS;sBAAWP,aAAaQ,iBAAiB;;IAClE;IACA,qBACE,MAACnB;QAAMoB,SAAS;;0BACd,KAACvB;gBACCwB,iBAAiB;gBACjBP,UAAUA;gBACVQ,IAAI;oBAAEC,YAAY;oBAAcC,IAAI;gBAAE;gBACtCC,uBACE,KAAC7B;oBACCgB,SAASA;oBACTC,UAAU,CAACa,QAAUb,SAASa,MAAMC,MAAM,CAACf,OAAO;oBAClDgB,MAAK;oBACLC,OAAM;oBACNP,IAAI;wBACF;4BAAEQ,IAAI,CAAC;wBAAK;wBACZC,QAAQhB,UAAU,CAACH,WAAW;4BAAEiB,OAAO;wBAAa;qBACrD;oBACDG,WAAW;wBACTC,OAAO;4BACL,cAAc,CAAC,aAAa,EAAE3B,2BAA2B;2BACrDS,QAAQ;4BAAE,gBAAgB;4BAAM,oBAAoBC;wBAAQ,IAAI,CAAC;oBAEzE;;gBAGJkB,qBACE,MAACjC;oBAAWkC,WAAU;oBAAOC,SAAQ;;wBAClC;sCACD,KAACrC;4BACCsC,IAAI,GAAE1B,4BAAAA,aAAa2B,WAAW,YAAxB3B,4BAA4B4B;4BAClCZ,QAAO;4BACPa,KAAI;4BACJC,WAAU;sCAETnC;;;;;YAKRS,sBACC,KAACjB;gBAAe4C,IAAI1B;gBAASD,KAAK;gBAACO,IAAI;oBAAEqB,GAAG;gBAAE;0BAC3C5B;iBAED;;;AAGV;AAEAN,2BAA2BmC,WAAW,GAAG;AAYzC,gFAAgF,GAChF,OAAO,SAASC;IACd,MAAM,CAACC,QAAQC,UAAU,GAAG1C,SAAS;IACrC,MAAM2C,QAAQ9C,YAAY,IAAM6C,UAAU,QAAQ,EAAE;IACpD,OAAO3C,QACL,IAAO,CAAA;YACL0C;YACAC;YACAE,SAASH,SAASvC,8BAA8BgC;YAChDS;QACF,CAAA,GACA;QAACF;QAAQE;KAAM;AAEnB;AAEA,eAAevC,2BAA0B"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { PublisherAgreementConsent } from '../model/publisher-agreement';
|
|
18
|
+
export interface PublisherAgreementConfirmDialogProps {
|
|
19
|
+
open: boolean;
|
|
20
|
+
title: string;
|
|
21
|
+
/** What the change does, in a sentence. */
|
|
22
|
+
body: string;
|
|
23
|
+
confirmLabel: string;
|
|
24
|
+
/** In the error color: it takes a listing out of the marketplace. */
|
|
25
|
+
destructive?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Makes the change with the agreement. Resolves to null when it went
|
|
28
|
+
* through, which closes the dialog, or to the message to show when it was
|
|
29
|
+
* refused, which keeps it open.
|
|
30
|
+
*/
|
|
31
|
+
onConfirm: (consent: PublisherAgreementConsent) => Promise<string | null>;
|
|
32
|
+
onClose: () => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A one-click publisher change asked first, with the agreement box above its
|
|
36
|
+
* button (AGL-4105): making a listing private or public, unpublishing or
|
|
37
|
+
* republishing it. Those were menu items that saved on the click; a save in
|
|
38
|
+
* the marketplace now agrees to the Publisher Agreement first, so the click
|
|
39
|
+
* opens this, and the change is made from here.
|
|
40
|
+
*/
|
|
41
|
+
export declare function PublisherAgreementConfirmDialog(props: PublisherAgreementConfirmDialogProps): import("react").JSX.Element;
|
|
42
|
+
export declare namespace PublisherAgreementConfirmDialog {
|
|
43
|
+
var displayName: string;
|
|
44
|
+
}
|
|
45
|
+
export default PublisherAgreementConfirmDialog;
|