@aglyn/aglyn 1.0.0-beta.152 → 1.0.0-beta.154
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 +10 -10
- package/src/lib/app-utils/crm-csv.d.ts +10 -3
- package/src/lib/app-utils/crm-csv.js +37 -2
- package/src/lib/app-utils/crm-csv.js.map +1 -1
- package/src/lib/app-utils/crm-email-templates.js +15 -0
- package/src/lib/app-utils/crm-email-templates.js.map +1 -1
- package/src/lib/app-utils/crm.d.ts +69 -2
- package/src/lib/app-utils/crm.js +126 -1
- package/src/lib/app-utils/crm.js.map +1 -1
- package/src/lib/app-utils/docs-help.generated.d.ts +1 -1
- package/src/lib/app-utils/docs-help.generated.js +2 -0
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.js +25 -11
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/email-starter-policy.js +5 -3
- package/src/lib/app-utils/email-starter-policy.js.map +1 -1
- package/src/lib/app-utils/plan-entitlements.d.ts +34 -0
- package/src/lib/app-utils/plan-entitlements.js +40 -0
- package/src/lib/app-utils/plan-entitlements.js.map +1 -1
- package/src/lib/app-utils/server.d.ts +0 -1
- package/src/lib/app-utils/server.js +0 -1
- package/src/lib/app-utils/server.js.map +1 -1
- package/src/lib/plugin-manager/first-party-plugins.generated.js +1 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
- package/src/lib/plugin-manager/plugin-artifact-inventory.d.ts +145 -0
- package/src/lib/plugin-manager/plugin-artifact-inventory.js +126 -0
- package/src/lib/plugin-manager/plugin-artifact-inventory.js.map +1 -0
- package/src/lib/plugin-manager/plugin-contact-capture.d.ts +32 -1
- package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
- package/src/lib/plugin-manager/plugin-lead-conversion.d.ts +67 -0
- package/src/lib/plugin-manager/plugin-lead-conversion.js +93 -0
- package/src/lib/plugin-manager/plugin-lead-conversion.js.map +1 -0
- package/src/lib/plugin-manager/plugin-org-capacity.d.ts +12 -0
- package/src/lib/plugin-manager/plugin-org-capacity.js.map +1 -1
- package/src/lib/plugin-manager/plugin-record-timeline.d.ts +8 -1
- package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
- package/src/lib/app-utils/marketplace-verification.d.ts +0 -95
- package/src/lib/app-utils/marketplace-verification.js +0 -81
- package/src/lib/app-utils/marketplace-verification.js.map +0 -1
- package/src/lib/app-utils/publisher-attestation.d.ts +0 -99
- package/src/lib/app-utils/publisher-attestation.js +0 -158
- package/src/lib/app-utils/publisher-attestation.js.map +0 -1
|
@@ -1,99 +0,0 @@
|
|
|
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
|
-
export interface PublisherAttestationItem {
|
|
18
|
-
id: string;
|
|
19
|
-
/** First person — the publisher is the one saying it. */
|
|
20
|
-
label: string;
|
|
21
|
-
/** What they are actually committing to, shown under the item. */
|
|
22
|
-
detail: string;
|
|
23
|
-
/**
|
|
24
|
-
* Only asked when the listing already exists. A first submission has no
|
|
25
|
-
* "since the last version", and asking anyway teaches publishers that
|
|
26
|
-
* some of these boxes are noise.
|
|
27
|
-
*/
|
|
28
|
-
updateOnly?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* The submitted field this item is a claim ABOUT (AGL-1076).
|
|
31
|
-
*
|
|
32
|
-
* An attestation whose subject is absent is a statement about nothing:
|
|
33
|
-
* `repository` shipped for a while confirming that a repository URL is
|
|
34
|
-
* public and matches, in a form with nowhere to name a repository, on
|
|
35
|
-
* listings whose `repositoryUrl` was empty. A reviewer opened it first and
|
|
36
|
-
* found nothing to open.
|
|
37
|
-
*
|
|
38
|
-
* So a subject makes the tick enforceable: the publish route refuses with
|
|
39
|
-
* the same 428 as a missing tick when the value is not in the request that
|
|
40
|
-
* stores it. Declared here rather than in the route so the form knows to
|
|
41
|
-
* ask for it and the route knows to require it from one place.
|
|
42
|
-
*/
|
|
43
|
-
subject?: {
|
|
44
|
-
/** Key in the publish body, and on the listing/version doc. */
|
|
45
|
-
field: string;
|
|
46
|
-
/** How the field is labelled to the publisher, for the error. */
|
|
47
|
-
label: string;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
export declare const PUBLISHER_ATTESTATION: readonly PublisherAttestationItem[];
|
|
51
|
-
/** A stored attestation: who said it, when, and against which bytes. */
|
|
52
|
-
export interface AttestationEntry {
|
|
53
|
-
by?: string;
|
|
54
|
-
at?: unknown;
|
|
55
|
-
sha256?: string;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* The ids a submission must carry.
|
|
59
|
-
*
|
|
60
|
-
* `isUpdate` is decided server-side from whether a listing already exists,
|
|
61
|
-
* never from a client flag — otherwise "this is my first version" becomes a
|
|
62
|
-
* way to skip an item.
|
|
63
|
-
*/
|
|
64
|
-
export declare function requiredAttestationIds(isUpdate: boolean): string[];
|
|
65
|
-
/**
|
|
66
|
-
* Which required attestations a submission is missing, given the ids the
|
|
67
|
-
* publisher ticked.
|
|
68
|
-
*/
|
|
69
|
-
export declare function missingAttestations(ticked: readonly string[] | null | undefined, isUpdate: boolean): string[];
|
|
70
|
-
/** The fields a submission must carry alongside its ticks (AGL-1076). */
|
|
71
|
-
export declare function attestationSubjects(isUpdate: boolean): Array<{
|
|
72
|
-
id: string;
|
|
73
|
-
field: string;
|
|
74
|
-
label: string;
|
|
75
|
-
}>;
|
|
76
|
-
/**
|
|
77
|
-
* Which required attestations have nothing to be about (AGL-1076).
|
|
78
|
-
*
|
|
79
|
-
* `values` is the submission being stored, never the listing doc: on a first
|
|
80
|
-
* publish there is no listing, and on an update the tick is a statement about
|
|
81
|
-
* what this publish declares, not about whatever the listing said last year.
|
|
82
|
-
*/
|
|
83
|
-
export declare function missingAttestationSubjects(values: Record<string, unknown> | null | undefined, isUpdate: boolean): Array<{
|
|
84
|
-
id: string;
|
|
85
|
-
field: string;
|
|
86
|
-
label: string;
|
|
87
|
-
}>;
|
|
88
|
-
/** Human labels for a set of ids, for an error a publisher can act on. */
|
|
89
|
-
export declare function attestationLabels(ids: readonly string[]): string[];
|
|
90
|
-
/**
|
|
91
|
-
* Which stored attestations count for a given bundle.
|
|
92
|
-
*
|
|
93
|
-
* Keyed to sha256 exactly like the staff checklist (AGL-963) and the
|
|
94
|
-
* verifier verdict (AGL-962): an attestation is a statement about specific
|
|
95
|
-
* bytes, so a republish under the same version string re-asks. Carrying
|
|
96
|
-
* ticks across a rebuild would let a publisher attest to code they then
|
|
97
|
-
* replaced.
|
|
98
|
-
*/
|
|
99
|
-
export declare function attestationsForBytes(attestation: Record<string, AttestationEntry> | null | undefined, sha256: string): string[];
|
|
@@ -1,158 +0,0 @@
|
|
|
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
|
-
* What a publisher states about their own bundle before it enters the queue
|
|
18
|
-
* (AGL-969).
|
|
19
|
-
*
|
|
20
|
-
* Deliberately NOT the staff checklist. Those items are judgements *about*
|
|
21
|
-
* the publisher — "publisher is identifiable and contactable" is worthless
|
|
22
|
-
* as self-attestation, because the answer is always yes. Every item here is
|
|
23
|
-
* something only the publisher can know and a reviewer would otherwise have
|
|
24
|
-
* to guess at or chase by email: whether the repo really holds this code,
|
|
25
|
-
* whether they have the right to publish it, whether each declared host is
|
|
26
|
-
* actually reached.
|
|
27
|
-
*
|
|
28
|
-
* Two things come out of this. Most review round-trips are questions the
|
|
29
|
-
* publisher could have answered at submit time, so the queue moves faster.
|
|
30
|
-
* And a false attestation is a timestamped statement by a named publisher
|
|
31
|
-
* against specific bytes, which makes takedown a documented consequence
|
|
32
|
-
* rather than a judgement call.
|
|
33
|
-
*
|
|
34
|
-
* This module is shared on purpose: the publish API is the enforcement
|
|
35
|
-
* point, the upload dialog renders the same list, and the review page shows
|
|
36
|
-
* staff what was claimed. Three copies of these strings would drift, and a
|
|
37
|
-
* drifted attestation is one nobody can be held to.
|
|
38
|
-
*/ import { PLATFORM_BRAND_NAME } from "./platform-brand.js";
|
|
39
|
-
export const PUBLISHER_ATTESTATION = [
|
|
40
|
-
{
|
|
41
|
-
id: 'repository',
|
|
42
|
-
label: 'The repository URL is public and contains the source for this bundle',
|
|
43
|
-
detail: 'A reviewer opens it first. A repo that 404s, is private, or holds something unrelated is the cheapest reason a submission gets sent back.',
|
|
44
|
-
subject: {
|
|
45
|
-
field: 'repositoryUrl',
|
|
46
|
-
label: 'Repository URL'
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: 'license',
|
|
51
|
-
label: 'A license is included and I have the right to publish this code',
|
|
52
|
-
detail: 'Missing or incompatible licensing is a legal problem for every workspace that installs it, not only for us.'
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
id: 'data-disclosure',
|
|
56
|
-
label: 'The README documents what data this plugin reads, stores or sends, and where it goes',
|
|
57
|
-
detail: 'Anything the plugin does with member or page data belongs in the README before it is installed, not in a support thread afterwards.'
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
id: 'network-hosts',
|
|
61
|
-
label: 'Every declared network host is required — I have removed the ones I do not use',
|
|
62
|
-
detail: 'Declared hosts become this plugin’s CSP connect-src. An allowlist wider than the plugin needs is the single most common thing review sends back, and it widens the blast radius if the bundle is ever compromised.'
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
id: 'tested',
|
|
66
|
-
label: 'I have tested this version on a site I control',
|
|
67
|
-
detail: 'These exact bytes, not an earlier build. Static review cannot tell a reviewer what your plugin does at runtime.'
|
|
68
|
-
},
|
|
69
|
-
/**
|
|
70
|
-
* Publisher Agreement §3(h), which binds "Neither the Artifact nor its
|
|
71
|
-
* listing" — so it already reached the element names and descriptions a
|
|
72
|
-
* plugin declares in its manifest, which ship INSIDE the artifact. This
|
|
73
|
-
* sentence did not, and a publisher can only be held to what they were
|
|
74
|
-
* asked (AGL-2486).
|
|
75
|
-
*
|
|
76
|
-
* Written as a CAPABILITY — any text you supply that renders in, or ranks
|
|
77
|
-
* within, the console — rather than as a list of today's fields. The list
|
|
78
|
-
* was already wrong once: `tags` and `keywords` reached the picker's search
|
|
79
|
-
* ranking days after `description` reached its detail panel, and a sentence
|
|
80
|
-
* enumerating fields goes stale the next time one is added. Ranking is
|
|
81
|
-
* named explicitly because it is the non-obvious half: a search term never
|
|
82
|
-
* appears on screen, yet it decides which element a customer is SHOWN.
|
|
83
|
-
*
|
|
84
|
-
* The id stays `listing-conduct` deliberately. A stored tick is keyed by
|
|
85
|
-
* id (see {@link attestationsForBytes}), so renaming it to something truer
|
|
86
|
-
* to the widened wording would orphan every attestation on file as an
|
|
87
|
-
* unrecognised id, and re-ask for bytes already attested.
|
|
88
|
-
*/ {
|
|
89
|
-
id: 'listing-conduct',
|
|
90
|
-
label: `Neither my listing nor any text on my elements disparages ${PLATFORM_BRAND_NAME}, quotes what its plans cost, or sells a way around one`,
|
|
91
|
-
detail: `Saying which ${PLATFORM_BRAND_NAME} plans or features your plugin needs, or works with, is fine and useful. Editorialising about ${PLATFORM_BRAND_NAME}’s prices or quotas, stating or implying what a plan contains, or pitching this version as a way to avoid a plan or an upgrade is not. This covers any text you supply that renders in — or ranks within — the console, not only the listing: an element’s name, description, tags, search keywords and attribute labels all ship inside your bundle, and a customer meets them in their own element picker. Search terms count even though nobody reads them, because they decide which element gets shown.`
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
id: 'changelog',
|
|
95
|
-
label: 'The changelog describes what changed since the last version',
|
|
96
|
-
detail: 'An update is where something slips through — the first version gets read closely, the fourth rarely does. Saying what moved is what makes reviewing a diff possible.',
|
|
97
|
-
updateOnly: true
|
|
98
|
-
}
|
|
99
|
-
];
|
|
100
|
-
/**
|
|
101
|
-
* The ids a submission must carry.
|
|
102
|
-
*
|
|
103
|
-
* `isUpdate` is decided server-side from whether a listing already exists,
|
|
104
|
-
* never from a client flag — otherwise "this is my first version" becomes a
|
|
105
|
-
* way to skip an item.
|
|
106
|
-
*/ export function requiredAttestationIds(isUpdate) {
|
|
107
|
-
return PUBLISHER_ATTESTATION.filter((item)=>isUpdate || !item.updateOnly).map((item)=>item.id);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Which required attestations a submission is missing, given the ids the
|
|
111
|
-
* publisher ticked.
|
|
112
|
-
*/ export function missingAttestations(ticked, isUpdate) {
|
|
113
|
-
const given = new Set(ticked != null ? ticked : []);
|
|
114
|
-
return requiredAttestationIds(isUpdate).filter((id)=>!given.has(id));
|
|
115
|
-
}
|
|
116
|
-
/** The fields a submission must carry alongside its ticks (AGL-1076). */ export function attestationSubjects(isUpdate) {
|
|
117
|
-
return PUBLISHER_ATTESTATION.filter((item)=>item.subject && (isUpdate || !item.updateOnly)).map((item)=>{
|
|
118
|
-
var _ref, _ref1;
|
|
119
|
-
var _item_subject, _item_subject1;
|
|
120
|
-
return {
|
|
121
|
-
id: item.id,
|
|
122
|
-
field: (_ref = (_item_subject = item.subject) == null ? void 0 : _item_subject.field) != null ? _ref : '',
|
|
123
|
-
label: (_ref1 = (_item_subject1 = item.subject) == null ? void 0 : _item_subject1.label) != null ? _ref1 : ''
|
|
124
|
-
};
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Which required attestations have nothing to be about (AGL-1076).
|
|
129
|
-
*
|
|
130
|
-
* `values` is the submission being stored, never the listing doc: on a first
|
|
131
|
-
* publish there is no listing, and on an update the tick is a statement about
|
|
132
|
-
* what this publish declares, not about whatever the listing said last year.
|
|
133
|
-
*/ export function missingAttestationSubjects(values, isUpdate) {
|
|
134
|
-
return attestationSubjects(isUpdate).filter((subject)=>{
|
|
135
|
-
const value = (values != null ? values : {})[subject.field];
|
|
136
|
-
return typeof value !== 'string' || !value.trim();
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
/** Human labels for a set of ids, for an error a publisher can act on. */ export function attestationLabels(ids) {
|
|
140
|
-
return ids.map((id)=>{
|
|
141
|
-
var _PUBLISHER_ATTESTATION_find;
|
|
142
|
-
return (_PUBLISHER_ATTESTATION_find = PUBLISHER_ATTESTATION.find((item)=>item.id === id)) == null ? void 0 : _PUBLISHER_ATTESTATION_find.label;
|
|
143
|
-
}).filter((label)=>Boolean(label));
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Which stored attestations count for a given bundle.
|
|
147
|
-
*
|
|
148
|
-
* Keyed to sha256 exactly like the staff checklist (AGL-963) and the
|
|
149
|
-
* verifier verdict (AGL-962): an attestation is a statement about specific
|
|
150
|
-
* bytes, so a republish under the same version string re-asks. Carrying
|
|
151
|
-
* ticks across a rebuild would let a publisher attest to code they then
|
|
152
|
-
* replaced.
|
|
153
|
-
*/ export function attestationsForBytes(attestation, sha256) {
|
|
154
|
-
if (!sha256) return [];
|
|
155
|
-
return Object.entries(attestation != null ? attestation : {}).filter(([, entry])=>(entry == null ? void 0 : entry.sha256) === sha256).map(([id])=>id);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
//# sourceMappingURL=publisher-attestation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/publisher-attestation.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\n/**\n * What a publisher states about their own bundle before it enters the queue\n * (AGL-969).\n *\n * Deliberately NOT the staff checklist. Those items are judgements *about*\n * the publisher — \"publisher is identifiable and contactable\" is worthless\n * as self-attestation, because the answer is always yes. Every item here is\n * something only the publisher can know and a reviewer would otherwise have\n * to guess at or chase by email: whether the repo really holds this code,\n * whether they have the right to publish it, whether each declared host is\n * actually reached.\n *\n * Two things come out of this. Most review round-trips are questions the\n * publisher could have answered at submit time, so the queue moves faster.\n * And a false attestation is a timestamped statement by a named publisher\n * against specific bytes, which makes takedown a documented consequence\n * rather than a judgement call.\n *\n * This module is shared on purpose: the publish API is the enforcement\n * point, the upload dialog renders the same list, and the review page shows\n * staff what was claimed. Three copies of these strings would drift, and a\n * drifted attestation is one nobody can be held to.\n */\nimport { PLATFORM_BRAND_NAME } from './platform-brand'\n\nexport interface PublisherAttestationItem {\n id: string\n /** First person — the publisher is the one saying it. */\n label: string\n /** What they are actually committing to, shown under the item. */\n detail: string\n /**\n * Only asked when the listing already exists. A first submission has no\n * \"since the last version\", and asking anyway teaches publishers that\n * some of these boxes are noise.\n */\n updateOnly?: boolean\n /**\n * The submitted field this item is a claim ABOUT (AGL-1076).\n *\n * An attestation whose subject is absent is a statement about nothing:\n * `repository` shipped for a while confirming that a repository URL is\n * public and matches, in a form with nowhere to name a repository, on\n * listings whose `repositoryUrl` was empty. A reviewer opened it first and\n * found nothing to open.\n *\n * So a subject makes the tick enforceable: the publish route refuses with\n * the same 428 as a missing tick when the value is not in the request that\n * stores it. Declared here rather than in the route so the form knows to\n * ask for it and the route knows to require it from one place.\n */\n subject?: {\n /** Key in the publish body, and on the listing/version doc. */\n field: string\n /** How the field is labelled to the publisher, for the error. */\n label: string\n }\n}\n\nexport const PUBLISHER_ATTESTATION: readonly PublisherAttestationItem[] = [\n {\n id: 'repository',\n label: 'The repository URL is public and contains the source for this bundle',\n detail:\n 'A reviewer opens it first. A repo that 404s, is private, or holds something unrelated is the cheapest reason a submission gets sent back.',\n subject: { field: 'repositoryUrl', label: 'Repository URL' },\n },\n {\n id: 'license',\n label: 'A license is included and I have the right to publish this code',\n detail:\n 'Missing or incompatible licensing is a legal problem for every workspace that installs it, not only for us.',\n },\n {\n id: 'data-disclosure',\n label:\n 'The README documents what data this plugin reads, stores or sends, and where it goes',\n detail:\n 'Anything the plugin does with member or page data belongs in the README before it is installed, not in a support thread afterwards.',\n },\n {\n id: 'network-hosts',\n label:\n 'Every declared network host is required — I have removed the ones I do not use',\n detail:\n 'Declared hosts become this plugin’s CSP connect-src. An allowlist wider than the plugin needs is the single most common thing review sends back, and it widens the blast radius if the bundle is ever compromised.',\n },\n {\n id: 'tested',\n label: 'I have tested this version on a site I control',\n detail:\n 'These exact bytes, not an earlier build. Static review cannot tell a reviewer what your plugin does at runtime.',\n },\n /**\n * Publisher Agreement §3(h), which binds \"Neither the Artifact nor its\n * listing\" — so it already reached the element names and descriptions a\n * plugin declares in its manifest, which ship INSIDE the artifact. This\n * sentence did not, and a publisher can only be held to what they were\n * asked (AGL-2486).\n *\n * Written as a CAPABILITY — any text you supply that renders in, or ranks\n * within, the console — rather than as a list of today's fields. The list\n * was already wrong once: `tags` and `keywords` reached the picker's search\n * ranking days after `description` reached its detail panel, and a sentence\n * enumerating fields goes stale the next time one is added. Ranking is\n * named explicitly because it is the non-obvious half: a search term never\n * appears on screen, yet it decides which element a customer is SHOWN.\n *\n * The id stays `listing-conduct` deliberately. A stored tick is keyed by\n * id (see {@link attestationsForBytes}), so renaming it to something truer\n * to the widened wording would orphan every attestation on file as an\n * unrecognised id, and re-ask for bytes already attested.\n */\n {\n id: 'listing-conduct',\n label:\n `Neither my listing nor any text on my elements disparages ${PLATFORM_BRAND_NAME}, quotes what its plans cost, or sells a way around one`,\n detail:\n `Saying which ${PLATFORM_BRAND_NAME} plans or features your plugin needs, or works with, is fine and useful. Editorialising about ${PLATFORM_BRAND_NAME}’s prices or quotas, stating or implying what a plan contains, or pitching this version as a way to avoid a plan or an upgrade is not. This covers any text you supply that renders in — or ranks within — the console, not only the listing: an element’s name, description, tags, search keywords and attribute labels all ship inside your bundle, and a customer meets them in their own element picker. Search terms count even though nobody reads them, because they decide which element gets shown.`,\n },\n {\n id: 'changelog',\n label: 'The changelog describes what changed since the last version',\n detail:\n 'An update is where something slips through — the first version gets read closely, the fourth rarely does. Saying what moved is what makes reviewing a diff possible.',\n updateOnly: true,\n },\n]\n\n/** A stored attestation: who said it, when, and against which bytes. */\nexport interface AttestationEntry {\n by?: string\n at?: unknown\n sha256?: string\n}\n\n/**\n * The ids a submission must carry.\n *\n * `isUpdate` is decided server-side from whether a listing already exists,\n * never from a client flag — otherwise \"this is my first version\" becomes a\n * way to skip an item.\n */\nexport function requiredAttestationIds(isUpdate: boolean): string[] {\n return PUBLISHER_ATTESTATION.filter(\n (item) => isUpdate || !item.updateOnly,\n ).map((item) => item.id)\n}\n\n/**\n * Which required attestations a submission is missing, given the ids the\n * publisher ticked.\n */\nexport function missingAttestations(\n ticked: readonly string[] | null | undefined,\n isUpdate: boolean,\n): string[] {\n const given = new Set(ticked ?? [])\n return requiredAttestationIds(isUpdate).filter((id) => !given.has(id))\n}\n\n/** The fields a submission must carry alongside its ticks (AGL-1076). */\nexport function attestationSubjects(\n isUpdate: boolean,\n): Array<{ id: string; field: string; label: string }> {\n return PUBLISHER_ATTESTATION.filter(\n (item) => item.subject && (isUpdate || !item.updateOnly),\n ).map((item) => ({\n id: item.id,\n field: item.subject?.field ?? '',\n label: item.subject?.label ?? '',\n }))\n}\n\n/**\n * Which required attestations have nothing to be about (AGL-1076).\n *\n * `values` is the submission being stored, never the listing doc: on a first\n * publish there is no listing, and on an update the tick is a statement about\n * what this publish declares, not about whatever the listing said last year.\n */\nexport function missingAttestationSubjects(\n values: Record<string, unknown> | null | undefined,\n isUpdate: boolean,\n): Array<{ id: string; field: string; label: string }> {\n return attestationSubjects(isUpdate).filter((subject) => {\n const value = (values ?? {})[subject.field]\n return typeof value !== 'string' || !value.trim()\n })\n}\n\n/** Human labels for a set of ids, for an error a publisher can act on. */\nexport function attestationLabels(ids: readonly string[]): string[] {\n return ids\n .map((id) => PUBLISHER_ATTESTATION.find((item) => item.id === id)?.label)\n .filter((label): label is string => Boolean(label))\n}\n\n/**\n * Which stored attestations count for a given bundle.\n *\n * Keyed to sha256 exactly like the staff checklist (AGL-963) and the\n * verifier verdict (AGL-962): an attestation is a statement about specific\n * bytes, so a republish under the same version string re-asks. Carrying\n * ticks across a rebuild would let a publisher attest to code they then\n * replaced.\n */\nexport function attestationsForBytes(\n attestation: Record<string, AttestationEntry> | null | undefined,\n sha256: string,\n): string[] {\n if (!sha256) return []\n return Object.entries(attestation ?? {})\n .filter(([, entry]) => entry?.sha256 === sha256)\n .map(([id]) => id)\n}\n"],"names":["PLATFORM_BRAND_NAME","PUBLISHER_ATTESTATION","id","label","detail","subject","field","updateOnly","requiredAttestationIds","isUpdate","filter","item","map","missingAttestations","ticked","given","Set","has","attestationSubjects","missingAttestationSubjects","values","value","trim","attestationLabels","ids","find","Boolean","attestationsForBytes","attestation","sha256","Object","entries","entry"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;;;;;CAsBC,GACD,SAASA,mBAAmB,QAAQ,sBAAkB;AAoCtD,OAAO,MAAMC,wBAA6D;IACxE;QACEC,IAAI;QACJC,OAAO;QACPC,QACE;QACFC,SAAS;YAAEC,OAAO;YAAiBH,OAAO;QAAiB;IAC7D;IACA;QACED,IAAI;QACJC,OAAO;QACPC,QACE;IACJ;IACA;QACEF,IAAI;QACJC,OACE;QACFC,QACE;IACJ;IACA;QACEF,IAAI;QACJC,OACE;QACFC,QACE;IACJ;IACA;QACEF,IAAI;QACJC,OAAO;QACPC,QACE;IACJ;IACA;;;;;;;;;;;;;;;;;;;GAmBC,GACD;QACEF,IAAI;QACJC,OACE,CAAC,0DAA0D,EAAEH,oBAAoB,uDAAuD,CAAC;QAC3II,QACE,CAAC,aAAa,EAAEJ,oBAAoB,8FAA8F,EAAEA,oBAAoB,4eAA4e,CAAC;IACzoB;IACA;QACEE,IAAI;QACJC,OAAO;QACPC,QACE;QACFG,YAAY;IACd;CACD,CAAA;AASD;;;;;;CAMC,GACD,OAAO,SAASC,uBAAuBC,QAAiB;IACtD,OAAOR,sBAAsBS,MAAM,CACjC,CAACC,OAASF,YAAY,CAACE,KAAKJ,UAAU,EACtCK,GAAG,CAAC,CAACD,OAASA,KAAKT,EAAE;AACzB;AAEA;;;CAGC,GACD,OAAO,SAASW,oBACdC,MAA4C,EAC5CL,QAAiB;IAEjB,MAAMM,QAAQ,IAAIC,IAAIF,iBAAAA,SAAU,EAAE;IAClC,OAAON,uBAAuBC,UAAUC,MAAM,CAAC,CAACR,KAAO,CAACa,MAAME,GAAG,CAACf;AACpE;AAEA,uEAAuE,GACvE,OAAO,SAASgB,oBACdT,QAAiB;IAEjB,OAAOR,sBAAsBS,MAAM,CACjC,CAACC,OAASA,KAAKN,OAAO,IAAKI,CAAAA,YAAY,CAACE,KAAKJ,UAAU,AAAD,GACtDK,GAAG,CAAC,CAACD;;YAEEA,eACAA;eAHQ;YACfT,IAAIS,KAAKT,EAAE;YACXI,KAAK,WAAEK,gBAAAA,KAAKN,OAAO,qBAAZM,cAAcL,KAAK,mBAAI;YAC9BH,KAAK,YAAEQ,iBAAAA,KAAKN,OAAO,qBAAZM,eAAcR,KAAK,oBAAI;QAChC;;AACF;AAEA;;;;;;CAMC,GACD,OAAO,SAASgB,2BACdC,MAAkD,EAClDX,QAAiB;IAEjB,OAAOS,oBAAoBT,UAAUC,MAAM,CAAC,CAACL;QAC3C,MAAMgB,QAAQ,CAACD,iBAAAA,SAAU,CAAC,EAAE,CAACf,QAAQC,KAAK,CAAC;QAC3C,OAAO,OAAOe,UAAU,YAAY,CAACA,MAAMC,IAAI;IACjD;AACF;AAEA,wEAAwE,GACxE,OAAO,SAASC,kBAAkBC,GAAsB;IACtD,OAAOA,IACJZ,GAAG,CAAC,CAACV;YAAOD;gBAAAA,8BAAAA,sBAAsBwB,IAAI,CAAC,CAACd,OAASA,KAAKT,EAAE,KAAKA,wBAAjDD,4BAAsDE,KAAK;OACvEO,MAAM,CAAC,CAACP,QAA2BuB,QAAQvB;AAChD;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASwB,qBACdC,WAAgE,EAChEC,MAAc;IAEd,IAAI,CAACA,QAAQ,OAAO,EAAE;IACtB,OAAOC,OAAOC,OAAO,CAACH,sBAAAA,cAAe,CAAC,GACnClB,MAAM,CAAC,CAAC,GAAGsB,MAAM,GAAKA,CAAAA,yBAAAA,MAAOH,MAAM,MAAKA,QACxCjB,GAAG,CAAC,CAAC,CAACV,GAAG,GAAKA;AACnB"}
|