@burdenoff/microfe-devportal 2026.1108.2 → 2026.1109.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeCampusAppletsPage.js","names":["EmptyState","_Fragment","EmptyState$1","REFRESH_QUERIES","primaryButton","outlineButton","editorKey","target","ManifestEditor","tr","useTr","client","useSafeGatewayClient","text","setText","useState","initialText","problems","setProblems","validated","setValidated","validate","validating","useDevportalValidateTimeCampusAppletManifestLazyQuery","createApplet","creating","useDevportalCreateTimeCampusAppletMutation","addVersion","adding","useDevportalAddTimeCampusAppletVersionMutation","updateVersion","updating","useDevportalUpdateTimeCampusAppletVersionMutation","saving","parsed","result","parseManifestText","handleValidate","manifest","data","err","errorText","handleSave","onSaved","title","GlassCard","TIMECAMPUS_MANIFEST_DOCS_URL","ExternalLink","event","problem","index","CheckCircle2","onClose","Upload","AppletCard","latest","applet","action","versionAction","offer","marketplaceOffer","listing","submission","StatusBadge","onNewVersion","busy","canAddVersion","FilePlus2","formatDate","canEditVersion","onEditVersion","Pencil","onSubmitVersion","Send","onWithdrawVersion","Undo2","Globe","canWithdrawFromMarketplace","onWithdrawOffer","onOffer","ResourceLinks","links","BookOpen","TIMECAMPUS_SAMPLE_WIDGET_URL","Puzzle","TIMECAMPUS_APPLETS_DOCS_URL","Icon","label","href","TimeCampusAppletsPage","useDevportal","workspaceClient","hasWorkspace","workspaceId","editorState","setEditorState","editor","openEditor","setFeedback","feedback","useDevportalTimeCampusAppletsQuery","workspacesData","useMyWorkspacesQuery","workspaceName","item","mutationOptions","submitVersion","submitState","useDevportalSubmitTimeCampusAppletVersionMutation","withdrawVersion","withdrawState","useDevportalWithdrawTimeCampusAppletVersionMutation","offerToMarketplace","offerState","useDevportalSubmitTimeCampusAppletToMarketplaceMutation","withdrawOffer","withdrawOfferState","useDevportalWithdrawTimeCampusAppletFromMarketplaceMutation","run","success","applets","PageLayout","starterManifest","PageSection","Fragment","message","loading","LoadingState","error","manifestForNextVersion","manifestText"],"sources":["../../../src/devportal/pages/TimeCampusAppletsPage.tsx"],"sourcesContent":["/**\n * TimeCampus applets (BOFF-11005)\n *\n * The developer portal's home for third-party TimeCampus applet developers.\n * It lists the applets the developer registered in their active workspace\n * with each one's workspace review state, public marketplace listing,\n * latest submission and review notes, and it covers the developer flow end\n * to end: register an applet from a JSON manifest, upload new manifest\n * versions, submit a version for workspace review, and offer the live\n * version to the public TimeCampus marketplace for platform certification.\n *\n * Every call goes to the TimeCampus subgraph through the workspace gateway\n * with the developer's own session and active workspace (the shell's context\n * switcher picks the workspace), so the gateway's @rbac checks on the\n * timecampus-applet-developer resource apply exactly as they do in the\n * TimeCampus app. Certification itself stays with the TimeCampus platform\n * team.\n */\nimport type { FC } from \"react\";\nimport { useState } from \"react\";\nimport {\n BookOpen,\n CheckCircle2,\n ExternalLink,\n FilePlus2,\n Globe,\n Pencil,\n Puzzle,\n Send,\n Undo2,\n Upload,\n} from \"lucide-react\";\nimport { useSafeGatewayClient } from \"@burdenoff/fe-libs/shared/graphql\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { LoadingState } from \"../components/LoadingState\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { useTr } from \"../utils/i18n\";\nimport {\n TIMECAMPUS_APPLETS_DOCS_URL,\n TIMECAMPUS_MANIFEST_DOCS_URL,\n TIMECAMPUS_SAMPLE_WIDGET_URL,\n canAddVersion,\n canEditVersion,\n canWithdrawFromMarketplace,\n errorText,\n formatDate,\n manifestForNextVersion,\n manifestText,\n marketplaceOffer,\n parseManifestText,\n starterManifest,\n versionAction,\n} from \"../utils/timecampusApplets\";\nimport {\n useDevportalAddTimeCampusAppletVersionMutation,\n useDevportalCreateTimeCampusAppletMutation,\n useDevportalSubmitTimeCampusAppletToMarketplaceMutation,\n useDevportalSubmitTimeCampusAppletVersionMutation,\n useDevportalTimeCampusAppletsQuery,\n useDevportalUpdateTimeCampusAppletVersionMutation,\n useDevportalValidateTimeCampusAppletManifestLazyQuery,\n useDevportalWithdrawTimeCampusAppletFromMarketplaceMutation,\n useDevportalWithdrawTimeCampusAppletVersionMutation,\n useMyWorkspacesQuery,\n type DevportalTimeCampusAppletFragment,\n type DevportalTimeCampusAppletsQuery,\n type DevportalValidateTimeCampusAppletManifestQuery,\n type MyWorkspacesQuery,\n} from \"../../generated/wspace-operations\";\n\nconst REFRESH_QUERIES = [\"DevportalTimeCampusApplets\"];\n\nconst primaryButton =\n \"inline-flex items-center justify-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\";\nconst outlineButton =\n \"inline-flex items-center justify-center gap-1.5 rounded-md border border-border-subtle bg-bg-surface px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-bg-surface-hover disabled:opacity-50\";\n\n/** What the manifest editor saves to. */\ntype EditorTarget =\n | { kind: \"new\" }\n | { kind: \"version\"; appletId: string; appletName: string }\n | { kind: \"edit\"; versionId: string; appletName: string; version: string };\n\n/**\n * An open manifest editor, tied to the workspace it was opened in. The page\n * only renders it while that workspace is still active, so switching\n * workspace can never save a manifest into a different workspace.\n */\ntype EditorState = { target: EditorTarget; text: string; workspaceId: string };\n\nfunction editorKey(target: EditorTarget): string {\n if (target.kind === \"new\") return \"new\";\n if (target.kind === \"version\") return `version-${target.appletId}`;\n return `edit-${target.versionId}`;\n}\n\ntype Feedback = { tone: \"success\" | \"error\"; text: string } | null;\n\n// =============================================================================\n// Manifest editor\n// =============================================================================\n\nconst ManifestEditor: FC<{\n target: EditorTarget;\n initialText: string;\n onClose: () => void;\n onSaved: (message: string) => void;\n}> = ({ target, initialText, onClose, onSaved }) => {\n const tr = useTr();\n const workspaceClient = useSafeGatewayClient(\"workspace\");\n const client = workspaceClient ?? undefined;\n const [text, setText] = useState(initialText);\n const [problems, setProblems] = useState<string[]>([]);\n const [validated, setValidated] = useState(false);\n const [validate, { loading: validating }] =\n useDevportalValidateTimeCampusAppletManifestLazyQuery({\n client,\n fetchPolicy: \"no-cache\",\n });\n const [createApplet, { loading: creating }] =\n useDevportalCreateTimeCampusAppletMutation({\n client,\n refetchQueries: REFRESH_QUERIES,\n awaitRefetchQueries: true,\n });\n const [addVersion, { loading: adding }] =\n useDevportalAddTimeCampusAppletVersionMutation({\n client,\n refetchQueries: REFRESH_QUERIES,\n awaitRefetchQueries: true,\n });\n const [updateVersion, { loading: updating }] =\n useDevportalUpdateTimeCampusAppletVersionMutation({\n client,\n refetchQueries: REFRESH_QUERIES,\n awaitRefetchQueries: true,\n });\n const saving = creating || adding || updating;\n\n const parsed = () => {\n const result = parseManifestText(text);\n if (!result.ok) {\n setProblems([result.error]);\n setValidated(false);\n return null;\n }\n return result.manifest;\n };\n\n const handleValidate = async () => {\n const manifest = parsed();\n if (!manifest) return;\n try {\n const { data } = await validate({ variables: { manifest } });\n const result:\n | DevportalValidateTimeCampusAppletManifestQuery[\"validateTimeCampusAppletManifest\"]\n | undefined = data?.validateTimeCampusAppletManifest;\n setProblems(result?.errors ?? []);\n setValidated(result?.valid === true);\n } catch (err) {\n setProblems([errorText(err)]);\n setValidated(false);\n }\n };\n\n const handleSave = async () => {\n const manifest = parsed();\n if (!manifest) return;\n try {\n if (target.kind === \"new\") {\n await createApplet({ variables: { manifest } });\n onSaved(\n tr(\n \"devportal.timecampusApplets.registered\",\n \"Applet registered as a draft. Submit it for review when it is ready.\",\n ),\n );\n } else if (target.kind === \"edit\") {\n await updateVersion({\n variables: { versionId: target.versionId, manifest },\n });\n onSaved(\n tr(\n \"devportal.timecampusApplets.versionUpdated\",\n \"Manifest saved. The version is a draft.\",\n ),\n );\n } else {\n await addVersion({\n variables: { appletId: target.appletId, manifest },\n });\n onSaved(\n tr(\n \"devportal.timecampusApplets.versionAdded\",\n \"New version saved as a draft.\",\n ),\n );\n }\n } catch (err) {\n setProblems([errorText(err)]);\n setValidated(false);\n }\n };\n\n const title =\n target.kind === \"new\"\n ? tr(\"devportal.timecampusApplets.registerTitle\", \"Register an applet\")\n : target.kind === \"edit\"\n ? tr(\n \"devportal.timecampusApplets.editVersionTitle\",\n \"Edit v{{version}} of {{name}}\",\n { name: target.appletName, version: target.version },\n )\n : tr(\n \"devportal.timecampusApplets.newVersionTitle\",\n \"Upload a new version of {{name}}\",\n { name: target.appletName },\n );\n\n return (\n <GlassCard\n className=\"flex flex-col gap-3 p-4\"\n data-testid=\"tc-manifest-editor\"\n >\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h2 className=\"text-base font-semibold text-text-primary\">{title}</h2>\n <a\n href={TIMECAMPUS_MANIFEST_DOCS_URL}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm text-primary hover:underline\"\n >\n {tr(\n \"devportal.timecampusApplets.manifestReference\",\n \"Manifest reference\",\n )}\n <ExternalLink className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </a>\n </div>\n <label className=\"flex flex-col gap-1 text-sm text-text-secondary\">\n {tr(\"devportal.timecampusApplets.manifestLabel\", \"Manifest (JSON)\")}\n <textarea\n value={text}\n onChange={(event) => {\n setText(event.target.value);\n setValidated(false);\n }}\n spellCheck={false}\n rows={18}\n className=\"w-full rounded-md border border-border-subtle bg-bg-sunken p-3 font-mono text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n data-testid=\"tc-manifest-text\"\n />\n </label>\n {problems.length > 0 && (\n <ul\n className=\"list-disc space-y-1 rounded-md bg-status-error-bg-subtle py-2 pl-6 pr-3 text-xs text-status-error-text\"\n role=\"alert\"\n data-testid=\"tc-manifest-problems\"\n >\n {problems.map((problem, index) => (\n // Validation errors can repeat (two widgets failing the same\n // check), so the message alone is not a unique key.\n <li key={`${index}-${problem}`}>{problem}</li>\n ))}\n </ul>\n )}\n {validated && problems.length === 0 && (\n <p\n className=\"flex items-center gap-1.5 text-xs text-status-success-text\"\n data-testid=\"tc-manifest-valid\"\n >\n <CheckCircle2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\n \"devportal.timecampusApplets.manifestValid\",\n \"The manifest is valid.\",\n )}\n </p>\n )}\n <div className=\"flex flex-wrap justify-end gap-2\">\n <button type=\"button\" className={outlineButton} onClick={onClose}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n className={outlineButton}\n onClick={() => void handleValidate()}\n disabled={validating || saving}\n >\n <CheckCircle2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\"devportal.timecampusApplets.validate\", \"Validate\")}\n </button>\n <button\n type=\"button\"\n className={primaryButton}\n onClick={() => void handleSave()}\n disabled={saving}\n data-testid=\"tc-manifest-save\"\n >\n <Upload className=\"h-4 w-4\" aria-hidden=\"true\" />\n {target.kind === \"new\"\n ? tr(\"devportal.timecampusApplets.register\", \"Register applet\")\n : tr(\"devportal.timecampusApplets.uploadVersion\", \"Upload version\")}\n </button>\n </div>\n </GlassCard>\n );\n};\n\n// =============================================================================\n// Applet card\n// =============================================================================\n\nconst AppletCard: FC<{\n applet: DevportalTimeCampusAppletFragment;\n busy: boolean;\n onNewVersion: () => void;\n onEditVersion: () => void;\n onSubmitVersion: (versionId: string) => void;\n onWithdrawVersion: (versionId: string) => void;\n onOffer: () => void;\n onWithdrawOffer: () => void;\n}> = ({\n applet,\n busy,\n onNewVersion,\n onEditVersion,\n onSubmitVersion,\n onWithdrawVersion,\n onOffer,\n onWithdrawOffer,\n}) => {\n const tr = useTr();\n const latest = applet.latestVersion;\n const action = versionAction(applet);\n const offer = marketplaceOffer(applet);\n const listing = applet.marketplace;\n const submission = listing?.latestSubmission;\n\n return (\n <GlassCard\n className=\"flex flex-col gap-4 p-4\"\n data-testid={`tc-applet-${applet.key}`}\n >\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n {applet.name}\n </h3>\n <StatusBadge status={applet.status} />\n </div>\n <p className=\"mt-0.5 font-mono text-xs text-text-tertiary\">\n {applet.key}\n </p>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {applet.description}\n </p>\n </div>\n <button\n type=\"button\"\n className={outlineButton}\n onClick={onNewVersion}\n disabled={busy || !canAddVersion(applet)}\n title={\n canAddVersion(applet)\n ? undefined\n : tr(\n \"devportal.timecampusApplets.openVersionHint\",\n \"Finish or withdraw the open version first.\",\n )\n }\n >\n <FilePlus2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\"devportal.timecampusApplets.newVersion\", \"New version\")}\n </button>\n </div>\n\n <div className=\"grid gap-3 md:grid-cols-2\">\n {/* Workspace review of the latest version */}\n <div\n className=\"flex flex-col gap-2 rounded-md border border-border-subtle bg-bg-sunken/40 p-3\"\n data-testid={`tc-applet-version-${applet.key}`}\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr(\n \"devportal.timecampusApplets.latestVersion\",\n \"Latest version\",\n )}{\" \"}\n v{latest.version}\n </p>\n <StatusBadge status={latest.status} />\n </div>\n {applet.liveVersion && applet.liveVersion.id !== latest.id && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n \"devportal.timecampusApplets.liveInWorkspace\",\n \"v{{version}} is live in your workspace.\",\n { version: applet.liveVersion.version },\n )}\n </p>\n )}\n {latest.submittedAt && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.timecampusApplets.submitted\", \"Submitted\")}{\" \"}\n {formatDate(latest.submittedAt)}\n </p>\n )}\n {latest.reviewNotes && (\n <p className=\"text-xs text-text-secondary\">\n <span className=\"font-medium text-text-primary\">\n {tr(\"devportal.timecampusApplets.reviewNotes\", \"Review notes\")}:\n </span>{\" \"}\n {latest.reviewNotes}\n </p>\n )}\n {latest.suspendedReason && (\n <p className=\"text-xs text-status-warning-text\">\n {latest.suspendedReason}\n </p>\n )}\n {canEditVersion(applet) && (\n <button\n type=\"button\"\n className={outlineButton}\n onClick={onEditVersion}\n disabled={busy}\n data-testid={`tc-edit-version-${applet.key}`}\n >\n <Pencil className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\"devportal.timecampusApplets.editManifest\", \"Edit manifest\")}\n </button>\n )}\n {action.kind === \"submit\" && (\n <button\n type=\"button\"\n className={primaryButton}\n onClick={() => onSubmitVersion(action.versionId)}\n disabled={busy}\n >\n <Send className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\n \"devportal.timecampusApplets.submitForReview\",\n \"Submit for review\",\n )}\n </button>\n )}\n {action.kind === \"withdraw\" && (\n <button\n type=\"button\"\n className={outlineButton}\n onClick={() => onWithdrawVersion(action.versionId)}\n disabled={busy}\n >\n <Undo2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\n \"devportal.timecampusApplets.withdrawReview\",\n \"Withdraw from review\",\n )}\n </button>\n )}\n </div>\n\n {/* Public marketplace listing */}\n <div\n className=\"flex flex-col gap-2 rounded-md border border-border-subtle bg-bg-sunken/40 p-3\"\n data-testid={`tc-applet-marketplace-${applet.key}`}\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <Globe className=\"h-4 w-4 text-text-tertiary\" aria-hidden=\"true\" />\n <p className=\"text-sm font-medium text-text-primary\">\n {tr(\n \"devportal.timecampusApplets.marketplace\",\n \"Public marketplace\",\n )}\n </p>\n {listing ? (\n <StatusBadge status={listing.status} />\n ) : (\n <StatusBadge status=\"NOT_LISTED\" />\n )}\n </div>\n {listing?.liveSubmission && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n \"devportal.timecampusApplets.certifiedLive\",\n \"v{{version}} is certified and live in the marketplace.\",\n { version: listing.liveSubmission.version },\n )}\n </p>\n )}\n {submission && (\n <p className=\"flex flex-wrap items-center gap-2 text-xs text-text-secondary\">\n {tr(\n \"devportal.timecampusApplets.latestSubmission\",\n \"Latest submission v{{version}}\",\n { version: submission.version },\n )}\n <StatusBadge status={submission.status} />\n </p>\n )}\n {submission?.reviewNotes && (\n <p className=\"text-xs text-text-secondary\">\n <span className=\"font-medium text-text-primary\">\n {tr(\n \"devportal.timecampusApplets.certificationNotes\",\n \"Certification notes\",\n )}\n :\n </span>{\" \"}\n {submission.reviewNotes}\n </p>\n )}\n {listing?.suspendedReason && (\n <p className=\"text-xs text-status-warning-text\">\n {listing.suspendedReason}\n </p>\n )}\n {canWithdrawFromMarketplace(applet) ? (\n <button\n type=\"button\"\n className={outlineButton}\n onClick={onWithdrawOffer}\n disabled={busy}\n >\n <Undo2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\n \"devportal.timecampusApplets.withdrawSubmission\",\n \"Withdraw submission\",\n )}\n </button>\n ) : offer.canOffer ? (\n <button\n type=\"button\"\n className={primaryButton}\n onClick={onOffer}\n disabled={busy}\n >\n <Globe className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\n \"devportal.timecampusApplets.offer\",\n \"Offer v{{version}} to the marketplace\",\n { version: offer.version },\n )}\n </button>\n ) : (\n <p className=\"text-xs text-text-tertiary\">{offer.reason}</p>\n )}\n </div>\n </div>\n </GlassCard>\n );\n};\n\n// =============================================================================\n// Page\n// =============================================================================\n\nconst ResourceLinks: FC = () => {\n const tr = useTr();\n const links = [\n {\n href: TIMECAMPUS_MANIFEST_DOCS_URL,\n label: tr(\n \"devportal.timecampusApplets.docsManifest\",\n \"Applet manifest reference\",\n ),\n icon: BookOpen,\n },\n {\n href: TIMECAMPUS_SAMPLE_WIDGET_URL,\n label: tr(\n \"devportal.timecampusApplets.docsSample\",\n \"Sample widget (view source)\",\n ),\n icon: Puzzle,\n },\n {\n href: TIMECAMPUS_APPLETS_DOCS_URL,\n label: tr(\n \"devportal.timecampusApplets.docsApplets\",\n \"How applets work in TimeCampus\",\n ),\n icon: Globe,\n },\n ];\n return (\n <ul className=\"flex flex-wrap gap-2\" data-testid=\"tc-applet-resources\">\n {links.map(({ href, label, icon: Icon }) => (\n <li key={href}>\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={outlineButton}\n >\n <Icon className=\"h-4 w-4\" aria-hidden=\"true\" />\n {label}\n <ExternalLink className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </a>\n </li>\n ))}\n </ul>\n );\n};\n\nexport const TimeCampusAppletsPage: FC = () => {\n const tr = useTr();\n const { workspaceId } = useDevportal();\n const workspaceClient = useSafeGatewayClient(\"workspace\");\n const client = workspaceClient ?? undefined;\n const hasWorkspace = Boolean(workspaceId) && Boolean(workspaceClient);\n\n const [editorState, setEditorState] = useState<EditorState | null>(null);\n // An editor opened in another workspace is dropped, not carried over.\n const editor =\n editorState && editorState.workspaceId === workspaceId ? editorState : null;\n const openEditor = (target: EditorTarget, text: string) => {\n if (!workspaceId) return;\n setFeedback(null);\n setEditorState({ target, text, workspaceId });\n };\n const [feedback, setFeedback] = useState<Feedback>(null);\n\n const { data, loading, error } = useDevportalTimeCampusAppletsQuery({\n client,\n skip: !hasWorkspace,\n fetchPolicy: \"cache-and-network\",\n });\n const { data: workspacesData } = useMyWorkspacesQuery({\n client,\n skip: !hasWorkspace,\n variables: { pagination: { limit: 100, offset: 0 } },\n });\n // The generated hooks resolve their result types loosely (the codegen\n // preset types them against wspace-types), so pin the shapes here.\n const workspaceItems: MyWorkspacesQuery[\"myWorkspaces\"][\"items\"] =\n workspacesData?.myWorkspaces?.items ?? [];\n const workspaceName =\n workspaceItems.find((item) => item.id === workspaceId)?.name ?? null;\n\n const mutationOptions = {\n client,\n refetchQueries: REFRESH_QUERIES,\n awaitRefetchQueries: true,\n };\n const [submitVersion, submitState] =\n useDevportalSubmitTimeCampusAppletVersionMutation(mutationOptions);\n const [withdrawVersion, withdrawState] =\n useDevportalWithdrawTimeCampusAppletVersionMutation(mutationOptions);\n const [offerToMarketplace, offerState] =\n useDevportalSubmitTimeCampusAppletToMarketplaceMutation(mutationOptions);\n const [withdrawOffer, withdrawOfferState] =\n useDevportalWithdrawTimeCampusAppletFromMarketplaceMutation(\n mutationOptions,\n );\n const busy =\n submitState.loading ||\n withdrawState.loading ||\n offerState.loading ||\n withdrawOfferState.loading;\n\n const run = async (action: () => Promise<unknown>, success: string) => {\n setFeedback(null);\n try {\n await action();\n setFeedback({ tone: \"success\", text: success });\n } catch (err) {\n setFeedback({ tone: \"error\", text: errorText(err) });\n }\n };\n\n const applets: DevportalTimeCampusAppletsQuery[\"timeCampusMyThirdPartyApplets\"] =\n data?.timeCampusMyThirdPartyApplets ?? [];\n\n return (\n <PageLayout\n title={tr(\"devportal.timecampusApplets.title\", \"TimeCampus applets\")}\n description={tr(\n \"devportal.timecampusApplets.description\",\n \"Build widgets for TimeCampus, publish them in your workspace and offer them to every TimeCampus workspace.\",\n )}\n purpose={tr(\n \"devportal.timecampusApplets.purpose\",\n \"Register an applet from a JSON manifest, upload new versions, send each version to your workspace's reviewers, and once it is live offer it to the public marketplace. The TimeCampus platform team certifies every marketplace version before other workspaces can install it.\",\n )}\n purposeLearnMoreHref={TIMECAMPUS_MANIFEST_DOCS_URL}\n actions={\n hasWorkspace ? (\n <button\n type=\"button\"\n className={primaryButton}\n onClick={() => openEditor({ kind: \"new\" }, starterManifest())}\n data-testid=\"tc-register-applet\"\n >\n <FilePlus2 className=\"h-4 w-4\" aria-hidden=\"true\" />\n {tr(\"devportal.timecampusApplets.register\", \"Register applet\")}\n </button>\n ) : undefined\n }\n >\n <PageSection\n title={tr(\"devportal.timecampusApplets.resources\", \"Build an applet\")}\n >\n <ResourceLinks />\n </PageSection>\n\n {!hasWorkspace ? (\n <EmptyState\n icon={<Puzzle className=\"h-8 w-8\" aria-hidden=\"true\" />}\n title={tr(\n \"devportal.timecampusApplets.noWorkspaceTitle\",\n \"Choose a workspace\",\n )}\n description={tr(\n \"devportal.timecampusApplets.noWorkspace\",\n \"TimeCampus applets belong to a workspace. Pick the workspace you develop in with the context switcher at the top of the page.\",\n )}\n />\n ) : (\n <>\n <p className=\"text-sm text-text-secondary\" data-testid=\"tc-workspace\">\n {workspaceName\n ? tr(\n \"devportal.timecampusApplets.inWorkspace\",\n \"Your applets in {{workspace}}. Switch workspace with the context switcher.\",\n { workspace: workspaceName },\n )\n : tr(\n \"devportal.timecampusApplets.inActiveWorkspace\",\n \"Your applets in the active workspace. Switch workspace with the context switcher.\",\n )}\n </p>\n\n {feedback && (\n <p\n role={feedback.tone === \"error\" ? \"alert\" : \"status\"}\n className={\n feedback.tone === \"error\"\n ? \"rounded-md bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\"\n : \"rounded-md bg-status-success-bg-subtle px-3 py-2 text-sm text-status-success-text\"\n }\n data-testid=\"tc-feedback\"\n >\n {feedback.text}\n </p>\n )}\n\n {editor && (\n <ManifestEditor\n key={`${editor.workspaceId}-${editorKey(editor.target)}`}\n target={editor.target}\n initialText={editor.text}\n onClose={() => setEditorState(null)}\n onSaved={(message) => {\n setEditorState(null);\n setFeedback({ tone: \"success\", text: message });\n }}\n />\n )}\n\n <PageSection\n title={tr(\n \"devportal.timecampusApplets.yourApplets\",\n \"Your applets\",\n )}\n data-testid=\"tc-applet-list\"\n >\n {loading && applets.length === 0 ? (\n <LoadingState\n message={tr(\n \"devportal.timecampusApplets.loading\",\n \"Loading your applets...\",\n )}\n />\n ) : error && applets.length === 0 ? (\n <p\n role=\"alert\"\n className=\"rounded-md bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\"\n >\n {errorText(error)}\n </p>\n ) : applets.length === 0 ? (\n <EmptyState\n icon={<Puzzle className=\"h-8 w-8\" aria-hidden=\"true\" />}\n title={tr(\n \"devportal.timecampusApplets.emptyTitle\",\n \"No applets yet\",\n )}\n description={tr(\n \"devportal.timecampusApplets.empty\",\n \"Register your first applet. The starter manifest points at the sample widget, so it validates as is.\",\n )}\n />\n ) : (\n <div className=\"flex flex-col gap-4\">\n {applets.map((applet) => (\n <AppletCard\n key={applet.id}\n applet={applet}\n busy={busy}\n onNewVersion={() =>\n openEditor(\n {\n kind: \"version\",\n appletId: applet.id,\n appletName: applet.name,\n },\n manifestForNextVersion(applet.latestVersion.manifest),\n )\n }\n onEditVersion={() =>\n openEditor(\n {\n kind: \"edit\",\n versionId: applet.latestVersion.id,\n appletName: applet.name,\n version: applet.latestVersion.version,\n },\n manifestText(applet.latestVersion.manifest),\n )\n }\n onSubmitVersion={(versionId) =>\n void run(\n () => submitVersion({ variables: { versionId } }),\n tr(\n \"devportal.timecampusApplets.submittedForReview\",\n \"Sent to your workspace's reviewers.\",\n ),\n )\n }\n onWithdrawVersion={(versionId) =>\n void run(\n () => withdrawVersion({ variables: { versionId } }),\n tr(\n \"devportal.timecampusApplets.withdrawnFromReview\",\n \"Withdrawn from review. The version is a draft again.\",\n ),\n )\n }\n onOffer={() =>\n void run(\n () =>\n offerToMarketplace({\n variables: { appletId: applet.id },\n }),\n tr(\n \"devportal.timecampusApplets.offered\",\n \"Sent to the TimeCampus platform team for certification.\",\n ),\n )\n }\n onWithdrawOffer={() =>\n void run(\n () =>\n withdrawOffer({ variables: { appletId: applet.id } }),\n tr(\n \"devportal.timecampusApplets.offerWithdrawn\",\n \"Marketplace submission withdrawn.\",\n ),\n )\n }\n />\n ))}\n </div>\n )}\n </PageSection>\n </>\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -10,7 +10,11 @@ var e = {
10
10
  DEPRECATED: "bg-bg-sunken text-text-secondary",
