@aglyn/plugins-marketplace 1.0.0-beta.151 → 1.0.0-beta.152
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/plugin-review-detail.component.js +1 -1
- package/src/lib/components/plugin-review-detail.component.js.map +1 -1
- package/src/lib/server/admin-reviews.js +3 -3
- package/src/lib/server/admin-reviews.js.map +1 -1
- package/src/lib/server/admin-trust.d.ts +51 -0
- package/src/lib/server/admin-trust.js +190 -0
- package/src/lib/server/admin-trust.js.map +1 -0
- package/src/lib/server.js +7 -0
- package/src/lib/server.js.map +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
/**
|
|
18
|
+
* Staff trust-signing for realm plugins (AGL-420), served at
|
|
19
|
+
* `/api/marketplace/admin/trust` for this plugin's review queue.
|
|
20
|
+
*
|
|
21
|
+
* It was `apps/console/app/api/admin/sign-plugin/route.ts` until AGL-3080.
|
|
22
|
+
* What moved is everything that is the MARKETPLACE's: `marketplaceListings`
|
|
23
|
+
* is its collection, "a version must have passed review" is its rule, and
|
|
24
|
+
* the fields a grant writes are its documents.
|
|
25
|
+
*
|
|
26
|
+
* ⛔ WHAT DID NOT MOVE IS THE KEY. `PLUGIN_TRUST_PRIVATE_KEY` is deployed to
|
|
27
|
+
* the console and nowhere else — never to a tenant runtime — and this
|
|
28
|
+
* package is published to npm, where a self-hoster generates their own
|
|
29
|
+
* pair. So the signature comes from the shell through
|
|
30
|
+
* `signPluginTrust`, and this route refuses the grant outright when it
|
|
31
|
+
* answers `signed: false`. A `trust: 'realm'` flag written without a
|
|
32
|
+
* signature beside it is the one state the loaders cannot tell from
|
|
33
|
+
* tampering.
|
|
34
|
+
*
|
|
35
|
+
* Granting writes
|
|
36
|
+
* `{trust: 'realm', signature}` onto the listing's version doc, where the
|
|
37
|
+
* signature is the platform Ed25519 key's signature over the version's
|
|
38
|
+
* sha256 hex — the loaders (client blob-import + env-gated server import)
|
|
39
|
+
* verify it against `PLUGIN_TRUST_PUBLIC_KEY` before a byte executes.
|
|
40
|
+
* Super staff only: a realm grant lets marketplace code run in the app
|
|
41
|
+
* realm of every workspace that installs it, the largest blast radius any
|
|
42
|
+
* staff action has. Revoking removes the grant (already-loaded realms
|
|
43
|
+
* pick it up on next load; use `revocations/{listingId}` for the hard
|
|
44
|
+
* kill switch).
|
|
45
|
+
*
|
|
46
|
+
* `PLUGIN_TRUST_PRIVATE_KEY` is the base64 PKCS8 DER Ed25519 private key
|
|
47
|
+
* (pair generated by `tools/scripts/generate-plugin-trust-key.mjs`) —
|
|
48
|
+
* deployed ONLY to the console app, never to tenant runtimes.
|
|
49
|
+
*/
|
|
50
|
+
declare function handler(request: Request): Promise<Response>;
|
|
51
|
+
export { handler as marketplaceAdminTrust };
|
|
@@ -0,0 +1,190 @@
|
|
|
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
|
+
*/ import { pluginRequestFromWeb } from "@aglyn/aglyn/server";
|
|
17
|
+
import { signPluginTrust } from "@aglyn/aglyn/plugin-manager/plugin-trust-signing";
|
|
18
|
+
import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession } from "@aglyn/tenant-data-admin";
|
|
19
|
+
import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
|
|
20
|
+
import { FieldValue } from "firebase-admin/firestore";
|
|
21
|
+
/**
|
|
22
|
+
* Staff trust-signing for realm plugins (AGL-420), served at
|
|
23
|
+
* `/api/marketplace/admin/trust` for this plugin's review queue.
|
|
24
|
+
*
|
|
25
|
+
* It was `apps/console/app/api/admin/sign-plugin/route.ts` until AGL-3080.
|
|
26
|
+
* What moved is everything that is the MARKETPLACE's: `marketplaceListings`
|
|
27
|
+
* is its collection, "a version must have passed review" is its rule, and
|
|
28
|
+
* the fields a grant writes are its documents.
|
|
29
|
+
*
|
|
30
|
+
* ⛔ WHAT DID NOT MOVE IS THE KEY. `PLUGIN_TRUST_PRIVATE_KEY` is deployed to
|
|
31
|
+
* the console and nowhere else — never to a tenant runtime — and this
|
|
32
|
+
* package is published to npm, where a self-hoster generates their own
|
|
33
|
+
* pair. So the signature comes from the shell through
|
|
34
|
+
* `signPluginTrust`, and this route refuses the grant outright when it
|
|
35
|
+
* answers `signed: false`. A `trust: 'realm'` flag written without a
|
|
36
|
+
* signature beside it is the one state the loaders cannot tell from
|
|
37
|
+
* tampering.
|
|
38
|
+
*
|
|
39
|
+
* Granting writes
|
|
40
|
+
* `{trust: 'realm', signature}` onto the listing's version doc, where the
|
|
41
|
+
* signature is the platform Ed25519 key's signature over the version's
|
|
42
|
+
* sha256 hex — the loaders (client blob-import + env-gated server import)
|
|
43
|
+
* verify it against `PLUGIN_TRUST_PUBLIC_KEY` before a byte executes.
|
|
44
|
+
* Super staff only: a realm grant lets marketplace code run in the app
|
|
45
|
+
* realm of every workspace that installs it, the largest blast radius any
|
|
46
|
+
* staff action has. Revoking removes the grant (already-loaded realms
|
|
47
|
+
* pick it up on next load; use `revocations/{listingId}` for the hard
|
|
48
|
+
* kill switch).
|
|
49
|
+
*
|
|
50
|
+
* `PLUGIN_TRUST_PRIVATE_KEY` is the base64 PKCS8 DER Ed25519 private key
|
|
51
|
+
* (pair generated by `tools/scripts/generate-plugin-trust-key.mjs`) —
|
|
52
|
+
* deployed ONLY to the console app, never to tenant runtimes.
|
|
53
|
+
*/ async function handler(request) {
|
|
54
|
+
var _headers_authorization;
|
|
55
|
+
const { method, body, headers: rawHeaders } = await pluginRequestFromWeb(request);
|
|
56
|
+
const headers = rawHeaders;
|
|
57
|
+
if (method !== 'POST') {
|
|
58
|
+
return Response.json({
|
|
59
|
+
error: 'Method not allowed'
|
|
60
|
+
}, {
|
|
61
|
+
status: 405
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const authorization = (_headers_authorization = headers.authorization) != null ? _headers_authorization : '';
|
|
65
|
+
const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
|
|
66
|
+
if (!idToken) return Response.json({
|
|
67
|
+
error: 'Unauthenticated'
|
|
68
|
+
}, {
|
|
69
|
+
status: 401
|
|
70
|
+
});
|
|
71
|
+
try {
|
|
72
|
+
var _decoded_staffRole, _ref, _ref1;
|
|
73
|
+
const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
|
|
74
|
+
if (!decoded.email_verified && !isImpersonationSession(decoded)) {
|
|
75
|
+
return emailUnverifiedResponse();
|
|
76
|
+
}
|
|
77
|
+
if (!decoded['staff']) {
|
|
78
|
+
return Response.json({
|
|
79
|
+
error: 'Staff only'
|
|
80
|
+
}, {
|
|
81
|
+
status: 403
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (String((_decoded_staffRole = decoded['staffRole']) != null ? _decoded_staffRole : 'support') !== 'super') {
|
|
85
|
+
return Response.json({
|
|
86
|
+
error: 'Requires the super staff role'
|
|
87
|
+
}, {
|
|
88
|
+
status: 403
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const listingId = String((_ref = body == null ? void 0 : body.listingId) != null ? _ref : '');
|
|
92
|
+
const version = String((_ref1 = body == null ? void 0 : body.version) != null ? _ref1 : '');
|
|
93
|
+
const action = (body == null ? void 0 : body.action) === 'revoke' ? 'revoke' : 'grant';
|
|
94
|
+
if (!listingId || !version) {
|
|
95
|
+
return Response.json({
|
|
96
|
+
error: 'Missing listingId or version'
|
|
97
|
+
}, {
|
|
98
|
+
status: 400
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
const versionRef = firebaseAdmin.app().firestore().collection('marketplaceListings').doc(listingId).collection('pluginVersions').doc(version);
|
|
102
|
+
const snapshot = await versionRef.get();
|
|
103
|
+
const sha256 = snapshot.get('sha256');
|
|
104
|
+
if (typeof sha256 !== 'string' || !sha256) {
|
|
105
|
+
return Response.json({
|
|
106
|
+
error: 'Unknown plugin version'
|
|
107
|
+
}, {
|
|
108
|
+
status: 404
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Realm trust is the strongest grant in the platform — it drops a
|
|
112
|
+
// bundle into the app realm, where the sandbox iframe and the manifest
|
|
113
|
+
// CSP no longer stand between it and user data. It cannot be granted to
|
|
114
|
+
// bytes that have not passed review (AGL-966).
|
|
115
|
+
if (action === 'grant' && snapshot.get('reviewState') !== 'approved') {
|
|
116
|
+
var _snapshot_get;
|
|
117
|
+
return Response.json({
|
|
118
|
+
error: 'That version has not passed review — approve it before granting realm trust',
|
|
119
|
+
reviewState: (_snapshot_get = snapshot.get('reviewState')) != null ? _snapshot_get : 'unknown'
|
|
120
|
+
}, {
|
|
121
|
+
status: 409
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (action === 'grant') {
|
|
125
|
+
/*
|
|
126
|
+
* The shell signs; this decides what is worth signing. A refusal here
|
|
127
|
+
* is final — nothing is written, and the 501 is the same answer an
|
|
128
|
+
* unconfigured deployment has always given, now reached through the
|
|
129
|
+
* contract rather than by reading the key.
|
|
130
|
+
*/ const { signed, signature, reason } = await signPluginTrust(sha256);
|
|
131
|
+
if (!signed || !signature) {
|
|
132
|
+
return Response.json({
|
|
133
|
+
error: reason != null ? reason : 'Trust signing is not configured (missing PLUGIN_TRUST_PRIVATE_KEY)'
|
|
134
|
+
}, {
|
|
135
|
+
status: 501
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
await versionRef.set({
|
|
139
|
+
trust: 'realm',
|
|
140
|
+
signature,
|
|
141
|
+
trustGrantedBy: decoded.uid,
|
|
142
|
+
trustGrantedAt: FieldValue.serverTimestamp()
|
|
143
|
+
}, {
|
|
144
|
+
merge: true
|
|
145
|
+
});
|
|
146
|
+
} else {
|
|
147
|
+
await versionRef.set({
|
|
148
|
+
trust: FieldValue.delete(),
|
|
149
|
+
signature: FieldValue.delete(),
|
|
150
|
+
trustGrantedBy: FieldValue.delete(),
|
|
151
|
+
trustGrantedAt: FieldValue.delete()
|
|
152
|
+
}, {
|
|
153
|
+
merge: true
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
await firebaseAdmin.app().firestore().collection('adminAudit').add({
|
|
157
|
+
actorUid: decoded.uid,
|
|
158
|
+
action: `plugins.trust.${action}`,
|
|
159
|
+
target: `marketplaceListings/${listingId}/pluginVersions/${version}`,
|
|
160
|
+
after: action === 'grant' ? {
|
|
161
|
+
trust: 'realm'
|
|
162
|
+
} : {
|
|
163
|
+
trust: null
|
|
164
|
+
},
|
|
165
|
+
at: FieldValue.serverTimestamp()
|
|
166
|
+
});
|
|
167
|
+
return Response.json({
|
|
168
|
+
ok: true,
|
|
169
|
+
action,
|
|
170
|
+
listingId,
|
|
171
|
+
version
|
|
172
|
+
}, {
|
|
173
|
+
status: 200
|
|
174
|
+
});
|
|
175
|
+
} catch (error) {
|
|
176
|
+
// An unverifiable credential is a 401, not a fault of ours
|
|
177
|
+
// (AGL-1993). Null for anything else, so a real failure keeps its 500.
|
|
178
|
+
const unauthenticated = invalidIdTokenResponse(error);
|
|
179
|
+
if (unauthenticated) return unauthenticated;
|
|
180
|
+
console.error(error);
|
|
181
|
+
return Response.json({
|
|
182
|
+
error: 'Trust signing failed'
|
|
183
|
+
}, {
|
|
184
|
+
status: 500
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export { handler as marketplaceAdminTrust };
|
|
189
|
+
|
|
190
|
+
//# sourceMappingURL=admin-trust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/marketplace/src/lib/server/admin-trust.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { pluginRequestFromWeb } from '@aglyn/aglyn/server'\nimport { signPluginTrust } from '@aglyn/aglyn/plugin-manager/plugin-trust-signing'\nimport {\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n} from '@aglyn/tenant-data-admin'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport { FieldValue } from 'firebase-admin/firestore'\n\n/**\n * Staff trust-signing for realm plugins (AGL-420), served at\n * `/api/marketplace/admin/trust` for this plugin's review queue.\n *\n * It was `apps/console/app/api/admin/sign-plugin/route.ts` until AGL-3080.\n * What moved is everything that is the MARKETPLACE's: `marketplaceListings`\n * is its collection, \"a version must have passed review\" is its rule, and\n * the fields a grant writes are its documents.\n *\n * ⛔ WHAT DID NOT MOVE IS THE KEY. `PLUGIN_TRUST_PRIVATE_KEY` is deployed to\n * the console and nowhere else — never to a tenant runtime — and this\n * package is published to npm, where a self-hoster generates their own\n * pair. So the signature comes from the shell through\n * `signPluginTrust`, and this route refuses the grant outright when it\n * answers `signed: false`. A `trust: 'realm'` flag written without a\n * signature beside it is the one state the loaders cannot tell from\n * tampering.\n *\n * Granting writes\n * `{trust: 'realm', signature}` onto the listing's version doc, where the\n * signature is the platform Ed25519 key's signature over the version's\n * sha256 hex — the loaders (client blob-import + env-gated server import)\n * verify it against `PLUGIN_TRUST_PUBLIC_KEY` before a byte executes.\n * Super staff only: a realm grant lets marketplace code run in the app\n * realm of every workspace that installs it, the largest blast radius any\n * staff action has. Revoking removes the grant (already-loaded realms\n * pick it up on next load; use `revocations/{listingId}` for the hard\n * kill switch).\n *\n * `PLUGIN_TRUST_PRIVATE_KEY` is the base64 PKCS8 DER Ed25519 private key\n * (pair generated by `tools/scripts/generate-plugin-trust-key.mjs`) —\n * deployed ONLY to the console app, never to tenant runtimes.\n */\nasync function handler(request: Request): Promise<Response> {\n const { method, body, headers: rawHeaders } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n if (method !== 'POST') {\n return Response.json({ error: 'Method not allowed' }, { status: 405 })\n }\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ')\n ? authorization.slice('Bearer '.length)\n : undefined\n if (!idToken) return Response.json({ error: 'Unauthenticated' }, { status: 401 })\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) {\n return emailUnverifiedResponse()\n }\n if (!decoded['staff']) {\n return Response.json({ error: 'Staff only' }, { status: 403 })\n }\n if (String(decoded['staffRole'] ?? 'support') !== 'super') {\n return Response.json({ error: 'Requires the super staff role' }, { status: 403 })\n }\n\n const listingId = String(body?.listingId ?? '')\n const version = String(body?.version ?? '')\n const action = body?.action === 'revoke' ? 'revoke' : 'grant'\n if (!listingId || !version) {\n return Response.json({ error: 'Missing listingId or version' }, { status: 400 })\n }\n\n const versionRef = firebaseAdmin\n .app()\n .firestore()\n .collection('marketplaceListings')\n .doc(listingId)\n .collection('pluginVersions')\n .doc(version)\n const snapshot = await versionRef.get()\n const sha256 = snapshot.get('sha256')\n if (typeof sha256 !== 'string' || !sha256) {\n return Response.json({ error: 'Unknown plugin version' }, { status: 404 })\n }\n\n // Realm trust is the strongest grant in the platform — it drops a\n // bundle into the app realm, where the sandbox iframe and the manifest\n // CSP no longer stand between it and user data. It cannot be granted to\n // bytes that have not passed review (AGL-966).\n if (action === 'grant' && snapshot.get('reviewState') !== 'approved') {\n return Response.json(\n {\n error:\n 'That version has not passed review — approve it before granting realm trust',\n reviewState: snapshot.get('reviewState') ?? 'unknown',\n },\n { status: 409 },\n )\n }\n\n if (action === 'grant') {\n /*\n * The shell signs; this decides what is worth signing. A refusal here\n * is final — nothing is written, and the 501 is the same answer an\n * unconfigured deployment has always given, now reached through the\n * contract rather than by reading the key.\n */\n const { signed, signature, reason } = await signPluginTrust(sha256)\n if (!signed || !signature) {\n return Response.json(\n {\n error:\n reason ??\n 'Trust signing is not configured (missing PLUGIN_TRUST_PRIVATE_KEY)',\n },\n { status: 501 },\n )\n }\n await versionRef.set(\n {\n trust: 'realm',\n signature,\n trustGrantedBy: decoded.uid,\n trustGrantedAt: FieldValue.serverTimestamp(),\n },\n { merge: true },\n )\n } else {\n await versionRef.set(\n {\n trust: FieldValue.delete(),\n signature: FieldValue.delete(),\n trustGrantedBy: FieldValue.delete(),\n trustGrantedAt: FieldValue.delete(),\n },\n { merge: true },\n )\n }\n\n await firebaseAdmin\n .app()\n .firestore()\n .collection('adminAudit')\n .add({\n actorUid: decoded.uid,\n action: `plugins.trust.${action}`,\n target: `marketplaceListings/${listingId}/pluginVersions/${version}`,\n after: action === 'grant' ? { trust: 'realm' } : { trust: null },\n at: FieldValue.serverTimestamp(),\n })\n\n return Response.json({ ok: true, action, listingId, version }, { status: 200 })\n } catch (error) {\n // An unverifiable credential is a 401, not a fault of ours\n // (AGL-1993). Null for anything else, so a real failure keeps its 500.\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error(error)\n return Response.json({ error: 'Trust signing failed' }, { status: 500 })\n }\n}\n\nexport { handler as marketplaceAdminTrust }\n"],"names":["pluginRequestFromWeb","signPluginTrust","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","invalidIdTokenResponse","FieldValue","handler","request","headers","method","body","rawHeaders","Response","json","error","status","authorization","idToken","startsWith","slice","length","undefined","decoded","app","auth","verifyIdToken","email_verified","String","listingId","version","action","versionRef","firestore","collection","doc","snapshot","get","sha256","reviewState","signed","signature","reason","set","trust","trustGrantedBy","uid","trustGrantedAt","serverTimestamp","merge","delete","add","actorUid","target","after","at","ok","unauthenticated","console","marketplaceAdminTrust"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,oBAAoB,QAAQ,sBAAqB;AAC1D,SAASC,eAAe,QAAQ,mDAAkD;AAClF,SACEC,uBAAuB,EACvBC,aAAa,EACbC,sBAAsB,QACjB,2BAA0B;AACjC,SAASC,sBAAsB,QAAQ,mDAAkD;AACzF,SAASC,UAAU,QAAQ,2BAA0B;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCC,GACD,eAAeC,QAAQC,OAAgB;QAMfC;IALtB,MAAM,EAAEC,MAAM,EAAEC,IAAI,EAAEF,SAASG,UAAU,EAAE,GAAG,MAAMZ,qBAAqBQ;IACzE,MAAMC,UAAUG;IAChB,IAAIF,WAAW,QAAQ;QACrB,OAAOG,SAASC,IAAI,CAAC;YAAEC,OAAO;QAAqB,GAAG;YAAEC,QAAQ;QAAI;IACtE;IACA,MAAMC,iBAAgBR,yBAAAA,QAAQQ,aAAa,YAArBR,yBAAyB;IAC/C,MAAMS,UAAUD,cAAcE,UAAU,CAAC,aACrCF,cAAcG,KAAK,CAAC,UAAUC,MAAM,IACpCC;IACJ,IAAI,CAACJ,SAAS,OAAOL,SAASC,IAAI,CAAC;QAAEC,OAAO;IAAkB,GAAG;QAAEC,QAAQ;IAAI;IAE/E,IAAI;YAQSO;QAPX,MAAMA,UAAU,MAAMpB,cAAcqB,GAAG,GAAGC,IAAI,GAAGC,aAAa,CAACR;QAC/D,IAAI,CAACK,QAAQI,cAAc,IAAI,CAACvB,uBAAuBmB,UAAU;YAC/D,OAAOrB;QACT;QACA,IAAI,CAACqB,OAAO,CAAC,QAAQ,EAAE;YACrB,OAAOV,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAAa,GAAG;gBAAEC,QAAQ;YAAI;QAC9D;QACA,IAAIY,QAAOL,qBAAAA,OAAO,CAAC,YAAY,YAApBA,qBAAwB,eAAe,SAAS;YACzD,OAAOV,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAAgC,GAAG;gBAAEC,QAAQ;YAAI;QACjF;QAEA,MAAMa,YAAYD,eAAOjB,wBAAAA,KAAMkB,SAAS,mBAAI;QAC5C,MAAMC,UAAUF,gBAAOjB,wBAAAA,KAAMmB,OAAO,oBAAI;QACxC,MAAMC,SAASpB,CAAAA,wBAAAA,KAAMoB,MAAM,MAAK,WAAW,WAAW;QACtD,IAAI,CAACF,aAAa,CAACC,SAAS;YAC1B,OAAOjB,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAA+B,GAAG;gBAAEC,QAAQ;YAAI;QAChF;QAEA,MAAMgB,aAAa7B,cAChBqB,GAAG,GACHS,SAAS,GACTC,UAAU,CAAC,uBACXC,GAAG,CAACN,WACJK,UAAU,CAAC,kBACXC,GAAG,CAACL;QACP,MAAMM,WAAW,MAAMJ,WAAWK,GAAG;QACrC,MAAMC,SAASF,SAASC,GAAG,CAAC;QAC5B,IAAI,OAAOC,WAAW,YAAY,CAACA,QAAQ;YACzC,OAAOzB,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAAyB,GAAG;gBAAEC,QAAQ;YAAI;QAC1E;QAEA,kEAAkE;QAClE,uEAAuE;QACvE,wEAAwE;QACxE,+CAA+C;QAC/C,IAAIe,WAAW,WAAWK,SAASC,GAAG,CAAC,mBAAmB,YAAY;gBAKnDD;YAJjB,OAAOvB,SAASC,IAAI,CAClB;gBACEC,OACE;gBACFwB,WAAW,GAAEH,gBAAAA,SAASC,GAAG,CAAC,0BAAbD,gBAA+B;YAC9C,GACA;gBAAEpB,QAAQ;YAAI;QAElB;QAEA,IAAIe,WAAW,SAAS;YACtB;;;;;OAKC,GACD,MAAM,EAAES,MAAM,EAAEC,SAAS,EAAEC,MAAM,EAAE,GAAG,MAAMzC,gBAAgBqC;YAC5D,IAAI,CAACE,UAAU,CAACC,WAAW;gBACzB,OAAO5B,SAASC,IAAI,CAClB;oBACEC,KAAK,EACH2B,iBAAAA,SACA;gBACJ,GACA;oBAAE1B,QAAQ;gBAAI;YAElB;YACA,MAAMgB,WAAWW,GAAG,CAClB;gBACEC,OAAO;gBACPH;gBACAI,gBAAgBtB,QAAQuB,GAAG;gBAC3BC,gBAAgBzC,WAAW0C,eAAe;YAC5C,GACA;gBAAEC,OAAO;YAAK;QAElB,OAAO;YACL,MAAMjB,WAAWW,GAAG,CAClB;gBACEC,OAAOtC,WAAW4C,MAAM;gBACxBT,WAAWnC,WAAW4C,MAAM;gBAC5BL,gBAAgBvC,WAAW4C,MAAM;gBACjCH,gBAAgBzC,WAAW4C,MAAM;YACnC,GACA;gBAAED,OAAO;YAAK;QAElB;QAEA,MAAM9C,cACHqB,GAAG,GACHS,SAAS,GACTC,UAAU,CAAC,cACXiB,GAAG,CAAC;YACHC,UAAU7B,QAAQuB,GAAG;YACrBf,QAAQ,CAAC,cAAc,EAAEA,QAAQ;YACjCsB,QAAQ,CAAC,oBAAoB,EAAExB,UAAU,gBAAgB,EAAEC,SAAS;YACpEwB,OAAOvB,WAAW,UAAU;gBAAEa,OAAO;YAAQ,IAAI;gBAAEA,OAAO;YAAK;YAC/DW,IAAIjD,WAAW0C,eAAe;QAChC;QAEF,OAAOnC,SAASC,IAAI,CAAC;YAAE0C,IAAI;YAAMzB;YAAQF;YAAWC;QAAQ,GAAG;YAAEd,QAAQ;QAAI;IAC/E,EAAE,OAAOD,OAAO;QACd,2DAA2D;QAC3D,uEAAuE;QACvE,MAAM0C,kBAAkBpD,uBAAuBU;QAC/C,IAAI0C,iBAAiB,OAAOA;QAC5BC,QAAQ3C,KAAK,CAACA;QACd,OAAOF,SAASC,IAAI,CAAC;YAAEC,OAAO;QAAuB,GAAG;YAAEC,QAAQ;QAAI;IACxE;AACF;AAEA,SAAST,WAAWoD,qBAAqB,GAAE"}
|
package/src/lib/server.js
CHANGED
|
@@ -37,6 +37,7 @@ import { previewImageHandler } from "./server/preview-image.js";
|
|
|
37
37
|
import { publishHandler } from "./server/publish.js";
|
|
38
38
|
import { marketplaceAdminReports } from "./server/admin-reports.js";
|
|
39
39
|
import { marketplaceAdminReviews } from "./server/admin-reviews.js";
|
|
40
|
+
import { marketplaceAdminTrust } from "./server/admin-trust.js";
|
|
40
41
|
import { reportHandler } from "./server/report.js";
|
|
41
42
|
import { reviewsHandler } from "./server/reviews.js";
|
|
42
43
|
import { publisherProfileSaveHandler } from "./server/publisher-profile-save.js";
|
|
@@ -124,6 +125,12 @@ import { updateArtifactHandler } from "./server/update-artifact.js";
|
|
|
124
125
|
registerPluginApiRoute('marketplace/admin/reviews', {
|
|
125
126
|
web: marketplaceAdminReviews
|
|
126
127
|
});
|
|
128
|
+
// Realm trust (AGL-420, moved by AGL-3080). Super-staff only, and the
|
|
129
|
+
// SIGNATURE comes from the shell — the key is the console's and stays
|
|
130
|
+
// there. See `server/admin-trust.ts`.
|
|
131
|
+
registerPluginApiRoute('marketplace/admin/trust', {
|
|
132
|
+
web: marketplaceAdminTrust
|
|
133
|
+
});
|
|
127
134
|
registerPluginApiRoute('marketplace/reviews', reviewsHandler);
|
|
128
135
|
registerPluginApiRoute('marketplace/publisher-profile', publisherProfileSaveHandler);
|
|
129
136
|
registerPluginApiRoute('marketplace/verification-request', verificationRequestHandler);
|
package/src/lib/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n registerBillingWebhookHandler,\n registerPluginApiRoute,\n registerCustomFieldType,\n} from '@aglyn/aglyn/server'\n// Its own subpath, never the plugin-manager barrel: what a published page\n// does not need, it must not import.\nimport { registerPluginRouteMetadata } from '@aglyn/aglyn/plugin-manager/plugin-route-metadata'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { marketplaceBillingWebhookHandler } from './server/billing-webhook'\nimport { publishPluginHandler } from './server/publish-plugin'\nimport { verificationRequestHandler } from './server/verification-request'\nimport { checkoutHandler } from './server/checkout'\nimport { connectHandler } from './server/connect'\nimport { installHandler } from './server/install'\nimport { installPluginHandler } from './server/install-plugin'\nimport { listingVersionsHandler } from './server/listing-versions'\nimport { RATING_FIELD } from './model/rating-field'\nimport { installDatasetSchemaHandler } from './server/install-dataset-schema'\nimport { installEmailStarterHandler } from './server/install-email-starter'\nimport { installEmailTemplateHandler } from './server/install-email-template'\nimport { installLayoutHandler } from './server/install-layout'\nimport { installTemplateHandler } from './server/install-template'\nimport { installThemeHandler } from './server/install-theme'\nimport { previewImageHandler } from './server/preview-image'\nimport { publishHandler } from './server/publish'\nimport { marketplaceAdminReports } from './server/admin-reports'\nimport { marketplaceAdminReviews } from './server/admin-reviews'\nimport { reportHandler } from './server/report'\nimport { reviewsHandler } from './server/reviews'\nimport { publisherProfileSaveHandler } from './server/publisher-profile-save'\nimport { publishDatasetSchemaHandler } from './server/publish-dataset-schema'\nimport { publishEmailStarterHandler } from './server/publish-email-starter'\nimport { publishEmailTemplateHandler } from './server/publish-email-template'\nimport { publishLayoutHandler } from './server/publish-layout'\nimport { publishTemplateHandler } from './server/publish-template'\nimport { publishThemeHandler } from './server/publish-theme'\nimport { updateArtifactHandler } from './server/update-artifact'\n\n/**\n * Registers the marketplace plugin's console-side API routes (AGL-396):\n * marketplace publish/install of templates and plugins, and the Stripe\n * Connect + checkout flows for paid listings.\n *\n * Upload-bodied routes register here too. The note that used to sit here —\n * that they had to stay as named console routes because the dispatcher\n * \"can't grant per-route bodyParser limits\" — was a Pages Router leftover:\n * `runLegacyHandler` reads the request through the same\n * `pluginRequestFromWeb` a named App Router route would, and imposes no\n * limit of its own. publish-plugin's 8 MB bundle has been going through the\n * dispatcher the whole time.\n */\nexport function registerMarketplaceConsoleApi(): void {\n // Server side of the rating custom field (AGL-434): validators run\n // on import/write paths even when no client loaded the plugin.\n registerCustomFieldType(RATING_FIELD)\n /*\n * What a listing link unfurls as (AGL-876, handed to the platform by\n * AGL-3080).\n *\n * The card used to be built by a hand-written console route with a server\n * layout of its own, which is what kept that route out of the generic\n * plugin route — moving it would have dropped every listing's card with\n * nothing red. The shell asks this instead, so the card survives the move\n * and no console file reads `marketplaceListings` to build a head.\n *\n * One segment and one only: `/{org}/marketplace/{listingId}`. The hub, the\n * publish page and every other address under this route answer `null`,\n * which leaves the shell's own title exactly as it was.\n */\n registerPluginRouteMetadata(\n {\n route: 'marketplace',\n resolve: async (segments) => {\n if (segments.length !== 1) return null\n const { readListingForSocialCard } = await import(\n './server/listing-social-card.server'\n )\n const { listingSocialCard } = await import('./model/listing-social-card')\n return listingSocialCard(await readListingForSocialCard(segments[0]))\n },\n },\n // Named, because this registrar is called directly by the app's server\n // loader rather than from inside a plugin `register` fn, where the\n // loader's owner marker would be set.\n { pluginId: BUNDLE_ID },\n )\n registerPluginApiRoute('marketplace/checkout', checkoutHandler)\n registerPluginApiRoute('marketplace/connect', connectHandler)\n registerPluginApiRoute('marketplace/install', installHandler)\n registerPluginApiRoute('marketplace/install-plugin', installPluginHandler)\n registerPluginApiRoute('marketplace/install-layout', installLayoutHandler)\n registerPluginApiRoute('marketplace/install-template', installTemplateHandler)\n // A theme install DOES change the running site (AGL-1020) — it is the site's\n // appearance — so this route also owns the ways back: `revert` and `reset`.\n registerPluginApiRoute('marketplace/install-theme', installThemeHandler)\n registerPluginApiRoute(\n 'marketplace/install-dataset-schema',\n installDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-starter',\n installEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-template',\n installEmailTemplateHandler,\n )\n // Updating a copied artifact is its own route (AGL-1018), not a flag on\n // install: install writes the publisher's version, this one reconciles it\n // with a copy that has diverged and refuses to overwrite silently.\n registerPluginApiRoute('marketplace/update-artifact', updateArtifactHandler)\n registerPluginApiRoute('marketplace/listing-versions', listingVersionsHandler)\n registerPluginApiRoute('marketplace/preview-image', previewImageHandler)\n registerPluginApiRoute('marketplace/publish', publishHandler)\n registerPluginApiRoute('marketplace/report', reportHandler)\n /*\n * The staff end of that button (AGL-2310), moved out of\n * `apps/console/app/api/admin/` by AGL-3080. `web:` because it is a plain\n * fetch from this plugin's own staff page, not a plugin-request handler —\n * the same shape the AI plugin's `ai/admin/*` routes use, and for the same\n * reason: a staff route names no host, so there is no subject to resolve.\n */\n registerPluginApiRoute('marketplace/admin/reports', {\n web: marketplaceAdminReports,\n })\n // The review queue (AGL-432, moved by AGL-3080). Same shape and the same\n // reason: a staff route names no host, so there is no subject to resolve.\n registerPluginApiRoute('marketplace/admin/reviews', {\n web: marketplaceAdminReviews,\n })\n registerPluginApiRoute('marketplace/reviews', reviewsHandler)\n registerPluginApiRoute(\n 'marketplace/publisher-profile',\n publisherProfileSaveHandler,\n )\n registerPluginApiRoute(\n 'marketplace/verification-request',\n verificationRequestHandler,\n )\n registerPluginApiRoute('marketplace/publish-layout', publishLayoutHandler)\n registerPluginApiRoute('marketplace/publish-template', publishTemplateHandler)\n registerPluginApiRoute('marketplace/publish-theme', publishThemeHandler)\n registerPluginApiRoute(\n 'marketplace/publish-dataset-schema',\n publishDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-starter',\n publishEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-template',\n publishEmailTemplateHandler,\n )\n // Relocated console routes (AGL-418): URLs preserved via the dispatcher.\n registerPluginApiRoute('marketplace/publish-plugin', publishPluginHandler)\n // Marketplace purchases ride the platform Stripe webhook (AGL-418).\n registerBillingWebhookHandler(marketplaceBillingWebhookHandler)\n}\n"],"names":["registerBillingWebhookHandler","registerPluginApiRoute","registerCustomFieldType","registerPluginRouteMetadata","BUNDLE_ID","marketplaceBillingWebhookHandler","publishPluginHandler","verificationRequestHandler","checkoutHandler","connectHandler","installHandler","installPluginHandler","listingVersionsHandler","RATING_FIELD","installDatasetSchemaHandler","installEmailStarterHandler","installEmailTemplateHandler","installLayoutHandler","installTemplateHandler","installThemeHandler","previewImageHandler","publishHandler","marketplaceAdminReports","marketplaceAdminReviews","reportHandler","reviewsHandler","publisherProfileSaveHandler","publishDatasetSchemaHandler","publishEmailStarterHandler","publishEmailTemplateHandler","publishLayoutHandler","publishTemplateHandler","publishThemeHandler","updateArtifactHandler","registerMarketplaceConsoleApi","route","resolve","segments","length","readListingForSocialCard","listingSocialCard","pluginId","web"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/plugins/marketplace/src/lib/server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n registerBillingWebhookHandler,\n registerPluginApiRoute,\n registerCustomFieldType,\n} from '@aglyn/aglyn/server'\n// Its own subpath, never the plugin-manager barrel: what a published page\n// does not need, it must not import.\nimport { registerPluginRouteMetadata } from '@aglyn/aglyn/plugin-manager/plugin-route-metadata'\nimport { BUNDLE_ID } from './constants/bundle-common'\nimport { marketplaceBillingWebhookHandler } from './server/billing-webhook'\nimport { publishPluginHandler } from './server/publish-plugin'\nimport { verificationRequestHandler } from './server/verification-request'\nimport { checkoutHandler } from './server/checkout'\nimport { connectHandler } from './server/connect'\nimport { installHandler } from './server/install'\nimport { installPluginHandler } from './server/install-plugin'\nimport { listingVersionsHandler } from './server/listing-versions'\nimport { RATING_FIELD } from './model/rating-field'\nimport { installDatasetSchemaHandler } from './server/install-dataset-schema'\nimport { installEmailStarterHandler } from './server/install-email-starter'\nimport { installEmailTemplateHandler } from './server/install-email-template'\nimport { installLayoutHandler } from './server/install-layout'\nimport { installTemplateHandler } from './server/install-template'\nimport { installThemeHandler } from './server/install-theme'\nimport { previewImageHandler } from './server/preview-image'\nimport { publishHandler } from './server/publish'\nimport { marketplaceAdminReports } from './server/admin-reports'\nimport { marketplaceAdminReviews } from './server/admin-reviews'\nimport { marketplaceAdminTrust } from './server/admin-trust'\nimport { reportHandler } from './server/report'\nimport { reviewsHandler } from './server/reviews'\nimport { publisherProfileSaveHandler } from './server/publisher-profile-save'\nimport { publishDatasetSchemaHandler } from './server/publish-dataset-schema'\nimport { publishEmailStarterHandler } from './server/publish-email-starter'\nimport { publishEmailTemplateHandler } from './server/publish-email-template'\nimport { publishLayoutHandler } from './server/publish-layout'\nimport { publishTemplateHandler } from './server/publish-template'\nimport { publishThemeHandler } from './server/publish-theme'\nimport { updateArtifactHandler } from './server/update-artifact'\n\n/**\n * Registers the marketplace plugin's console-side API routes (AGL-396):\n * marketplace publish/install of templates and plugins, and the Stripe\n * Connect + checkout flows for paid listings.\n *\n * Upload-bodied routes register here too. The note that used to sit here —\n * that they had to stay as named console routes because the dispatcher\n * \"can't grant per-route bodyParser limits\" — was a Pages Router leftover:\n * `runLegacyHandler` reads the request through the same\n * `pluginRequestFromWeb` a named App Router route would, and imposes no\n * limit of its own. publish-plugin's 8 MB bundle has been going through the\n * dispatcher the whole time.\n */\nexport function registerMarketplaceConsoleApi(): void {\n // Server side of the rating custom field (AGL-434): validators run\n // on import/write paths even when no client loaded the plugin.\n registerCustomFieldType(RATING_FIELD)\n /*\n * What a listing link unfurls as (AGL-876, handed to the platform by\n * AGL-3080).\n *\n * The card used to be built by a hand-written console route with a server\n * layout of its own, which is what kept that route out of the generic\n * plugin route — moving it would have dropped every listing's card with\n * nothing red. The shell asks this instead, so the card survives the move\n * and no console file reads `marketplaceListings` to build a head.\n *\n * One segment and one only: `/{org}/marketplace/{listingId}`. The hub, the\n * publish page and every other address under this route answer `null`,\n * which leaves the shell's own title exactly as it was.\n */\n registerPluginRouteMetadata(\n {\n route: 'marketplace',\n resolve: async (segments) => {\n if (segments.length !== 1) return null\n const { readListingForSocialCard } = await import(\n './server/listing-social-card.server'\n )\n const { listingSocialCard } = await import('./model/listing-social-card')\n return listingSocialCard(await readListingForSocialCard(segments[0]))\n },\n },\n // Named, because this registrar is called directly by the app's server\n // loader rather than from inside a plugin `register` fn, where the\n // loader's owner marker would be set.\n { pluginId: BUNDLE_ID },\n )\n registerPluginApiRoute('marketplace/checkout', checkoutHandler)\n registerPluginApiRoute('marketplace/connect', connectHandler)\n registerPluginApiRoute('marketplace/install', installHandler)\n registerPluginApiRoute('marketplace/install-plugin', installPluginHandler)\n registerPluginApiRoute('marketplace/install-layout', installLayoutHandler)\n registerPluginApiRoute('marketplace/install-template', installTemplateHandler)\n // A theme install DOES change the running site (AGL-1020) — it is the site's\n // appearance — so this route also owns the ways back: `revert` and `reset`.\n registerPluginApiRoute('marketplace/install-theme', installThemeHandler)\n registerPluginApiRoute(\n 'marketplace/install-dataset-schema',\n installDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-starter',\n installEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/install-email-template',\n installEmailTemplateHandler,\n )\n // Updating a copied artifact is its own route (AGL-1018), not a flag on\n // install: install writes the publisher's version, this one reconciles it\n // with a copy that has diverged and refuses to overwrite silently.\n registerPluginApiRoute('marketplace/update-artifact', updateArtifactHandler)\n registerPluginApiRoute('marketplace/listing-versions', listingVersionsHandler)\n registerPluginApiRoute('marketplace/preview-image', previewImageHandler)\n registerPluginApiRoute('marketplace/publish', publishHandler)\n registerPluginApiRoute('marketplace/report', reportHandler)\n /*\n * The staff end of that button (AGL-2310), moved out of\n * `apps/console/app/api/admin/` by AGL-3080. `web:` because it is a plain\n * fetch from this plugin's own staff page, not a plugin-request handler —\n * the same shape the AI plugin's `ai/admin/*` routes use, and for the same\n * reason: a staff route names no host, so there is no subject to resolve.\n */\n registerPluginApiRoute('marketplace/admin/reports', {\n web: marketplaceAdminReports,\n })\n // The review queue (AGL-432, moved by AGL-3080). Same shape and the same\n // reason: a staff route names no host, so there is no subject to resolve.\n registerPluginApiRoute('marketplace/admin/reviews', {\n web: marketplaceAdminReviews,\n })\n // Realm trust (AGL-420, moved by AGL-3080). Super-staff only, and the\n // SIGNATURE comes from the shell — the key is the console's and stays\n // there. See `server/admin-trust.ts`.\n registerPluginApiRoute('marketplace/admin/trust', {\n web: marketplaceAdminTrust,\n })\n registerPluginApiRoute('marketplace/reviews', reviewsHandler)\n registerPluginApiRoute(\n 'marketplace/publisher-profile',\n publisherProfileSaveHandler,\n )\n registerPluginApiRoute(\n 'marketplace/verification-request',\n verificationRequestHandler,\n )\n registerPluginApiRoute('marketplace/publish-layout', publishLayoutHandler)\n registerPluginApiRoute('marketplace/publish-template', publishTemplateHandler)\n registerPluginApiRoute('marketplace/publish-theme', publishThemeHandler)\n registerPluginApiRoute(\n 'marketplace/publish-dataset-schema',\n publishDatasetSchemaHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-starter',\n publishEmailStarterHandler,\n )\n registerPluginApiRoute(\n 'marketplace/publish-email-template',\n publishEmailTemplateHandler,\n )\n // Relocated console routes (AGL-418): URLs preserved via the dispatcher.\n registerPluginApiRoute('marketplace/publish-plugin', publishPluginHandler)\n // Marketplace purchases ride the platform Stripe webhook (AGL-418).\n registerBillingWebhookHandler(marketplaceBillingWebhookHandler)\n}\n"],"names":["registerBillingWebhookHandler","registerPluginApiRoute","registerCustomFieldType","registerPluginRouteMetadata","BUNDLE_ID","marketplaceBillingWebhookHandler","publishPluginHandler","verificationRequestHandler","checkoutHandler","connectHandler","installHandler","installPluginHandler","listingVersionsHandler","RATING_FIELD","installDatasetSchemaHandler","installEmailStarterHandler","installEmailTemplateHandler","installLayoutHandler","installTemplateHandler","installThemeHandler","previewImageHandler","publishHandler","marketplaceAdminReports","marketplaceAdminReviews","marketplaceAdminTrust","reportHandler","reviewsHandler","publisherProfileSaveHandler","publishDatasetSchemaHandler","publishEmailStarterHandler","publishEmailTemplateHandler","publishLayoutHandler","publishTemplateHandler","publishThemeHandler","updateArtifactHandler","registerMarketplaceConsoleApi","route","resolve","segments","length","readListingForSocialCard","listingSocialCard","pluginId","web"],"mappings":"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"}
|