11
11
  ACTIVE: "bg-status-success-bg-subtle text-status-success-text",
12
12
  INACTIVE: "bg-bg-sunken text-text-secondary",
13
- REVOKED: "bg-status-error-bg-subtle text-status-error-text"
13
+ REVOKED: "bg-status-error-bg-subtle text-status-error-text",
14
+ CERTIFIED: "bg-status-success-bg-subtle text-status-success-text",
15
+ WITHDRAWN: "bg-bg-sunken text-text-secondary",
16
+ SUPERSEDED: "bg-bg-sunken text-text-secondary",
17
+ NOT_LISTED: "bg-bg-sunken text-text-secondary"
14
18
  }, t = {
15
19
  ACTIVE: "bg-status-success-bg-subtle text-status-success-text",
16
20
  PAUSED: "bg-status-warning-bg-subtle text-status-warning-text",
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":["APP_STATUS_COLORS","WEBHOOK_STATUS_COLORS","DELIVERY_STATUS_COLORS","INVITATION_STATUS_COLORS","ORG_TIER_COLORS","PARTNER_TIER_COLORS","APP_TYPE_LABELS","ORG_ROLE_LABELS"],"sources":["../../../src/devportal/utils/constants.ts"],"sourcesContent":["/**\n * Developer Portal Constants\n */\n\n// API Endpoints\nexport const API_ENDPOINTS = {\n GRAPHQL: \"/graphql\",\n} as const;\n\n// App Status Colors\nexport const APP_STATUS_COLORS: Record<string, string> = {\n DRAFT: \"bg-bg-sunken text-text-primary\",\n SUBMITTED: \"bg-status-info-bg-subtle text-status-info-text\",\n IN_REVIEW: \"bg-status-warning-bg-subtle text-status-warning-text\",\n APPROVED: \"bg-status-success-bg-subtle text-status-success-text\",\n PUBLISHED: \"bg-status-success-bg-subtle text-status-success-text\",\n REJECTED: \"bg-status-error-bg-subtle text-status-error-text\",\n SUSPENDED: \"bg-accent-orange-subtle text-accent-orange\",\n DEPRECATED: \"bg-bg-sunken text-text-secondary\",\n ACTIVE: \"bg-status-success-bg-subtle text-status-success-text\",\n INACTIVE: \"bg-bg-sunken text-text-secondary\",\n REVOKED: \"bg-status-error-bg-subtle text-status-error-text\",\n};\n\n// Webhook Status Colors\nexport const WEBHOOK_STATUS_COLORS: Record<string, string> = {\n ACTIVE: \"bg-status-success-bg-subtle text-status-success-text\",\n PAUSED: \"bg-status-warning-bg-subtle text-status-warning-text\",\n FAILED: \"bg-status-error-bg-subtle text-status-error-text\",\n DISABLED: \"bg-bg-sunken text-text-secondary\",\n};\n\n// Delivery Status Colors\nexport const DELIVERY_STATUS_COLORS: Record<string, string> = {\n PENDING: \"bg-bg-sunken text-text-primary\",\n DELIVERING: \"bg-status-info-bg-subtle text-status-info-text\",\n DELIVERED: \"bg-status-success-bg-subtle text-status-success-text\",\n FAILED: \"bg-status-error-bg-subtle text-status-error-text\",\n RETRYING: \"bg-status-warning-bg-subtle text-status-warning-text\",\n};\n\n// Invitation Status Colors\nexport const INVITATION_STATUS_COLORS: Record<string, string> = {\n PENDING: \"bg-status-warning-bg-subtle text-status-warning-text\",\n ACCEPTED: \"bg-status-success-bg-subtle text-status-success-text\",\n REJECTED: \"bg-status-error-bg-subtle text-status-error-text\",\n EXPIRED: \"bg-bg-sunken text-text-secondary\",\n CANCELLED: \"bg-bg-sunken text-text-secondary\",\n};\n\n// Organization Tier Colors\nexport const ORG_TIER_COLORS: Record<string, string> = {\n FREE: \"bg-bg-sunken text-text-primary\",\n DEVELOPER: \"bg-status-info-bg-subtle text-status-info-text\",\n PROFESSIONAL: \"bg-accent-purple-subtle text-accent-purple\",\n ENTERPRISE: \"bg-status-warning-bg-subtle text-status-warning-text\",\n};\n\n// Partner Tier Colors\nexport const PARTNER_TIER_COLORS: Record<string, string> = {\n REGISTERED: \"bg-bg-sunken text-text-primary\",\n SELECT: \"bg-status-info-bg-subtle text-status-info-text\",\n PREMIER: \"bg-status-warning-bg-subtle text-status-warning-text\",\n};\n\n// App Type Labels\nexport const APP_TYPE_LABELS: Record<string, string> = {\n WEB_APP: \"Web Application\",\n MOBILE_APP: \"Mobile App\",\n DESKTOP_APP: \"Desktop App\",\n CLI_TOOL: \"CLI Tool\",\n API_INTEGRATION: \"API Integration\",\n WORKFLOW: \"Workflow\",\n WIDGET: \"Widget\",\n BOT: \"Bot\",\n SERVICE: \"Service\",\n INTEGRATION: \"Integration\",\n ANALYST: \"Analyst\",\n ASSISTANT: \"Assistant\",\n AUTOMATION: \"Automation\",\n SPECIALIST: \"Specialist\",\n PARSER: \"Parser\",\n DASHBOARD: \"Dashboard Template\",\n};\n\n// OAuth Grant Type Labels\nexport const GRANT_TYPE_LABELS: Record<string, string> = {\n AUTHORIZATION_CODE: \"Authorization Code\",\n REFRESH_TOKEN: \"Refresh Token\",\n CLIENT_CREDENTIALS: \"Client Credentials\",\n IMPLICIT: \"Implicit (Legacy)\",\n PASSWORD: \"Password (Legacy)\",\n};\n\n// API Key Type Labels\nexport const API_KEY_TYPE_LABELS: Record<string, string> = {\n PUBLISHABLE: \"Publishable Key\",\n SECRET: \"Secret Key\",\n RESTRICTED: \"Restricted Key\",\n};\n\n// Organization Role Labels\nexport const ORG_ROLE_LABELS: Record<string, string> = {\n OWNER: \"Owner\",\n ADMIN: \"Admin\",\n DEVELOPER: \"Developer\",\n VIEWER: \"Viewer\",\n};\n\n// Pagination defaults\nexport const DEFAULT_PAGE_SIZE = 10;\nexport const PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\n\n// Date format\nexport const DATE_FORMAT = \"MMM d, yyyy\";\nexport const DATETIME_FORMAT = \"MMM d, yyyy HH:mm\";\n\n// Documentation links\nexport const DOCS_LINKS = {\n GETTING_STARTED:\n \"https://docs.burdenoff.com/developer-portal/getting-started\",\n API_REFERENCE: \"https://docs.burdenoff.com/api-reference\",\n OAUTH2: \"https://docs.burdenoff.com/developer-portal/oauth2\",\n WEBHOOKS: \"https://docs.burdenoff.com/developer-portal/webhooks\",\n SDK_NODE: \"https://docs.burdenoff.com/sdks/nodejs\",\n SDK_PYTHON: \"https://docs.burdenoff.com/sdks/python\",\n BEST_PRACTICES: \"https://docs.burdenoff.com/developer-portal/best-practices\",\n CHANGELOG: \"https://docs.burdenoff.com/changelog\",\n};\n\n// Feature flags (for progressive rollout)\nexport const FEATURE_FLAGS = {\n SHOW_ANALYTICS: true,\n SHOW_REVENUE: true,\n SHOW_STORE_INTEGRATION: true,\n SHOW_AUDIT_LOGS: true,\n ENABLE_DARK_MODE: true,\n};\n\n// Available OAuth/API scopes\nexport const AVAILABLE_SCOPES = [\n // User scopes\n {\n scope: \"user:read\",\n description: \"Read user profile information\",\n category: \"User\",\n },\n {\n scope: \"user:write\",\n description: \"Modify user profile information\",\n category: \"User\",\n },\n {\n scope: \"user:email\",\n description: \"Access user email address\",\n category: \"User\",\n },\n // Workspace scopes\n {\n scope: \"workspace:read\",\n description: \"Read workspace information\",\n category: \"Workspace\",\n },\n {\n scope: \"workspace:write\",\n description: \"Create and modify workspaces\",\n category: \"Workspace\",\n },\n {\n scope: \"workspace:delete\",\n description: \"Delete workspaces\",\n category: \"Workspace\",\n },\n {\n scope: \"workspace:members\",\n description: \"Manage workspace members\",\n category: \"Workspace\",\n },\n // Project scopes\n {\n scope: \"project:read\",\n description: \"Read project information\",\n category: \"Project\",\n },\n {\n scope: \"project:write\",\n description: \"Create and modify projects\",\n category: \"Project\",\n },\n {\n scope: \"project:delete\",\n description: \"Delete projects\",\n category: \"Project\",\n },\n // Task scopes\n { scope: \"task:read\", description: \"Read tasks\", category: \"Task\" },\n {\n scope: \"task:write\",\n description: \"Create and modify tasks\",\n category: \"Task\",\n },\n { scope: \"task:delete\", description: \"Delete tasks\", category: \"Task\" },\n // File scopes\n { scope: \"file:read\", description: \"Read files\", category: \"File\" },\n {\n scope: \"file:write\",\n description: \"Upload and modify files\",\n category: \"File\",\n },\n { scope: \"file:delete\", description: \"Delete files\", category: \"File\" },\n // Offline access\n {\n scope: \"offline_access\",\n description: \"Access data while user is offline\",\n category: \"Access\",\n },\n] as const;\n"],"mappings":";AAUA,IAAaA,IAA4C;CACvD,OAAO;CACP,WAAW;CACX,WAAW;CACX,UAAU;CACV,WAAW;CACX,UAAU;CACV,WAAW;CACX,YAAY;CACZ,QAAQ;CACR,UAAU;CACV,SAAS;AACX,GAGaC,IAAgD;CAC3D,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,UAAU;AACZ,GAGaC,IAAiD;CAC5D,SAAS;CACT,YAAY;CACZ,WAAW;CACX,QAAQ;CACR,UAAU;AACZ,GAGaC,IAAmD;CAC9D,SAAS;CACT,UAAU;CACV,UAAU;CACV,SAAS;CACT,WAAW;AACb,GAGaC,IAA0C;CACrD,MAAM;CACN,WAAW;CACX,cAAc;CACd,YAAY;AACd,GAGaC,IAA8C;CACzD,YAAY;CACZ,QAAQ;CACR,SAAS;AACX,GAGaC,IAA0C;CACrD,SAAS;CACT,YAAY;CACZ,aAAa;CACb,UAAU;CACV,iBAAiB;CACjB,UAAU;CACV,QAAQ;CACR,KAAK;CACL,SAAS;CACT,aAAa;CACb,SAAS;CACT,WAAW;CACX,YAAY;CACZ,YAAY;CACZ,QAAQ;CACR,WAAW;AACb,GAmBaC,IAA0C;CACrD,OAAO;CACP,OAAO;CACP,WAAW;CACX,QAAQ;AACV"}
1
+ {"version":3,"file":"constants.js","names":["APP_STATUS_COLORS","WEBHOOK_STATUS_COLORS","DELIVERY_STATUS_COLORS","INVITATION_STATUS_COLORS","ORG_TIER_COLORS","PARTNER_TIER_COLORS","APP_TYPE_LABELS","ORG_ROLE_LABELS"],"sources":["../../../src/devportal/utils/constants.ts"],"sourcesContent":["/**\n * Developer Portal Constants\n */\n\n// API Endpoints\nexport const API_ENDPOINTS = {\n GRAPHQL: \"/graphql\",\n} as const;\n\n// App Status Colors\nexport const APP_STATUS_COLORS: Record<string, string> = {\n DRAFT: \"bg-bg-sunken text-text-primary\",\n SUBMITTED: \"bg-status-info-bg-subtle text-status-info-text\",\n IN_REVIEW: \"bg-status-warning-bg-subtle text-status-warning-text\",\n APPROVED: \"bg-status-success-bg-subtle text-status-success-text\",\n PUBLISHED: \"bg-status-success-bg-subtle text-status-success-text\",\n REJECTED: \"bg-status-error-bg-subtle text-status-error-text\",\n SUSPENDED: \"bg-accent-orange-subtle text-accent-orange\",\n DEPRECATED: \"bg-bg-sunken text-text-secondary\",\n ACTIVE: \"bg-status-success-bg-subtle text-status-success-text\",\n INACTIVE: \"bg-bg-sunken text-text-secondary\",\n REVOKED: \"bg-status-error-bg-subtle text-status-error-text\",\n // TimeCampus applet and marketplace states (BOFF-11005)\n CERTIFIED: \"bg-status-success-bg-subtle text-status-success-text\",\n WITHDRAWN: \"bg-bg-sunken text-text-secondary\",\n SUPERSEDED: \"bg-bg-sunken text-text-secondary\",\n NOT_LISTED: \"bg-bg-sunken text-text-secondary\",\n};\n\n// Webhook Status Colors\nexport const WEBHOOK_STATUS_COLORS: Record<string, string> = {\n ACTIVE: \"bg-status-success-bg-subtle text-status-success-text\",\n PAUSED: \"bg-status-warning-bg-subtle text-status-warning-text\",\n FAILED: \"bg-status-error-bg-subtle text-status-error-text\",\n DISABLED: \"bg-bg-sunken text-text-secondary\",\n};\n\n// Delivery Status Colors\nexport const DELIVERY_STATUS_COLORS: Record<string, string> = {\n PENDING: \"bg-bg-sunken text-text-primary\",\n DELIVERING: \"bg-status-info-bg-subtle text-status-info-text\",\n DELIVERED: \"bg-status-success-bg-subtle text-status-success-text\",\n FAILED: \"bg-status-error-bg-subtle text-status-error-text\",\n RETRYING: \"bg-status-warning-bg-subtle text-status-warning-text\",\n};\n\n// Invitation Status Colors\nexport const INVITATION_STATUS_COLORS: Record<string, string> = {\n PENDING: \"bg-status-warning-bg-subtle text-status-warning-text\",\n ACCEPTED: \"bg-status-success-bg-subtle text-status-success-text\",\n REJECTED: \"bg-status-error-bg-subtle text-status-error-text\",\n EXPIRED: \"bg-bg-sunken text-text-secondary\",\n CANCELLED: \"bg-bg-sunken text-text-secondary\",\n};\n\n// Organization Tier Colors\nexport const ORG_TIER_COLORS: Record<string, string> = {\n FREE: \"bg-bg-sunken text-text-primary\",\n DEVELOPER: \"bg-status-info-bg-subtle text-status-info-text\",\n PROFESSIONAL: \"bg-accent-purple-subtle text-accent-purple\",\n ENTERPRISE: \"bg-status-warning-bg-subtle text-status-warning-text\",\n};\n\n// Partner Tier Colors\nexport const PARTNER_TIER_COLORS: Record<string, string> = {\n REGISTERED: \"bg-bg-sunken text-text-primary\",\n SELECT: \"bg-status-info-bg-subtle text-status-info-text\",\n PREMIER: \"bg-status-warning-bg-subtle text-status-warning-text\",\n};\n\n// App Type Labels\nexport const APP_TYPE_LABELS: Record<string, string> = {\n WEB_APP: \"Web Application\",\n MOBILE_APP: \"Mobile App\",\n DESKTOP_APP: \"Desktop App\",\n CLI_TOOL: \"CLI Tool\",\n API_INTEGRATION: \"API Integration\",\n WORKFLOW: \"Workflow\",\n WIDGET: \"Widget\",\n BOT: \"Bot\",\n SERVICE: \"Service\",\n INTEGRATION: \"Integration\",\n ANALYST: \"Analyst\",\n ASSISTANT: \"Assistant\",\n AUTOMATION: \"Automation\",\n SPECIALIST: \"Specialist\",\n PARSER: \"Parser\",\n DASHBOARD: \"Dashboard Template\",\n};\n\n// OAuth Grant Type Labels\nexport const GRANT_TYPE_LABELS: Record<string, string> = {\n AUTHORIZATION_CODE: \"Authorization Code\",\n REFRESH_TOKEN: \"Refresh Token\",\n CLIENT_CREDENTIALS: \"Client Credentials\",\n IMPLICIT: \"Implicit (Legacy)\",\n PASSWORD: \"Password (Legacy)\",\n};\n\n// API Key Type Labels\nexport const API_KEY_TYPE_LABELS: Record<string, string> = {\n PUBLISHABLE: \"Publishable Key\",\n SECRET: \"Secret Key\",\n RESTRICTED: \"Restricted Key\",\n};\n\n// Organization Role Labels\nexport const ORG_ROLE_LABELS: Record<string, string> = {\n OWNER: \"Owner\",\n ADMIN: \"Admin\",\n DEVELOPER: \"Developer\",\n VIEWER: \"Viewer\",\n};\n\n// Pagination defaults\nexport const DEFAULT_PAGE_SIZE = 10;\nexport const PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\n\n// Date format\nexport const DATE_FORMAT = \"MMM d, yyyy\";\nexport const DATETIME_FORMAT = \"MMM d, yyyy HH:mm\";\n\n// Documentation links\nexport const DOCS_LINKS = {\n GETTING_STARTED:\n \"https://docs.burdenoff.com/developer-portal/getting-started\",\n API_REFERENCE: \"https://docs.burdenoff.com/api-reference\",\n OAUTH2: \"https://docs.burdenoff.com/developer-portal/oauth2\",\n WEBHOOKS: \"https://docs.burdenoff.com/developer-portal/webhooks\",\n SDK_NODE: \"https://docs.burdenoff.com/sdks/nodejs\",\n SDK_PYTHON: \"https://docs.burdenoff.com/sdks/python\",\n BEST_PRACTICES: \"https://docs.burdenoff.com/developer-portal/best-practices\",\n CHANGELOG: \"https://docs.burdenoff.com/changelog\",\n};\n\n// Feature flags (for progressive rollout)\nexport const FEATURE_FLAGS = {\n SHOW_ANALYTICS: true,\n SHOW_REVENUE: true,\n SHOW_STORE_INTEGRATION: true,\n SHOW_AUDIT_LOGS: true,\n ENABLE_DARK_MODE: true,\n};\n\n// Available OAuth/API scopes\nexport const AVAILABLE_SCOPES = [\n // User scopes\n {\n scope: \"user:read\",\n description: \"Read user profile information\",\n category: \"User\",\n },\n {\n scope: \"user:write\",\n description: \"Modify user profile information\",\n category: \"User\",\n },\n {\n scope: \"user:email\",\n description: \"Access user email address\",\n category: \"User\",\n },\n // Workspace scopes\n {\n scope: \"workspace:read\",\n description: \"Read workspace information\",\n category: \"Workspace\",\n },\n {\n scope: \"workspace:write\",\n description: \"Create and modify workspaces\",\n category: \"Workspace\",\n },\n {\n scope: \"workspace:delete\",\n description: \"Delete workspaces\",\n category: \"Workspace\",\n },\n {\n scope: \"workspace:members\",\n description: \"Manage workspace members\",\n category: \"Workspace\",\n },\n // Project scopes\n {\n scope: \"project:read\",\n description: \"Read project information\",\n category: \"Project\",\n },\n {\n scope: \"project:write\",\n description: \"Create and modify projects\",\n category: \"Project\",\n },\n {\n scope: \"project:delete\",\n description: \"Delete projects\",\n category: \"Project\",\n },\n // Task scopes\n { scope: \"task:read\", description: \"Read tasks\", category: \"Task\" },\n {\n scope: \"task:write\",\n description: \"Create and modify tasks\",\n category: \"Task\",\n },\n { scope: \"task:delete\", description: \"Delete tasks\", category: \"Task\" },\n // File scopes\n { scope: \"file:read\", description: \"Read files\", category: \"File\" },\n {\n scope: \"file:write\",\n description: \"Upload and modify files\",\n category: \"File\",\n },\n { scope: \"file:delete\", description: \"Delete files\", category: \"File\" },\n // Offline access\n {\n scope: \"offline_access\",\n description: \"Access data while user is offline\",\n category: \"Access\",\n },\n] as const;\n"],"mappings":";AAUA,IAAaA,IAA4C;CACvD,OAAO;CACP,WAAW;CACX,WAAW;CACX,UAAU;CACV,WAAW;CACX,UAAU;CACV,WAAW;CACX,YAAY;CACZ,QAAQ;CACR,UAAU;CACV,SAAS;CAET,WAAW;CACX,WAAW;CACX,YAAY;CACZ,YAAY;AACd,GAGaC,IAAgD;CAC3D,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,UAAU;AACZ,GAGaC,IAAiD;CAC5D,SAAS;CACT,YAAY;CACZ,WAAW;CACX,QAAQ;CACR,UAAU;AACZ,GAGaC,IAAmD;CAC9D,SAAS;CACT,UAAU;CACV,UAAU;CACV,SAAS;CACT,WAAW;AACb,GAGaC,IAA0C;CACrD,MAAM;CACN,WAAW;CACX,cAAc;CACd,YAAY;AACd,GAGaC,IAA8C;CACzD,YAAY;CACZ,QAAQ;CACR,SAAS;AACX,GAGaC,IAA0C;CACrD,SAAS;CACT,YAAY;CACZ,aAAa;CACb,UAAU;CACV,iBAAiB;CACjB,UAAU;CACV,QAAQ;CACR,KAAK;CACL,SAAS;CACT,aAAa;CACb,SAAS;CACT,WAAW;CACX,YAAY;CACZ,YAAY;CACZ,QAAQ;CACR,WAAW;AACb,GAmBaC,IAA0C;CACrD,OAAO;CACP,OAAO;CACP,WAAW;CACX,QAAQ;AACV"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * TimeCampus applets in the developer portal (BOFF-11005).
3
+ *
4
+ * Pure helpers for the TimeCampus applets page: manifest text handling, the
5
+ * starter manifest, version bumps and the rules that decide which developer
6
+ * action is available for an applet. The rules mirror wspace-timecampus-svc
7
+ * (the service is still the authority; these only decide which buttons to
8
+ * offer and what to say when one is not available).
9
+ */
10
+ /** Public TimeCampus docs: the manifest reference and the extensibility overview. */
11
+ export declare const TIMECAMPUS_MANIFEST_DOCS_URL = "https://docs.timecampus.com/developers/applet-manifest";
12
+ export declare const TIMECAMPUS_APPLETS_DOCS_URL = "https://docs.timecampus.com/extensibility/applets";
13
+ /** The sample widget the TimeCampus app shell serves (copy it as a starting point). */
14
+ export declare const TIMECAMPUS_SAMPLE_WIDGET_URL = "https://app.timecampus.com/applet-samples/time-summary.html";
15
+ export type ManifestParse = {
16
+ ok: true;
17
+ manifest: Record<string, unknown>;
18
+ } | {
19
+ ok: false;
20
+ error: string;
21
+ };
22
+ /** Parse the manifest editor's text into a JSON object. */
23
+ export declare function parseManifestText(text: string): ManifestParse;
24
+ export declare function manifestText(manifest: unknown): string;
25
+ /** Next patch version of MAJOR.MINOR.PATCH (falls back to 1.0.0). */
26
+ export declare function nextPatchVersion(version: string): string;
27
+ /** The manifest for a new version: the given one with the next patch version. */
28
+ export declare function manifestForNextVersion(manifest: unknown): string;
29
+ /** A working starter manifest that points at the TimeCampus sample widget. */
30
+ export declare function starterManifest(): string;
31
+ /** The bits of an applet the page decides on. */
32
+ export interface AppletActionInput {
33
+ status: string;
34
+ latestVersion: {
35
+ id: string;
36
+ version: string;
37
+ status: string;
38
+ };
39
+ liveVersion?: {
40
+ version: string;
41
+ } | null;
42
+ marketplace?: {
43
+ status: string;
44
+ latestSubmission: {
45
+ version: string;
46
+ status: string;
47
+ };
48
+ liveSubmission?: {
49
+ version: string;
50
+ } | null;
51
+ } | null;
52
+ }
53
+ /** What the developer can do with the applet's latest version right now. */
54
+ export type VersionAction = {
55
+ kind: "submit";
56
+ versionId: string;
57
+ } | {
58
+ kind: "withdraw";
59
+ versionId: string;
60
+ } | {
61
+ kind: "none";
62
+ };
63
+ /**
64
+ * A draft latest version can be submitted for workspace review; one in
65
+ * review can be withdrawn back to a draft. Rejected, published, superseded
66
+ * and suspended versions take no action here: add a new version instead.
67
+ */
68
+ export declare function versionAction(applet: AppletActionInput): VersionAction;
69
+ /** Whether a new version can be added (only when no draft or review is open). */
70
+ export declare function canAddVersion(applet: AppletActionInput): boolean;
71
+ /**
72
+ * Whether the latest version's manifest can be replaced in place. The
73
+ * service accepts edits to a DRAFT or REJECTED version (a rejected one
74
+ * returns to DRAFT); versions in review, live or retired are immutable.
75
+ */
76
+ export declare function canEditVersion(applet: AppletActionInput): boolean;
77
+ /** Compare two MAJOR.MINOR.PATCH versions (non-numeric parts count as 0). */
78
+ export declare function compareVersions(a: string, b: string): number;
79
+ export type MarketplaceOffer = {
80
+ canOffer: true;
81
+ version: string;
82
+ } | {
83
+ canOffer: false;
84
+ reason: string;
85
+ };
86
+ /**
87
+ * Whether the developer can offer the applet's live workspace version to the
88
+ * public marketplace now, and why not otherwise. Mirrors the service rules:
89
+ * only a workspace-published version, one submission in certification at a
90
+ * time, and only a version higher than every certified one.
91
+ */
92
+ export declare function marketplaceOffer(applet: AppletActionInput): MarketplaceOffer;
93
+ /** Whether the latest marketplace submission is still in certification (and can be withdrawn). */
94
+ export declare function canWithdrawFromMarketplace(applet: AppletActionInput): boolean;
95
+ /** A readable date for an ISO timestamp, or the raw value when it cannot be parsed. */
96
+ export declare function formatDate(iso: string): string;
97
+ /** A short, user-facing message for a failed request. */
98
+ export declare function errorText(err: unknown): string;
@@ -0,0 +1,130 @@
1
+ // src/devportal/utils/timecampusApplets.ts
2
+ var e = "https://docs.timecampus.com/developers/applet-manifest", t = "https://docs.timecampus.com/extensibility/applets", n = "https://app.timecampus.com/applet-samples/time-summary.html";
3
+ function r(e) {
4
+ if (!e.trim()) return {
5
+ ok: !1,
6
+ error: "Paste or write a manifest."
7
+ };
8
+ let t;
9
+ try {
10
+ t = JSON.parse(e);
11
+ } catch (e) {
12
+ return {
13
+ ok: !1,
14
+ error: `Not valid JSON: ${e instanceof Error ? e.message : "parse error"}`
15
+ };
16
+ }
17
+ return typeof t != "object" || !t || Array.isArray(t) ? {
18
+ ok: !1,
19
+ error: "The manifest must be a JSON object."
20
+ } : {
21
+ ok: !0,
22
+ manifest: t
23
+ };
24
+ }
25
+ function i(e) {
26
+ return JSON.stringify(e, null, 2);
27
+ }
28
+ function a(e) {
29
+ let t = /^(\d+)\.(\d+)\.(\d+)$/.exec(e);
30
+ return t ? `${t[1]}.${t[2]}.${Number(t[3]) + 1}` : "1.0.0";
31
+ }
32
+ function o(e) {
33
+ if (typeof e != "object" || !e) return i(e);
34
+ let t = e, n = typeof t.version == "string" ? t.version : "";
35
+ return i({
36
+ ...t,
37
+ version: a(n)
38
+ });
39
+ }
40
+ function s() {
41
+ return i({
42
+ manifestVersion: 1,
43
+ key: "my-first-applet",
44
+ name: "My first applet",
45
+ version: "1.0.0",
46
+ description: "Shows your tracked time today in a sandboxed widget.",
47
+ icon: "Puzzle",
48
+ category: "ANALYTICS",
49
+ entryPoint: "https://app.timecampus.com/applet-samples/",
50
+ permissions: ["time-summary:read"],
51
+ widgets: [{
52
+ key: "today",
53
+ name: "Tracked today",
54
+ description: "Your tracked time today and this week",
55
+ path: "/applet-samples/time-summary.html",
56
+ height: 220
57
+ }],
58
+ developer: { name: "Your team" }
59
+ });
60
+ }
61
+ function c(e) {
62
+ let t = e.latestVersion;
63
+ return t.status === "DRAFT" ? {
64
+ kind: "submit",
65
+ versionId: t.id
66
+ } : t.status === "IN_REVIEW" ? {
67
+ kind: "withdraw",
68
+ versionId: t.id
69
+ } : { kind: "none" };
70
+ }
71
+ function l(e) {
72
+ let t = e.latestVersion.status;
73
+ return t !== "DRAFT" && t !== "IN_REVIEW";
74
+ }
75
+ function u(e) {
76
+ let t = e.latestVersion.status;
77
+ return t === "DRAFT" || t === "REJECTED";
78
+ }
79
+ function d(e, t) {
80
+ let n = e.split(".").map((e) => Number(e) || 0), r = t.split(".").map((e) => Number(e) || 0);
81
+ for (let e = 0; e < 3; e += 1) {
82
+ let t = (n[e] ?? 0) - (r[e] ?? 0);
83
+ if (t !== 0) return t;
84
+ }
85
+ return 0;
86
+ }
87
+ var f = /* @__PURE__ */ new Set(["CERTIFIED", "SUPERSEDED"]);
88
+ function p(e) {
89
+ if (!e) return null;
90
+ let t = [];
91
+ return e.liveSubmission && t.push(e.liveSubmission.version), f.has(e.latestSubmission.status) && t.push(e.latestSubmission.version), t.reduce((e, t) => e === null || d(t, e) > 0 ? t : e, null);
92
+ }
93
+ function m(e) {
94
+ let t = e.liveVersion;
95
+ if (e.status !== "PUBLISHED" || !t) return {
96
+ canOffer: !1,
97
+ reason: "Publish a version in your workspace first."
98
+ };
99
+ let n = e.marketplace;
100
+ if (n?.latestSubmission.status === "IN_REVIEW") return {
101
+ canOffer: !1,
102
+ reason: `v${n.latestSubmission.version} is waiting for platform certification.`
103
+ };
104
+ let r = p(n);
105
+ return r !== null && d(t.version, r) <= 0 ? {
106
+ canOffer: !1,
107
+ reason: `v${r} is already certified. Publish a newer version to offer it.`
108
+ } : {
109
+ canOffer: !0,
110
+ version: t.version
111
+ };
112
+ }
113
+ function h(e) {
114
+ return e.marketplace?.latestSubmission.status === "IN_REVIEW";
115
+ }
116
+ function g(e) {
117
+ let t = new Date(e);
118
+ return Number.isNaN(t.getTime()) ? e : t.toLocaleDateString(void 0, {
119
+ year: "numeric",
120
+ month: "short",
121
+ day: "numeric"
122
+ });
123
+ }
124
+ function _(e) {
125
+ let t = e instanceof Error ? e.message : "";
126
+ return /forbidden|permission|not authori[sz]ed/i.test(t) ? "You do not have permission to do that in this workspace." : t || "Something went wrong";
127
+ }
128
+ export { t as TIMECAMPUS_APPLETS_DOCS_URL, e as TIMECAMPUS_MANIFEST_DOCS_URL, n as TIMECAMPUS_SAMPLE_WIDGET_URL, l as canAddVersion, u as canEditVersion, h as canWithdrawFromMarketplace, d as compareVersions, _ as errorText, g as formatDate, o as manifestForNextVersion, i as manifestText, m as marketplaceOffer, a as nextPatchVersion, r as parseManifestText, s as starterManifest, c as versionAction };
129
+
130
+ //# sourceMappingURL=timecampusApplets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timecampusApplets.js","names":["TIMECAMPUS_MANIFEST_DOCS_URL","TIMECAMPUS_APPLETS_DOCS_URL","TIMECAMPUS_SAMPLE_WIDGET_URL","parseManifestText","text","value","err","manifestText","manifest","nextPatchVersion","match","version","manifestForNextVersion","current","starterManifest","versionAction","latest","applet","canAddVersion","status","canEditVersion","compareVersions","left","a","part","right","b","i","diff","CERTIFIED_STATUSES","highestCertifiedVersion","listing","versions","top","marketplaceOffer","live","certified","canWithdrawFromMarketplace","formatDate","date","iso","errorText","message"],"sources":["../../../src/devportal/utils/timecampusApplets.ts"],"sourcesContent":["/**\n * TimeCampus applets in the developer portal (BOFF-11005).\n *\n * Pure helpers for the TimeCampus applets page: manifest text handling, the\n * starter manifest, version bumps and the rules that decide which developer\n * action is available for an applet. The rules mirror wspace-timecampus-svc\n * (the service is still the authority; these only decide which buttons to\n * offer and what to say when one is not available).\n */\n\n/** Public TimeCampus docs: the manifest reference and the extensibility overview. */\nexport const TIMECAMPUS_MANIFEST_DOCS_URL =\n \"https://docs.timecampus.com/developers/applet-manifest\";\nexport const TIMECAMPUS_APPLETS_DOCS_URL =\n \"https://docs.timecampus.com/extensibility/applets\";\n/** The sample widget the TimeCampus app shell serves (copy it as a starting point). */\nexport const TIMECAMPUS_SAMPLE_WIDGET_URL =\n \"https://app.timecampus.com/applet-samples/time-summary.html\";\nconst SAMPLE_ENTRY_POINT = \"https://app.timecampus.com/applet-samples/\";\n\nexport type ManifestParse =\n | { ok: true; manifest: Record<string, unknown> }\n | { ok: false; error: string };\n\n/** Parse the manifest editor's text into a JSON object. */\nexport function parseManifestText(text: string): ManifestParse {\n if (!text.trim()) return { ok: false, error: \"Paste or write a manifest.\" };\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch (err) {\n return {\n ok: false,\n error: `Not valid JSON: ${err instanceof Error ? err.message : \"parse error\"}`,\n };\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return { ok: false, error: \"The manifest must be a JSON object.\" };\n }\n return { ok: true, manifest: value as Record<string, unknown> };\n}\n\nexport function manifestText(manifest: unknown): string {\n return JSON.stringify(manifest, null, 2);\n}\n\n/** Next patch version of MAJOR.MINOR.PATCH (falls back to 1.0.0). */\nexport function nextPatchVersion(version: string): string {\n const match = /^(\\d+)\\.(\\d+)\\.(\\d+)$/.exec(version);\n if (!match) return \"1.0.0\";\n return `${match[1]}.${match[2]}.${Number(match[3]) + 1}`;\n}\n\n/** The manifest for a new version: the given one with the next patch version. */\nexport function manifestForNextVersion(manifest: unknown): string {\n if (typeof manifest !== \"object\" || manifest === null) {\n return manifestText(manifest);\n }\n const current = manifest as Record<string, unknown>;\n const version = typeof current.version === \"string\" ? current.version : \"\";\n return manifestText({ ...current, version: nextPatchVersion(version) });\n}\n\n/** A working starter manifest that points at the TimeCampus sample widget. */\nexport function starterManifest(): string {\n return manifestText({\n manifestVersion: 1,\n key: \"my-first-applet\",\n name: \"My first applet\",\n version: \"1.0.0\",\n description: \"Shows your tracked time today in a sandboxed widget.\",\n icon: \"Puzzle\",\n category: \"ANALYTICS\",\n entryPoint: SAMPLE_ENTRY_POINT,\n permissions: [\"time-summary:read\"],\n widgets: [\n {\n key: \"today\",\n name: \"Tracked today\",\n description: \"Your tracked time today and this week\",\n path: \"/applet-samples/time-summary.html\",\n height: 220,\n },\n ],\n developer: { name: \"Your team\" },\n });\n}\n\n/** The bits of an applet the page decides on. */\nexport interface AppletActionInput {\n status: string;\n latestVersion: { id: string; version: string; status: string };\n liveVersion?: { version: string } | null;\n marketplace?: {\n status: string;\n latestSubmission: { version: string; status: string };\n liveSubmission?: { version: string } | null;\n } | null;\n}\n\n/** What the developer can do with the applet's latest version right now. */\nexport type VersionAction =\n | { kind: \"submit\"; versionId: string }\n | { kind: \"withdraw\"; versionId: string }\n | { kind: \"none\" };\n\n/**\n * A draft latest version can be submitted for workspace review; one in\n * review can be withdrawn back to a draft. Rejected, published, superseded\n * and suspended versions take no action here: add a new version instead.\n */\nexport function versionAction(applet: AppletActionInput): VersionAction {\n const latest = applet.latestVersion;\n if (latest.status === \"DRAFT\") {\n return { kind: \"submit\", versionId: latest.id };\n }\n if (latest.status === \"IN_REVIEW\") {\n return { kind: \"withdraw\", versionId: latest.id };\n }\n return { kind: \"none\" };\n}\n\n/** Whether a new version can be added (only when no draft or review is open). */\nexport function canAddVersion(applet: AppletActionInput): boolean {\n const status = applet.latestVersion.status;\n return status !== \"DRAFT\" && status !== \"IN_REVIEW\";\n}\n\n/**\n * Whether the latest version's manifest can be replaced in place. The\n * service accepts edits to a DRAFT or REJECTED version (a rejected one\n * returns to DRAFT); versions in review, live or retired are immutable.\n */\nexport function canEditVersion(applet: AppletActionInput): boolean {\n const status = applet.latestVersion.status;\n return status === \"DRAFT\" || status === \"REJECTED\";\n}\n\n/** Compare two MAJOR.MINOR.PATCH versions (non-numeric parts count as 0). */\nexport function compareVersions(a: string, b: string): number {\n const left = a.split(\".\").map((part) => Number(part) || 0);\n const right = b.split(\".\").map((part) => Number(part) || 0);\n for (let i = 0; i < 3; i += 1) {\n const diff = (left[i] ?? 0) - (right[i] ?? 0);\n if (diff !== 0) return diff;\n }\n return 0;\n}\n\nconst CERTIFIED_STATUSES = new Set([\"CERTIFIED\", \"SUPERSEDED\"]);\n\n/** The highest certified version the page can see (the live and latest submissions). */\nfunction highestCertifiedVersion(\n listing: AppletActionInput[\"marketplace\"],\n): string | null {\n if (!listing) return null;\n const versions: string[] = [];\n if (listing.liveSubmission) versions.push(listing.liveSubmission.version);\n if (CERTIFIED_STATUSES.has(listing.latestSubmission.status)) {\n versions.push(listing.latestSubmission.version);\n }\n return versions.reduce<string | null>(\n (top, version) =>\n top === null || compareVersions(version, top) > 0 ? version : top,\n null,\n );\n}\n\nexport type MarketplaceOffer =\n { canOffer: true; version: string } | { canOffer: false; reason: string };\n\n/**\n * Whether the developer can offer the applet's live workspace version to the\n * public marketplace now, and why not otherwise. Mirrors the service rules:\n * only a workspace-published version, one submission in certification at a\n * time, and only a version higher than every certified one.\n */\nexport function marketplaceOffer(applet: AppletActionInput): MarketplaceOffer {\n const live = applet.liveVersion;\n if (applet.status !== \"PUBLISHED\" || !live) {\n return {\n canOffer: false,\n reason: \"Publish a version in your workspace first.\",\n };\n }\n const listing = applet.marketplace;\n if (listing?.latestSubmission.status === \"IN_REVIEW\") {\n return {\n canOffer: false,\n reason: `v${listing.latestSubmission.version} is waiting for platform certification.`,\n };\n }\n const certified = highestCertifiedVersion(listing);\n if (certified !== null && compareVersions(live.version, certified) <= 0) {\n return {\n canOffer: false,\n reason: `v${certified} is already certified. Publish a newer version to offer it.`,\n };\n }\n return { canOffer: true, version: live.version };\n}\n\n/** Whether the latest marketplace submission is still in certification (and can be withdrawn). */\nexport function canWithdrawFromMarketplace(applet: AppletActionInput): boolean {\n return applet.marketplace?.latestSubmission.status === \"IN_REVIEW\";\n}\n\n/** A readable date for an ISO timestamp, or the raw value when it cannot be parsed. */\nexport function formatDate(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return date.toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\n/** A short, user-facing message for a failed request. */\nexport function errorText(err: unknown): string {\n const message = err instanceof Error ? err.message : \"\";\n if (/forbidden|permission|not authori[sz]ed/i.test(message)) {\n return \"You do not have permission to do that in this workspace.\";\n }\n return message || \"Something went wrong\";\n}\n"],"mappings":"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"}
@@ -69,7 +69,10 @@ export type CreateApplicationInput = {
69
69
  appId?: string | number | null | undefined;
70
70
  appType: AppType;
71
71
  category?: string | null | undefined;
72
- /** Which products this item is compatible with (e.g. "fluidgrids", "workspaces"). Stored in manifest.compatibility.products and extracted to the store on publish. */
72
+ /**
73
+ * Which products this item is compatible with (e.g. "fluidgrids", "workspaces").
74
+ * Stored in manifest.compatibility.products and extracted to the store on publish.
75
+ */
73
76
  compatibleProducts?: Array<string> | null | undefined;
74
77
  description?: string | null | undefined;
75
78
  developerOrganizationId?: string | number | null | undefined;
@@ -133,7 +136,12 @@ export type CreateDeveloperOrganizationInput = {
133
136
  logoUrl?: string | null | undefined;
134
137
  metadata?: Record<string, unknown> | null | undefined;
135
138
  name: string;
136
- /** Optional at creation — dedicated pickup pincode for carrier rate quoting on physical-goods orders (Shiprocket, etc). Only meaningful for createSellerOrganization (PHYSICAL orgs); ignored for DIGITAL orgs. Can always be added or changed later from organization settings. */
139
+ /**
140
+ * Optional at creation — dedicated pickup pincode for carrier rate quoting
141
+ * on physical-goods orders (Shiprocket, etc). Only meaningful for
142
+ * createSellerOrganization (PHYSICAL orgs); ignored for DIGITAL orgs. Can
143
+ * always be added or changed later from organization settings.
144
+ */
137
145
  pickupPostalCode?: string | null | undefined;
138
146
  slug?: string | null | undefined;
139
147
  supportEmail?: string | null | undefined;
@@ -161,7 +169,11 @@ export type CreateWebhookInput = {
161
169
  export type DelegationStatus = 'ACTIVE' | 'EXPIRED' | 'REVOKED';
162
170
  export type DevPortalPaymentMethodType = 'BANK_ACCOUNT' | 'CHECK' | 'PAYPAL' | 'STRIPE_CONNECT' | 'WIRE';
163
171
  export type DevPortalPricingModel = 'ENTERPRISE' | 'FREE' | 'FREEMIUM' | 'ONE_TIME' | 'SUBSCRIPTION' | 'USAGE_BASED';
164
- /** DIGITAL orgs publish Applications to the store; PHYSICAL orgs list physical goods via the seller portal. Not user-selectable — fixed at creation by which flow provisioned the org. See BOFF-7285. */
172
+ /**
173
+ * DIGITAL orgs publish Applications to the store; PHYSICAL orgs list physical
174
+ * goods via the seller portal. Not user-selectable — fixed at creation by which
175
+ * flow provisioned the org. See BOFF-7285.
176
+ */
165
177
  export type DeveloperOrgKind = 'DIGITAL' | 'PHYSICAL';
166
178
  export type DeveloperOrgRole = 'ADMIN' | 'DEVELOPER' | 'OWNER' | 'VIEWER';
167
179
  export type DeveloperOrgTier = 'DEVELOPER' | 'ENTERPRISE' | 'FREE' | 'PROFESSIONAL';
@@ -247,7 +259,10 @@ export type UpdateApplicationInput = {
247
259
  appType?: AppType | null | undefined;
248
260
  bannerUrl?: string | null | undefined;
249
261
  category?: string | null | undefined;
250
- /** Which products this item is compatible with (e.g. "fluidgrids", "workspaces"). Stored in manifest.compatibility.products and extracted to the store on publish. */
262
+ /**
263
+ * Which products this item is compatible with (e.g. "fluidgrids", "workspaces").
264
+ * Stored in manifest.compatibility.products and extracted to the store on publish.
265
+ */
251
266
  compatibleProducts?: Array<string> | null | undefined;
252
267
  config?: Record<string, unknown> | null | undefined;
253
268
  description?: string | null | undefined;
@@ -298,7 +313,12 @@ export type UpdateDeveloperOrganizationInput = {
298
313
  logoUrl?: string | null | undefined;
299
314
  metadata?: Record<string, unknown> | null | undefined;
300
315
  name?: string | null | undefined;
301
- /** Dedicated pickup pincode for carrier rate quoting on physical-goods orders (Shiprocket, etc) — separate from the org's billing address, since a seller's fulfillment/warehouse location isn't necessarily the same place as their billing address. */
316
+ /**
317
+ * Dedicated pickup pincode for carrier rate quoting on physical-goods orders
318
+ * (Shiprocket, etc) — separate from the org's billing address, since a
319
+ * seller's fulfillment/warehouse location isn't necessarily the same place
320
+ * as their billing address.
321
+ */
302
322
  pickupPostalCode?: string | null | undefined;
303
323
  settings?: Record<string, unknown> | null | undefined;
304
324
  supportEmail?: string | null | undefined;