@openengio/cli 0.23.3 → 0.24.4
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/README.md +100 -14
- package/bin/public/openeng.js +785 -128
- package/package.json +1 -1
- package/skill/build-ui/SKILL.md +4 -0
- package/skill/conventions/SKILL.md +62 -0
- package/skill/demo/SKILL.md +130 -103
- package/skill/new-use-case/SKILL.md +4 -0
- package/skill/openeng/SKILL.md +128 -26
package/bin/public/openeng.js
CHANGED
|
@@ -98,6 +98,7 @@ var RULE_ENTRIES = {
|
|
|
98
98
|
"max-session-out-of-range": entry("The sign-in length in the request is outside the allowed range.", FIX_REQUEST),
|
|
99
99
|
"invalid-email": entry("The email address is not one the platform takes: it must have one @, and no space or non-ASCII character, and be at most 254 characters.", FIX_REQUEST),
|
|
100
100
|
"already-invited": entry("The organisation already has a pending invitation to this address.", { option: "List the pending invitations.", read: "listInvitations" }),
|
|
101
|
+
"no-such-client": entry("The client the request names is not an active client of your organisation.", { option: "List the organisation's clients.", read: "listClients" }),
|
|
101
102
|
"no-such-invitation": entry("The invitation the request names is not one of your organisation.", { option: "List the pending invitations.", read: "listInvitations" }),
|
|
102
103
|
"invitation-not-pending": entry("The invitation was already accepted or revoked.", { option: "List the pending invitations.", read: "listInvitations" }),
|
|
103
104
|
"invalid-domain": entry("A domain in the rule is not a valid domain name: it needs letters, digits, hyphens and at least one dot.", FIX_REQUEST),
|
|
@@ -131,6 +132,17 @@ var RULE_ENTRIES = {
|
|
|
131
132
|
"over-bound": entry("The request is larger than the platform allows.", FIX_REQUEST),
|
|
132
133
|
"malformed-history-request": entry("The history request is not one the platform can run.", FIX_REQUEST),
|
|
133
134
|
"protected-ref": entry("This branch is protected, so an agent cannot write to it.", { option: "Write to another branch." }),
|
|
135
|
+
immutable: entry("The record's type is immutable, so it cannot be changed or deleted on any branch.", { option: "Leave the record unchanged." }),
|
|
136
|
+
owned: entry("The record belongs to a connected system, which alone can write it.", { option: "Ask the connected system to make the change." }),
|
|
137
|
+
frozen: entry("The record is locked; it cannot be changed until someone allowed to lock records lifts the lock.", { option: "Ask someone allowed to lock records to lift the lock." }),
|
|
138
|
+
protected: entry("A rule protects this record on this branch, so it changes only by a merge from another branch.", { option: "Make the change on another branch and merge it." }),
|
|
139
|
+
"not-a-ref-head": entry("The commit is not the latest commit of a branch you can use.", { option: "Read the branches you can use and choose one." }),
|
|
140
|
+
"branch-needs-schema-update": entry("This branch's schema is older than the platform's, so it must be updated before it can be written.", { option: "Request a schema update for the branch." }),
|
|
141
|
+
"organisation-not-ready": entry("The organisation's trunk is not ready yet.", { option: "Try again shortly." }),
|
|
142
|
+
"read-only-ref": entry("The branch is read-only, so nothing can be written or merged into it.", { option: "Choose a writable branch." }),
|
|
143
|
+
"ref-exists": entry("An organisation ref of that name already exists.", { option: "List the organisation's refs.", read: "listOrganisationRefs" }),
|
|
144
|
+
"concurrent-change": entry("Another write changed the record first, so nothing was applied.", { option: "Try again shortly." }),
|
|
145
|
+
"lock-unavailable": entry("The lock could not be taken now, so nothing was applied.", { option: "Try again shortly." }),
|
|
134
146
|
"organisation-not-active": entry("The organisation is not active.", ASK_ADMINISTRATOR),
|
|
135
147
|
"duplicate-project": entry("A project with this identifier already exists.", { option: "List the projects.", read: "listProjects" }),
|
|
136
148
|
"duplicate-organisation": entry("An organisation with this identifier already exists.", { option: "Send it again as a new request." }),
|
|
@@ -175,11 +187,15 @@ var CLASS_ENTRIES = {
|
|
|
175
187
|
};
|
|
176
188
|
var API_RULE_ENTRIES = {
|
|
177
189
|
"not-found": KIND_ENTRIES["not-found"],
|
|
190
|
+
immutable: RULE_ENTRIES.immutable,
|
|
191
|
+
owned: RULE_ENTRIES.owned,
|
|
192
|
+
frozen: RULE_ENTRIES.frozen,
|
|
193
|
+
protected: RULE_ENTRIES.protected,
|
|
194
|
+
"branch-needs-schema-update": RULE_ENTRIES["branch-needs-schema-update"],
|
|
178
195
|
conflict: entry("A property's current value differs from the 'from' value the request expected; the refusal names each such property and its current value.", { option: "Read the current properties, reconcile the changes and send the update again with the from values you now expect." }),
|
|
179
196
|
"unknown-type": entry("The requested type is not a current object or edge type in this namespace.", { option: "Read the current types and use an object or edge type they contain.", read: "readCatalogue" }),
|
|
180
197
|
"type-version-precondition": entry("The type version the request expected differs from the type's current version.", { option: "Read the type's current version and send the request with that version." }),
|
|
181
198
|
"invalid-properties": entry("The property document failed validation; the violations name each offending path and rule.", { option: "Correct the properties at the paths the violations name and send the request again." }),
|
|
182
|
-
"trunk-write": entry("The trunk takes changes only by a merge from a branch, so this write was refused.", { option: "Make the change on a branch you can write." }),
|
|
183
199
|
"blocked-by-edge": entry("The object has a link you may not remove, so nothing was deleted.", { option: "Remove that link first, or ask someone who may to remove it." }),
|
|
184
200
|
"endpoint-type-mismatch": entry("An endpoint's object type does not match the source or target type required by the link's type version.", { option: "Use endpoints whose object types match the link's source and target types." }),
|
|
185
201
|
"cross-organisation-edge": entry("The link's endpoints belong to projects in different organisations.", { option: "Choose endpoints whose projects belong to the same organisation." }),
|
|
@@ -212,7 +228,11 @@ var API_REFUSAL_RULES = Object.freeze([
|
|
|
212
228
|
"unknown-type",
|
|
213
229
|
"type-version-precondition",
|
|
214
230
|
"invalid-properties",
|
|
215
|
-
"
|
|
231
|
+
"immutable",
|
|
232
|
+
"owned",
|
|
233
|
+
"frozen",
|
|
234
|
+
"protected",
|
|
235
|
+
"branch-needs-schema-update",
|
|
216
236
|
"blocked-by-edge",
|
|
217
237
|
"write-refused",
|
|
218
238
|
"endpoint-type-mismatch",
|
|
@@ -224,9 +244,44 @@ var API_REFUSAL_RULES = Object.freeze([
|
|
|
224
244
|
var SHIM_COLLIDING_API_RULES = Object.freeze(["write-refused"]);
|
|
225
245
|
|
|
226
246
|
// packages/api-contract/dist/route-docs.js
|
|
247
|
+
function need(capability, scope) {
|
|
248
|
+
return Object.freeze({ capability, scope });
|
|
249
|
+
}
|
|
250
|
+
var PROTECTION_ROUTE_CAPABILITIES = Object.freeze({
|
|
251
|
+
addRefRule: Object.freeze([need("administer projects", "project")]),
|
|
252
|
+
listRefRules: Object.freeze([need("read", "project")]),
|
|
253
|
+
removeRefRule: Object.freeze([need("administer projects", "project")]),
|
|
254
|
+
addOrganisationRule: Object.freeze([need("administer projects", "organisation")]),
|
|
255
|
+
listOrganisationRules: Object.freeze([need("read", "organisation")]),
|
|
256
|
+
removeOrganisationRule: Object.freeze([need("administer projects", "organisation")]),
|
|
257
|
+
createOrganisationRef: Object.freeze([need("administer projects", "organisation")]),
|
|
258
|
+
listOrganisationRefs: Object.freeze([need("read", "organisation")]),
|
|
259
|
+
deleteOrganisationRef: Object.freeze([need("administer projects", "organisation")]),
|
|
260
|
+
markOrganisationRefReadOnly: Object.freeze([need("administer projects", "organisation")]),
|
|
261
|
+
setObjectLock: Object.freeze([need("lock objects", "project")]),
|
|
262
|
+
readAgentCeiling: Object.freeze([need("read", "project")]),
|
|
263
|
+
setAgentCeiling: Object.freeze([need("administer projects", "project")]),
|
|
264
|
+
requestSchemaUpdate: Object.freeze([
|
|
265
|
+
need("write ref", "branch-home-project"),
|
|
266
|
+
need("administer projects", "organisation-ref")
|
|
267
|
+
]),
|
|
268
|
+
readSchemaUpdateRequest: Object.freeze([Object.freeze({ visibility: "requester-in-token-organisation" })])
|
|
269
|
+
});
|
|
227
270
|
var SIGNED_IN = ["unauthenticated", "invalid-request", "bound-exceeded", "internal"];
|
|
228
271
|
var SCOPED = [...SIGNED_IN, "not-found", "not-permitted"];
|
|
229
272
|
var WRITE = [...SCOPED, "in-flight", "unknown-outcome"];
|
|
273
|
+
var REF_READ = [...SCOPED, "organisation-not-ready", "branch-needs-schema-update"];
|
|
274
|
+
var REF_WRITE = [...REF_READ, "in-flight", "unknown-outcome"];
|
|
275
|
+
var OBJECT_WRITE = [
|
|
276
|
+
...REF_WRITE,
|
|
277
|
+
"immutable",
|
|
278
|
+
"owned",
|
|
279
|
+
"frozen",
|
|
280
|
+
"protected",
|
|
281
|
+
"read-only-ref",
|
|
282
|
+
"concurrent-change",
|
|
283
|
+
"lock-unavailable"
|
|
284
|
+
];
|
|
230
285
|
var PUBLIC = ["invalid-request", "bound-exceeded", "internal"];
|
|
231
286
|
var CHANGE_SET = [...SIGNED_IN, "not-permitted", "stale-revision", "not-open"];
|
|
232
287
|
var QUERY_PROJECT_SCOPE = 'Without input.projects, it reads every project the caller can read on the selected ref; selector.projectId does not narrow the set. To limit it to one project, include "projects":["<projectId>"] in input.';
|
|
@@ -246,15 +301,15 @@ var ROUTE_DOCS = Object.freeze({
|
|
|
246
301
|
serviceCredential: doc("Exchanges a service credential for an access token.", [...PUBLIC, "unknown-credential", "secret", "kind", "lifecycle"]),
|
|
247
302
|
registerClient: doc("Registers a third-party application as a client of the caller's organisation.", [...SIGNED_IN, "not-permitted", "capability-missing"]),
|
|
248
303
|
listClients: doc("Lists the clients of the caller's organisation, for a caller who administers them.", SCOPED),
|
|
249
|
-
revokeClient: doc("Revokes a client; its grants and tokens stop on their next use.", SCOPED),
|
|
250
|
-
replaceClientKeys: doc("Replaces a confidential client's public key set.", SCOPED),
|
|
304
|
+
revokeClient: doc("Revokes a client; its grants and tokens stop on their next use.", [...SCOPED, "no-such-client"]),
|
|
305
|
+
replaceClientKeys: doc("Replaces a confidential client's public key set.", [...SCOPED, "no-such-client"]),
|
|
251
306
|
readConsentRequest: doc("Reads a pending authorization request for the person who signed in inside it.", SCOPED),
|
|
252
307
|
decideConsent: doc("Approves or denies a pending authorization request.", SCOPED),
|
|
253
308
|
listConnectedApps: doc("Lists the applications the caller has connected.", SIGNED_IN),
|
|
254
309
|
revokeConnectedApp: doc("Disconnects an application: every grant the caller holds for it stops.", SCOPED),
|
|
255
|
-
readObject: doc("Reads one object at a ref.",
|
|
310
|
+
readObject: doc("Reads one object at a ref.", REF_READ),
|
|
256
311
|
queryObjects: doc(`Runs a filtered, ordered, paged query over the objects of a ref. ${QUERY_PROJECT_SCOPE}`, [
|
|
257
|
-
...
|
|
312
|
+
...REF_READ,
|
|
258
313
|
"malformed-query",
|
|
259
314
|
"over-bound",
|
|
260
315
|
"text-search-unavailable",
|
|
@@ -263,11 +318,11 @@ var ROUTE_DOCS = Object.freeze({
|
|
|
263
318
|
"stale-continuation",
|
|
264
319
|
"head-moved"
|
|
265
320
|
]),
|
|
266
|
-
aggregateObjects: doc(`Runs an aggregate over the objects of a ref: a count, or a minimum, maximum or sum of one numeric property, answered as one value, or, with groupBy, a count or a sum grouped by type or by a property's value, or a count grouped by structural parent, answered as groups. ${QUERY_PROJECT_SCOPE}`, [...
|
|
267
|
-
discoverVerbs: doc("Lists the verbs an object may be given.",
|
|
268
|
-
readHistory: doc("Reads one object's history of changes.", [...
|
|
269
|
-
mutate: doc('Creates, changes or deletes an object on a branch. For a property update, `from` is the value the caller expects now; a mismatch is refused as `conflict`, and `{"absent": true}` clears the property.', [...
|
|
270
|
-
mutateBatch: doc('Applies a list of object and edge operations to a branch in one save, one commit and one audit record, or none of them: a refused operation refuses the whole batch and writes nothing. An edge may name an object created earlier in the same batch. A batch with more operations than the maximum is refused as invalid-request naming input.operations, before any write. For a property update, `from` is the value the caller expects now; a mismatch is refused as `conflict`, and `{"absent": true}` clears the property.', [...
|
|
321
|
+
aggregateObjects: doc(`Runs an aggregate over the objects of a ref: a count, or a minimum, maximum or sum of one numeric property, answered as one value, or, with groupBy, a count or a sum grouped by type or by a property's value, or a count grouped by structural parent, answered as groups. ${QUERY_PROJECT_SCOPE}`, [...REF_READ, "malformed-query", "over-bound", "text-search-unavailable", "search-too-wide"]),
|
|
322
|
+
discoverVerbs: doc("Lists the verbs an object may be given.", REF_READ),
|
|
323
|
+
readHistory: doc("Reads one object's history of changes.", [...REF_READ, "invalid-continuation", "stale-continuation", "malformed-history-request"]),
|
|
324
|
+
mutate: doc('Creates, changes or deletes an object on the selected ref. A protected refusal means the change needs a branch and a merge. For a property update, `from` is the value the caller expects now; a mismatch is refused as `conflict`, and `{"absent": true}` clears the property.', [...OBJECT_WRITE, "plan-closed"]),
|
|
325
|
+
mutateBatch: doc('Applies a list of object and edge operations to a branch in one save, one commit and one audit record, or none of them: a refused operation refuses the whole batch and writes nothing. An edge may name an object created earlier in the same batch. A batch with more operations than the maximum is refused as invalid-request naming input.operations, before any write. For a property update, `from` is the value the caller expects now; a mismatch is refused as `conflict`, and `{"absent": true}` clears the property.', [...OBJECT_WRITE, "plan-closed"]),
|
|
271
326
|
createConnection: doc("Creates a connection to an external source system for the signed-in person: its mirror project and its service identity. The connection commits whether or not its types could be drafted, and the answer says which.", [...SIGNED_IN, "not-permitted", "organisation-not-active", "connection-exists"]),
|
|
272
327
|
listConnections: doc("Lists the connections whose mirror project the caller reads, each with its last run and whether the caller may start a run.", SIGNED_IN),
|
|
273
328
|
setConnectionCredential: doc("Stores the credential the connection reads the source system with, after the source system accepts it, and answers the upstream account and the time it was stored. The credential is never answered.", [...SCOPED, "credential-not-valid"]),
|
|
@@ -277,36 +332,48 @@ var ROUTE_DOCS = Object.freeze({
|
|
|
277
332
|
startImportRun: doc("Starts a run that imports the connection's source into its mirror project, and answers the run once its row has committed.", [...SCOPED, "import-running", "connection-revoked", "types-not-approved"]),
|
|
278
333
|
listImportRuns: doc("Lists the runs of a connection, newest first, or the one run named.", SCOPED),
|
|
279
334
|
closeImportRun: doc("Ends a running run: the connection's service identity as succeeded or failed, or the person who started it as failed.", [...SCOPED, "run-not-running"]),
|
|
280
|
-
previewDelete: doc("Previews deleting an object: the links the delete would remove, or the refusal it would meet. Changes nothing.", [...
|
|
281
|
-
recover: doc("Finds what an interrupted mutation did and finishes its record.",
|
|
282
|
-
executeVerb: doc("Runs a verb on an object and records its result.", [...
|
|
283
|
-
createBranch: doc("Creates a branch from a ref
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
335
|
+
previewDelete: doc("Previews deleting an object: the links the delete would remove, or the refusal it would meet. Changes nothing.", [...OBJECT_WRITE, "plan-closed"]),
|
|
336
|
+
recover: doc("Finds what an interrupted mutation did and finishes its record.", REF_READ),
|
|
337
|
+
executeVerb: doc("Runs a verb on an object and records its result.", [...OBJECT_WRITE, "plan-closed"]),
|
|
338
|
+
createBranch: doc("Creates a branch from a ref or an admitted current ref head.", [
|
|
339
|
+
...REF_WRITE,
|
|
340
|
+
"plan-closed",
|
|
341
|
+
"ref-exists",
|
|
342
|
+
"read-only-ref",
|
|
343
|
+
"concurrent-change",
|
|
344
|
+
"lock-unavailable",
|
|
345
|
+
"not-a-ref-head"
|
|
346
|
+
]),
|
|
347
|
+
merge: doc("Merges a reviewed head of a project branch or an organisation-ref source into main, or into the ref the optional target names.", [...REF_WRITE, "read-only-ref", "concurrent-change", "lock-unavailable", "not-a-ref-head"]),
|
|
348
|
+
readMergeConflicts: doc("Reads the conflicts a merge refused on.", REF_READ),
|
|
349
|
+
disposeRef: doc("Disposes a branch that is no longer wanted.", [
|
|
350
|
+
...WRITE,
|
|
351
|
+
"concurrent-change",
|
|
352
|
+
"lock-unavailable"
|
|
353
|
+
]),
|
|
287
354
|
listProjects: doc("Lists every project the caller may read in the organisation the session is attached to, with its namespace.", SIGNED_IN),
|
|
288
|
-
listRefs: doc("Lists the refs of a project, each with its head: readable with a hash, withheld when the caller may not read the ref, or unread past the first 50 refs.", SCOPED),
|
|
355
|
+
listRefs: doc("Lists the refs of a project, each with its head: readable with a hash, withheld when the caller may not read the ref, or unread past the first 50 refs.", [...SCOPED, "organisation-not-ready"]),
|
|
289
356
|
readCatalogue: doc("Reads the published catalogue of a project's namespace.", SCOPED),
|
|
290
357
|
readPendingProposal: doc("Reads the proposal waiting for review on a branch, if any.", SCOPED),
|
|
291
|
-
submitProposal: doc("Submits a branch for review.", [...
|
|
358
|
+
submitProposal: doc("Submits a branch for review.", [...REF_READ, "proposal-open", "no-commits"]),
|
|
292
359
|
createServiceIdentity: doc("Creates a service identity in an organisation.", [...SIGNED_IN, "not-permitted", "capability-missing", "duplicate-name"]),
|
|
293
360
|
revokeServiceIdentity: doc("Revokes a service identity.", [...SIGNED_IN, "not-permitted", "service_identity.revoke"]),
|
|
294
361
|
issueServiceCredential: doc("Issues a credential for a service identity.", [...SIGNED_IN, "not-permitted", "capability-missing"]),
|
|
295
362
|
revokeServiceCredential: doc("Revokes a service identity's credential.", [...SIGNED_IN, "not-permitted", "capability-missing"]),
|
|
296
363
|
grantMembership: doc("Grants a principal a role in a scope.", [...SIGNED_IN, "not-permitted", "above-caller-role", "membership-exists", "no-such-principal"]),
|
|
297
|
-
revokeMembership: doc("Revokes a principal's membership of a scope.", [...SIGNED_IN, "not-permitted", "last-administrator", "no-such-membership", "erasure-not-permitted"]),
|
|
364
|
+
revokeMembership: doc("Revokes a principal's membership of a scope; at organisation scope, also revokes their memberships in its projects.", [...SIGNED_IN, "not-permitted", "last-administrator", "no-such-membership", "erasure-not-permitted"]),
|
|
298
365
|
setModelConfiguration: doc("Sets the model configuration an organisation's agents use.", [...SIGNED_IN, "not-permitted", "capability-missing", "window-out-of-range", "max-session-out-of-range"]),
|
|
299
366
|
readDisplayNames: doc("Reads the display names of principals the caller may see.", SIGNED_IN),
|
|
300
367
|
listMembers: doc("Lists the members of a project.", SCOPED),
|
|
301
368
|
changeMembershipRole: doc("Changes a principal's role in a scope.", [...SIGNED_IN, "not-permitted", "above-caller-role", "last-administrator", "no-such-membership"]),
|
|
302
369
|
listOrganisationMembers: doc("Lists the memberships of the caller's organisation and of the projects of it the caller may read.", SCOPED),
|
|
303
370
|
searchPeople: doc("Finds the people of the caller's organisation whose name has a word starting with the query.", [...SIGNED_IN, "invalid-query"]),
|
|
304
|
-
searchObjectReaders: doc("Finds the people who can read an object on a ref, by a name prefix.", [...
|
|
305
|
-
listSubscribers: doc("Lists the subscriptions on an object.",
|
|
306
|
-
addSubscriber: doc("Adds a person to an object's subscriptions as owner, approver or watcher, when the type's `subscriptionRoles` admits that role. The declaration may set maxima; owner is limited to one. With no declaration, only watchers are admitted.", [...
|
|
307
|
-
removeSubscriber: doc("Removes a person's subscription to an object in a role.", [...
|
|
308
|
-
listComments: doc("Lists the comments on an object, oldest first, a page at a time.", [...
|
|
309
|
-
addComment: doc("Adds a comment to an object, naming the people it mentions.", [...
|
|
371
|
+
searchObjectReaders: doc("Finds the people who can read an object on a ref, by a name prefix.", [...REF_READ, "invalid-query", "invalid-ref"]),
|
|
372
|
+
listSubscribers: doc("Lists the subscriptions on an object.", REF_READ),
|
|
373
|
+
addSubscriber: doc("Adds a person to an object's subscriptions as owner, approver or watcher, when the type's `subscriptionRoles` admits that role. The declaration may set maxima; owner is limited to one. With no declaration, only watchers are admitted.", [...REF_READ, "limit-reached", "role-not-admitted", "unknown-person", "not-permitted", "invalid-ref"]),
|
|
374
|
+
removeSubscriber: doc("Removes a person's subscription to an object in a role.", [...REF_READ, "subscription-absent", "not-permitted", "invalid-ref"]),
|
|
375
|
+
listComments: doc("Lists the comments on an object, oldest first, a page at a time.", [...REF_READ, "invalid-query"]),
|
|
376
|
+
addComment: doc("Adds a comment to an object, naming the people it mentions.", [...REF_WRITE, "invalid-body", "invalid-mention", "unknown-person", "invalid-ref"]),
|
|
310
377
|
listServiceIdentities: doc("Lists the service identities of the caller's organisation, for a caller who administers them.", SCOPED),
|
|
311
378
|
createInvitation: doc("Invites an email address to the caller's organisation in a role, for a caller who administers its members.", [...SIGNED_IN, "capability-missing", "above-caller-role", "invalid-email", "already-invited", "domain-not-allowed"]),
|
|
312
379
|
listInvitations: doc("Lists the pending invitations of the caller's organisation, for a caller who administers its members.", [...SIGNED_IN, "capability-missing"]),
|
|
@@ -320,25 +387,43 @@ var ROUTE_DOCS = Object.freeze({
|
|
|
320
387
|
reissuePlatformInvitation: doc("Replaces the code and the expiry of a pending platform invitation and answers the new link, for a platform administrator.", [...SIGNED_IN, "capability-missing", "no-such-invitation", "invitation-not-pending"]),
|
|
321
388
|
readWebOrigin: doc("Reads the origin of the deployment's web application, or null when the host is given none.", SIGNED_IN),
|
|
322
389
|
readCallerCapabilities: doc("Lists the capabilities the caller holds in the token's organisation and its projects, and the platform capability for a platform administrator.", [...SIGNED_IN]),
|
|
323
|
-
queryGraph: doc(`Walks the edges from a start of addresses or an object set, and answers the objects reached with every hop among them. One start address with one hop step of depth 1 answers that object's connections, with a marker for each kind of connection whose far object the caller cannot read, and pages with a continuation. For an object-set start, omitting input.start.set.projects reads every project the caller can read on the selected ref; selector.projectId does not narrow the start set. To limit it to one project, include "projects":["<projectId>"] in input.start.set.`, [...
|
|
390
|
+
queryGraph: doc(`Walks the edges from a start of addresses or an object set, and answers the objects reached with every hop among them. One start address with one hop step of depth 1 answers that object's connections, with a marker for each kind of connection whose far object the caller cannot read, and pages with a continuation. For an object-set start, omitting input.start.set.projects reads every project the caller can read on the selected ref; selector.projectId does not narrow the start set. To limit it to one project, include "projects":["<projectId>"] in input.start.set.`, [...REF_READ, "malformed-query", "over-bound", "text-search-unavailable", "search-too-wide", "invalid-continuation", "stale-continuation", "head-moved"]),
|
|
324
391
|
readStructure: doc("Reads the structure of a type's objects as a tree: every root, one object's subtree or one object's ancestors, each placement an occurrence. A chosen relationship or one-step view places the type itself, and the types above it follow their own declared relationships.", [
|
|
325
|
-
...
|
|
392
|
+
...REF_READ,
|
|
326
393
|
"malformed-query",
|
|
327
394
|
"view-not-drawable",
|
|
328
395
|
"over-bound",
|
|
329
396
|
"head-moved"
|
|
330
397
|
]),
|
|
331
|
-
findPaths: doc("Finds every shortest path between two objects within a length, answered as the hops each path follows.", [...
|
|
398
|
+
findPaths: doc("Finds every shortest path between two objects within a length, answered as the hops each path follows.", [...REF_READ, "malformed-query", "over-bound", "head-moved"]),
|
|
332
399
|
listProposals: doc("Lists the proposals of a project.", SCOPED),
|
|
333
400
|
readProposal: doc("Reads one proposal.", SCOPED),
|
|
334
401
|
refuseProposal: doc("Refuses a proposal and returns its branch to its author.", [...SCOPED, "proposal-not-pending"]),
|
|
335
|
-
readBranchDiff: doc("Reads what a proposal's branch changes against its target.",
|
|
336
|
-
diffBranches: doc("Reads what one ref changes against another.",
|
|
402
|
+
readBranchDiff: doc("Reads what a proposal's branch changes against its target.", REF_READ),
|
|
403
|
+
diffBranches: doc("Reads what one ref changes against another.", REF_READ),
|
|
337
404
|
readBranchHistory: doc("Reads a branch's history of commits.", [...SCOPED, "invalid-continuation", "stale-continuation", "malformed-history-request"]),
|
|
338
405
|
listAudit: doc("Lists the audit records of a project.", [...SCOPED, "invalid-continuation"]),
|
|
339
|
-
readRefHead: doc("Reads the head of a ref.",
|
|
406
|
+
readRefHead: doc("Reads the head of a ref.", REF_READ),
|
|
340
407
|
inspectBranchOperation: doc("Reads the state of a branch operation the caller started.", SCOPED),
|
|
341
|
-
abandonBranch: doc("
|
|
408
|
+
abandonBranch: doc("Refuses branch abandonment because this operation is not available in this release.", [
|
|
409
|
+
...WRITE,
|
|
410
|
+
"not-in-this-release"
|
|
411
|
+
]),
|
|
412
|
+
addRefRule: doc("Adds a ref protection rule to the selected project and answers the full rule. Repeating the same pattern and consequence returns the existing rule, ignoring pattern letter case. Consequences are merge-only and locked-rows-only; an invalid pattern or consequence answers invalid-request naming that field.", SCOPED),
|
|
413
|
+
listRefRules: doc("Lists only the selected project's visible ref protection rules, including each rule's identifier, pattern and consequence.", SCOPED),
|
|
414
|
+
removeRefRule: doc("Removes a rule by identifier from the selected project and answers its ruleId. An absent or unreadable identifier, or one belonging to another project, answers not-found.", SCOPED),
|
|
415
|
+
addOrganisationRule: doc("Adds a ref protection rule in the attached organisation and answers the full rule. Repeating the same pattern and consequence returns the existing rule, ignoring pattern letter case. An invalid pattern or consequence answers invalid-request naming that field.", SCOPED),
|
|
416
|
+
listOrganisationRules: doc("Lists the attached organisation's visible ref rules, including identifier, pattern and consequence.", SCOPED),
|
|
417
|
+
removeOrganisationRule: doc("Removes a rule by identifier from the attached organisation and answers its ruleId. An absent, unreadable or project-rule identifier answers not-found.", SCOPED),
|
|
418
|
+
createOrganisationRef: doc("Creates a ref at the organisation's trunk head and answers its name, readOnly and creation attribution. The optional readOnly flag defaults to false; the name is one non-reserved ref segment.", [...WRITE, "ref-exists", "read-only-ref", "organisation-not-ready"]),
|
|
419
|
+
listOrganisationRefs: doc("Lists visible refs in the attached organisation, including each name, readOnly and creation attribution.", SCOPED),
|
|
420
|
+
deleteOrganisationRef: doc("Deletes a writable ref from the attached organisation and answers its name. A read-only ref cannot be deleted.", [...REF_WRITE, "read-only-ref"]),
|
|
421
|
+
markOrganisationRefReadOnly: doc("Marks a ref in the attached organisation read-only and answers the full ref. An absent or unreadable name answers not-found.", SCOPED),
|
|
422
|
+
setObjectLock: doc("Sets an object's lock on the selected project ref to none, merge-only or frozen and answers objectId and lock. The lock also applies to its existing structural child edges in that project; none lifts the lock. New children on a live ref are not thereby frozen. Use a read-only organisation ref for a fixed baseline. An unknown lock answers invalid-request at lock.", [...REF_WRITE, "read-only-ref", "concurrent-change", "lock-unavailable"]),
|
|
423
|
+
readAgentCeiling: doc("Reads the selected project's maximum agent role as { ceiling }: contributor or maintainer. An absent or unreadable project answers not-found.", SCOPED),
|
|
424
|
+
setAgentCeiling: doc("Sets the selected project's maximum agent role to contributor or maintainer and answers { ceiling }. An unknown role answers invalid-request at ceiling.", SCOPED),
|
|
425
|
+
requestSchemaUpdate: doc("Records a schema update request for a project branch or organisation ref and answers its state and attribution. Execution is separate. A branch whose name contains a slash cannot request a schema update today. The trunk main answers invalid-request at ref; an unreachable ref answers not-found.", SCOPED),
|
|
426
|
+
readSchemaUpdateRequest: doc("Reads the caller's latest schema update request for the ref in the token's organisation, or null. Project read access is not required. A branch whose name contains a slash cannot read its request today. The trunk main answers invalid-request at ref.", SCOPED),
|
|
342
427
|
openAgentSession: doc("Opens an agent session on a project.", [...SCOPED, "invalid-configuration"]),
|
|
343
428
|
listAgentSessions: doc("Lists the caller's agent sessions on a project.", SCOPED),
|
|
344
429
|
readAgentSession: doc("Reads one agent session and its runs.", SCOPED),
|
|
@@ -416,7 +501,7 @@ var SCHEMAS = {
|
|
|
416
501
|
recover: { "type": "object", "properties": { "correlationId": { "type": "string" } }, "required": ["correlationId"], "additionalProperties": false },
|
|
417
502
|
executeVerb: { "type": "object", "properties": { "correlation": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "mint" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "sent" }, "correlationId": { "type": "string" } }, "required": ["kind", "correlationId"], "additionalProperties": false }] }, "verb": { "type": "object", "properties": { "typeKey": { "type": "string" }, "typeVersion": { "type": "number" } }, "required": ["typeKey", "typeVersion"], "additionalProperties": false }, "subjectIds": { "type": "array", "items": { "type": "string" } }, "input": {} }, "required": ["correlation", "verb", "subjectIds", "input"], "additionalProperties": false },
|
|
418
503
|
createBranch: { "type": "object", "properties": { "correlation": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "mint" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "sent" }, "correlationId": { "type": "string" } }, "required": ["kind", "correlationId"], "additionalProperties": false }] }, "name": { "type": "string" }, "from": { "oneOf": [{ "type": "object", "properties": { "ref": { "type": "string" } }, "required": ["ref"], "additionalProperties": false }, { "type": "object", "properties": { "hash": { "type": "string" } }, "required": ["hash"], "additionalProperties": false }] } }, "required": ["correlation", "name"], "additionalProperties": false },
|
|
419
|
-
merge: { "type": "object", "properties": { "correlation": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "mint" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "sent" }, "correlationId": { "type": "string" } }, "required": ["kind", "correlationId"], "additionalProperties": false }] }, "sourceHash": { "type": "string" }, "message": { "type": "string" }, "name": { "type": "string" } }, "required": ["correlation", "sourceHash", "message"], "additionalProperties": false },
|
|
504
|
+
merge: { "type": "object", "properties": { "correlation": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "mint" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "sent" }, "correlationId": { "type": "string" } }, "required": ["kind", "correlationId"], "additionalProperties": false }] }, "sourceHash": { "type": "string" }, "message": { "type": "string" }, "name": { "type": "string" }, "source": { "type": "string" }, "target": { "type": "string" } }, "required": ["correlation", "sourceHash", "message"], "additionalProperties": false },
|
|
420
505
|
readMergeConflicts: { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false },
|
|
421
506
|
disposeRef: { "type": "object", "properties": { "correlation": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "mint" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "sent" }, "correlationId": { "type": "string" } }, "required": ["kind", "correlationId"], "additionalProperties": false }] }, "name": { "type": "string" }, "atHash": { "type": "string" } }, "required": ["correlation", "name", "atHash"], "additionalProperties": false },
|
|
422
507
|
listProjects: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
|
|
@@ -461,6 +546,21 @@ var SCHEMAS = {
|
|
|
461
546
|
readRefHead: { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false },
|
|
462
547
|
inspectBranchOperation: { "type": "object", "properties": { "correlationId": { "type": "string" } }, "required": ["correlationId"], "additionalProperties": false },
|
|
463
548
|
abandonBranch: { "type": "object", "properties": { "correlation": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "mint" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "sent" }, "correlationId": { "type": "string" } }, "required": ["kind", "correlationId"], "additionalProperties": false }] }, "name": { "type": "string" }, "atHash": { "type": "string" } }, "required": ["correlation", "name", "atHash"], "additionalProperties": false },
|
|
549
|
+
addRefRule: { "type": "object", "properties": { "pattern": { "type": "string" }, "consequence": { "enum": ["merge-only", "locked-rows-only"] } }, "required": ["pattern", "consequence"], "additionalProperties": false },
|
|
550
|
+
listRefRules: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
|
|
551
|
+
removeRefRule: { "type": "object", "properties": { "ruleId": { "type": "string" } }, "required": ["ruleId"], "additionalProperties": false },
|
|
552
|
+
addOrganisationRule: { "type": "object", "properties": { "pattern": { "type": "string" }, "consequence": { "enum": ["merge-only", "locked-rows-only"] } }, "required": ["pattern", "consequence"], "additionalProperties": false },
|
|
553
|
+
listOrganisationRules: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
|
|
554
|
+
removeOrganisationRule: { "type": "object", "properties": { "ruleId": { "type": "string" } }, "required": ["ruleId"], "additionalProperties": false },
|
|
555
|
+
createOrganisationRef: { "type": "object", "properties": { "name": { "type": "string" }, "readOnly": { "type": "boolean" } }, "required": ["name"], "additionalProperties": false },
|
|
556
|
+
listOrganisationRefs: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
|
|
557
|
+
deleteOrganisationRef: { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false },
|
|
558
|
+
markOrganisationRefReadOnly: { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"], "additionalProperties": false },
|
|
559
|
+
setObjectLock: { "type": "object", "properties": { "objectId": { "type": "string" }, "lock": { "enum": ["none", "merge-only", "frozen"] } }, "required": ["objectId", "lock"], "additionalProperties": false },
|
|
560
|
+
readAgentCeiling: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
|
|
561
|
+
setAgentCeiling: { "type": "object", "properties": { "ceiling": { "enum": ["contributor", "maintainer"] } }, "required": ["ceiling"], "additionalProperties": false },
|
|
562
|
+
requestSchemaUpdate: { "type": "object", "properties": { "ref": { "type": "string" } }, "required": ["ref"], "additionalProperties": false },
|
|
563
|
+
readSchemaUpdateRequest: { "type": "object", "properties": { "ref": { "type": "string" } }, "required": ["ref"], "additionalProperties": false },
|
|
464
564
|
openAgentSession: { "type": "object", "properties": { "agent": { "enum": ["object", "ontology"] } }, "required": ["agent"], "additionalProperties": false },
|
|
465
565
|
listAgentSessions: { "type": "object", "properties": { "agent": { "enum": ["object", "ontology"] } }, "required": ["agent"], "additionalProperties": false },
|
|
466
566
|
readAgentSession: { "type": "object", "properties": { "agentSessionId": { "type": "string" } }, "required": ["agentSessionId"], "additionalProperties": false },
|
|
@@ -587,6 +687,21 @@ var EXAMPLES = {
|
|
|
587
687
|
readRefHead: { "name": "<name>" },
|
|
588
688
|
inspectBranchOperation: { "correlationId": "<correlationId>" },
|
|
589
689
|
abandonBranch: { "correlation": { "kind": "mint" }, "name": "<name>", "atHash": "<atHash>" },
|
|
690
|
+
addRefRule: { "pattern": "<pattern>", "consequence": "merge-only" },
|
|
691
|
+
listRefRules: {},
|
|
692
|
+
removeRefRule: { "ruleId": "<ruleId>" },
|
|
693
|
+
addOrganisationRule: { "pattern": "<pattern>", "consequence": "merge-only" },
|
|
694
|
+
listOrganisationRules: {},
|
|
695
|
+
removeOrganisationRule: { "ruleId": "<ruleId>" },
|
|
696
|
+
createOrganisationRef: { "name": "<name>" },
|
|
697
|
+
listOrganisationRefs: {},
|
|
698
|
+
deleteOrganisationRef: { "name": "<name>" },
|
|
699
|
+
markOrganisationRefReadOnly: { "name": "<name>" },
|
|
700
|
+
setObjectLock: { "objectId": "<objectId>", "lock": "none" },
|
|
701
|
+
readAgentCeiling: {},
|
|
702
|
+
setAgentCeiling: { "ceiling": "contributor" },
|
|
703
|
+
requestSchemaUpdate: { "ref": "<ref>" },
|
|
704
|
+
readSchemaUpdateRequest: { "ref": "<ref>" },
|
|
590
705
|
openAgentSession: { "agent": "object" },
|
|
591
706
|
listAgentSessions: { "agent": "object" },
|
|
592
707
|
readAgentSession: { "agentSessionId": "<agentSessionId>" },
|
|
@@ -634,7 +749,7 @@ var EXAMPLES = {
|
|
|
634
749
|
var ROUTE_INPUT_EXAMPLES = deepFreeze(EXAMPLES);
|
|
635
750
|
|
|
636
751
|
// packages/api-contract/dist/routes.js
|
|
637
|
-
var PROTOCOL_VERSION =
|
|
752
|
+
var PROTOCOL_VERSION = 24;
|
|
638
753
|
var VERSION_HEADER = "oe2-protocol-version";
|
|
639
754
|
var TOKEN_HEADER = "authorization";
|
|
640
755
|
var IDEMPOTENCY_HEADER = "oe2-idempotency-key";
|
|
@@ -734,6 +849,21 @@ var ROUTES = Object.freeze({
|
|
|
734
849
|
readRefHead: route({ name: "readRefHead", method: "POST", path: "/branches/head", group: "read", selector: "project", subject: "project", idempotent: false, admission: admitting("user", "service", "run-explore", "run-apply", "run-types", "client"), versioned: true, module: "branches-sdk", capability: "branches.head" }),
|
|
735
850
|
inspectBranchOperation: route({ name: "inspectBranchOperation", method: "POST", path: "/branch-inspections", group: "branch", selector: "project", subject: "project", idempotent: false, admission: admitting("user", "service", "client"), versioned: true, module: "branches-sdk", capability: "branches.inspection" }),
|
|
736
851
|
abandonBranch: route({ name: "abandonBranch", method: "POST", path: "/branch-abandonments", group: "branch", selector: "project", subject: "project", idempotent: true, admission: admitting("user", "service", "client"), versioned: true, module: "branches-sdk", capability: "branches.abandonment" }),
|
|
852
|
+
addRefRule: route({ name: "addRefRule", method: "POST", path: "/ref-rules", group: "administration", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.ref-rules" }),
|
|
853
|
+
listRefRules: route({ name: "listRefRules", method: "POST", path: "/projects/ref-rules", group: "read", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.ref-rules" }),
|
|
854
|
+
removeRefRule: route({ name: "removeRefRule", method: "POST", path: "/ref-rule-removals", group: "administration", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.ref-rules" }),
|
|
855
|
+
addOrganisationRule: route({ name: "addOrganisationRule", method: "POST", path: "/organisation-ref-rules", group: "administration", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.organisation-ref-rules" }),
|
|
856
|
+
listOrganisationRules: route({ name: "listOrganisationRules", method: "POST", path: "/organisation-ref-rules/list", group: "read", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.organisation-ref-rules" }),
|
|
857
|
+
removeOrganisationRule: route({ name: "removeOrganisationRule", method: "POST", path: "/organisation-ref-rule-removals", group: "administration", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.organisation-ref-rules" }),
|
|
858
|
+
createOrganisationRef: route({ name: "createOrganisationRef", method: "POST", path: "/organisation-refs", group: "administration", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.organisation-refs" }),
|
|
859
|
+
listOrganisationRefs: route({ name: "listOrganisationRefs", method: "POST", path: "/organisation-refs/list", group: "read", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.organisation-refs" }),
|
|
860
|
+
deleteOrganisationRef: route({ name: "deleteOrganisationRef", method: "POST", path: "/organisation-ref-deletions", group: "administration", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.organisation-refs" }),
|
|
861
|
+
markOrganisationRefReadOnly: route({ name: "markOrganisationRefReadOnly", method: "POST", path: "/organisation-ref-read-only", group: "administration", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.organisation-refs" }),
|
|
862
|
+
setObjectLock: route({ name: "setObjectLock", method: "POST", path: "/object-locks", group: "write", selector: "object", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "objects-sdk", capability: "objects.locks" }),
|
|
863
|
+
readAgentCeiling: route({ name: "readAgentCeiling", method: "POST", path: "/projects/agent-ceiling", group: "read", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.agent-ceiling" }),
|
|
864
|
+
setAgentCeiling: route({ name: "setAgentCeiling", method: "POST", path: "/agent-ceiling", group: "administration", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.agent-ceiling" }),
|
|
865
|
+
requestSchemaUpdate: route({ name: "requestSchemaUpdate", method: "POST", path: "/schema-update-requests", group: "branch", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "branches-sdk", capability: "branches.schema-update" }),
|
|
866
|
+
readSchemaUpdateRequest: route({ name: "readSchemaUpdateRequest", method: "POST", path: "/schema-update-requests/read", group: "branch", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "branches-sdk", capability: "branches.schema-update" }),
|
|
737
867
|
openAgentSession: route({ name: "openAgentSession", method: "POST", path: "/agent-sessions", group: "agent", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "agents-sdk", capability: "agents.session" }),
|
|
738
868
|
listAgentSessions: route({ name: "listAgentSessions", method: "POST", path: "/agent-sessions/list", group: "agent", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "agents-sdk", capability: "agents.sessionList" }),
|
|
739
869
|
readAgentSession: route({ name: "readAgentSession", method: "POST", path: "/agent-sessions/read", group: "agent", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "agents-sdk", capability: "agents.sessionRead" }),
|
|
@@ -853,6 +983,21 @@ var ROUTE_CARRIES_CREDENTIAL = Object.freeze({
|
|
|
853
983
|
readRefHead: false,
|
|
854
984
|
inspectBranchOperation: false,
|
|
855
985
|
abandonBranch: false,
|
|
986
|
+
addRefRule: false,
|
|
987
|
+
listRefRules: false,
|
|
988
|
+
removeRefRule: false,
|
|
989
|
+
addOrganisationRule: false,
|
|
990
|
+
listOrganisationRules: false,
|
|
991
|
+
removeOrganisationRule: false,
|
|
992
|
+
createOrganisationRef: false,
|
|
993
|
+
listOrganisationRefs: false,
|
|
994
|
+
deleteOrganisationRef: false,
|
|
995
|
+
markOrganisationRefReadOnly: false,
|
|
996
|
+
setObjectLock: false,
|
|
997
|
+
readAgentCeiling: false,
|
|
998
|
+
setAgentCeiling: false,
|
|
999
|
+
requestSchemaUpdate: false,
|
|
1000
|
+
readSchemaUpdateRequest: false,
|
|
856
1001
|
openAgentSession: false,
|
|
857
1002
|
listAgentSessions: false,
|
|
858
1003
|
readAgentSession: false,
|
|
@@ -908,11 +1053,11 @@ var CLIENT_SCOPES = Object.freeze({
|
|
|
908
1053
|
"objects.write": Object.freeze({ capabilities: Object.freeze(["objects.write", "objects.verb"]), consentLine: "Create, change and delete objects, and run actions on them, as you." }),
|
|
909
1054
|
"branches.read": Object.freeze({ capabilities: Object.freeze(["branches.head", "branches.diff", "branches.history", "branches.conflicts", "branches.inspection", "branches.pendingProposal", "branches.proposalList", "branches.proposalRead", "branches.proposalDiff", "branches.list"]), consentLine: "Read your branches, their history and proposals." }),
|
|
910
1055
|
"branches.write": Object.freeze({ capabilities: Object.freeze(["branches.create", "branches.abandonment", "branches.proposalSubmit", "branches.proposalRefusal", "branches.head", "branches.diff", "branches.history", "branches.conflicts", "branches.inspection", "branches.pendingProposal", "branches.proposalList", "branches.proposalRead", "branches.proposalDiff", "branches.list"]), consentLine: "Create and abandon branches, submit and refuse proposals, and read your branches, as you." }),
|
|
911
|
-
"branches.manage": Object.freeze({ capabilities: Object.freeze(["branches.merge", "branches.disposal", "objects.recovery"]), consentLine: "Merge branches into
|
|
1056
|
+
"branches.manage": Object.freeze({ capabilities: Object.freeze(["branches.merge", "branches.disposal", "objects.recovery"]), consentLine: "Merge branches into the branches and trunks you may change, delete branches and other refs, and recover changes, as you." }),
|
|
912
1057
|
offline_access: Object.freeze({ capabilities: Object.freeze([]), consentLine: "Stay connected when you are away, until you disconnect it." })
|
|
913
1058
|
});
|
|
914
1059
|
|
|
915
|
-
// packages/sdk-
|
|
1060
|
+
// packages/sdk-dispatch/dist/explain.js
|
|
916
1061
|
function explainKind(kind) {
|
|
917
1062
|
if (!Object.hasOwn(BY_KIND, kind)) {
|
|
918
1063
|
throw new Error(`the refusal kind ${JSON.stringify(kind)} has no entry in the refusal catalogue`);
|
|
@@ -992,10 +1137,10 @@ function unauthenticatedEnvelope() {
|
|
|
992
1137
|
return { version: PROTOCOL_VERSION, refusal: explainedRefusalOf({ kind: "unauthenticated" }), correlationId: null };
|
|
993
1138
|
}
|
|
994
1139
|
|
|
995
|
-
// packages/sdk-
|
|
1140
|
+
// packages/sdk-dispatch/dist/socket-transport.js
|
|
996
1141
|
import { request } from "node:http";
|
|
997
1142
|
|
|
998
|
-
// packages/sdk-
|
|
1143
|
+
// packages/sdk-dispatch/dist/response.js
|
|
999
1144
|
function responseOf(status, text, reason) {
|
|
1000
1145
|
let read = false;
|
|
1001
1146
|
const members = {
|
|
@@ -1025,7 +1170,7 @@ function responseOf(status, text, reason) {
|
|
|
1025
1170
|
});
|
|
1026
1171
|
}
|
|
1027
1172
|
|
|
1028
|
-
// packages/sdk-
|
|
1173
|
+
// packages/sdk-dispatch/dist/socket-transport.js
|
|
1029
1174
|
var REQUEST_DEADLINE_MS = 1e4;
|
|
1030
1175
|
var HostOutcomeUnknown = class extends Error {
|
|
1031
1176
|
path;
|
|
@@ -1120,7 +1265,7 @@ function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
|
|
|
1120
1265
|
let written = false;
|
|
1121
1266
|
let settled = false;
|
|
1122
1267
|
let deadline = null;
|
|
1123
|
-
const
|
|
1268
|
+
const settle2 = (answer) => {
|
|
1124
1269
|
if (settled) {
|
|
1125
1270
|
return;
|
|
1126
1271
|
}
|
|
@@ -1131,7 +1276,7 @@ function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
|
|
|
1131
1276
|
answer();
|
|
1132
1277
|
};
|
|
1133
1278
|
const lost = (error) => {
|
|
1134
|
-
|
|
1279
|
+
settle2(() => {
|
|
1135
1280
|
reject(written ? new HostOutcomeUnknown(path, "connection-lost", `the connection to the host was lost after the request to ${path} was sent`) : error);
|
|
1136
1281
|
});
|
|
1137
1282
|
};
|
|
@@ -1152,7 +1297,7 @@ function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
|
|
|
1152
1297
|
}
|
|
1153
1298
|
const status = incoming.statusCode;
|
|
1154
1299
|
const reason = incoming.statusMessage;
|
|
1155
|
-
|
|
1300
|
+
settle2(() => {
|
|
1156
1301
|
if (status === void 0) {
|
|
1157
1302
|
reject(new Error("the host's response carried no status"));
|
|
1158
1303
|
return;
|
|
@@ -1162,7 +1307,7 @@ function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
|
|
|
1162
1307
|
});
|
|
1163
1308
|
});
|
|
1164
1309
|
deadline = setTimeout(() => {
|
|
1165
|
-
|
|
1310
|
+
settle2(() => {
|
|
1166
1311
|
reject(new HostOutcomeUnknown(path, "deadline", `the host did not answer ${path} within the deadline of ${String(deadlineMs)} ms`));
|
|
1167
1312
|
});
|
|
1168
1313
|
outgoing.destroy();
|
|
@@ -1320,7 +1465,7 @@ function createHostStreamFetch(socketPath, headDeadlineMs = REQUEST_DEADLINE_MS)
|
|
|
1320
1465
|
};
|
|
1321
1466
|
}
|
|
1322
1467
|
|
|
1323
|
-
// packages/sdk-
|
|
1468
|
+
// packages/sdk-dispatch/dist/call.js
|
|
1324
1469
|
function isEnvelope(value) {
|
|
1325
1470
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1326
1471
|
return false;
|
|
@@ -1425,7 +1570,7 @@ async function* callStreamed(transport, origin, route2, body, token, signal) {
|
|
|
1425
1570
|
}
|
|
1426
1571
|
}
|
|
1427
1572
|
|
|
1428
|
-
// packages/sdk-
|
|
1573
|
+
// packages/sdk-dispatch/dist/module-factory.js
|
|
1429
1574
|
function freezeDoc(doc2) {
|
|
1430
1575
|
return Object.freeze({ does: doc2.does, refuses: Object.freeze([...doc2.refuses]) });
|
|
1431
1576
|
}
|
|
@@ -1462,7 +1607,7 @@ function createModuleFactory(entries6, transport, origin, token) {
|
|
|
1462
1607
|
return Object.freeze(Object.fromEntries(Object.entries(byCapability).map(([capability, methods]) => [capability, Object.freeze(methods)])));
|
|
1463
1608
|
}
|
|
1464
1609
|
|
|
1465
|
-
// packages/sdk-
|
|
1610
|
+
// packages/sdk-dispatch/dist/typed-client.js
|
|
1466
1611
|
function createTypedClient(names, entries6, transport, origin, token) {
|
|
1467
1612
|
const factory = createModuleFactory(entries6, transport, origin, token);
|
|
1468
1613
|
const byName = new Map(entries6.map((entry2) => [entry2.name, entry2]));
|
|
@@ -1481,7 +1626,7 @@ function createTypedClient(names, entries6, transport, origin, token) {
|
|
|
1481
1626
|
return Object.freeze(client);
|
|
1482
1627
|
}
|
|
1483
1628
|
|
|
1484
|
-
// packages/sdk-
|
|
1629
|
+
// packages/sdk-dispatch/dist/https-transport.js
|
|
1485
1630
|
import { request as request2 } from "node:https";
|
|
1486
1631
|
function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLINE_MS) {
|
|
1487
1632
|
const originUrl = new URL(origin);
|
|
@@ -1498,7 +1643,7 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
|
|
|
1498
1643
|
let settled = false;
|
|
1499
1644
|
let deadline = null;
|
|
1500
1645
|
const path = `${url.pathname}${url.search}`;
|
|
1501
|
-
const
|
|
1646
|
+
const settle2 = (answer) => {
|
|
1502
1647
|
if (settled) {
|
|
1503
1648
|
return;
|
|
1504
1649
|
}
|
|
@@ -1509,7 +1654,7 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
|
|
|
1509
1654
|
answer();
|
|
1510
1655
|
};
|
|
1511
1656
|
const lost = (error) => {
|
|
1512
|
-
|
|
1657
|
+
settle2(() => {
|
|
1513
1658
|
reject(written ? new HostOutcomeUnknown(path, "connection-lost", `the connection to the host was lost after the request to ${path} was sent`) : error);
|
|
1514
1659
|
});
|
|
1515
1660
|
};
|
|
@@ -1529,7 +1674,7 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
|
|
|
1529
1674
|
incoming.on("end", () => {
|
|
1530
1675
|
const status = incoming.statusCode;
|
|
1531
1676
|
const reason = incoming.statusMessage;
|
|
1532
|
-
|
|
1677
|
+
settle2(() => {
|
|
1533
1678
|
if (status === void 0) {
|
|
1534
1679
|
reject(new Error("the host's response carried no status"));
|
|
1535
1680
|
return;
|
|
@@ -1539,7 +1684,7 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
|
|
|
1539
1684
|
});
|
|
1540
1685
|
});
|
|
1541
1686
|
deadline = setTimeout(() => {
|
|
1542
|
-
|
|
1687
|
+
settle2(() => {
|
|
1543
1688
|
reject(new HostOutcomeUnknown(path, "deadline", `the host did not answer ${path} within the deadline of ${String(deadlineMs)} ms`));
|
|
1544
1689
|
});
|
|
1545
1690
|
outgoing.destroy();
|
|
@@ -1553,7 +1698,7 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
|
|
|
1553
1698
|
};
|
|
1554
1699
|
}
|
|
1555
1700
|
|
|
1556
|
-
// packages/sdk-
|
|
1701
|
+
// packages/sdk-dispatch/dist/token-routes.js
|
|
1557
1702
|
async function redeem(transport, origin, body) {
|
|
1558
1703
|
return call(transport, origin, "redeem", body, null, null);
|
|
1559
1704
|
}
|
|
@@ -1610,6 +1755,18 @@ var ADMIN_ROUTE_NAMES = Object.freeze([
|
|
|
1610
1755
|
"listAudit",
|
|
1611
1756
|
"createProject",
|
|
1612
1757
|
"createOrganisation",
|
|
1758
|
+
"addRefRule",
|
|
1759
|
+
"listRefRules",
|
|
1760
|
+
"removeRefRule",
|
|
1761
|
+
"addOrganisationRule",
|
|
1762
|
+
"listOrganisationRules",
|
|
1763
|
+
"removeOrganisationRule",
|
|
1764
|
+
"createOrganisationRef",
|
|
1765
|
+
"listOrganisationRefs",
|
|
1766
|
+
"deleteOrganisationRef",
|
|
1767
|
+
"markOrganisationRefReadOnly",
|
|
1768
|
+
"readAgentCeiling",
|
|
1769
|
+
"setAgentCeiling",
|
|
1613
1770
|
"createConnection",
|
|
1614
1771
|
"listConnections",
|
|
1615
1772
|
"setConnectionCredential",
|
|
@@ -1668,7 +1825,9 @@ var BRANCHES_ROUTE_NAMES = Object.freeze([
|
|
|
1668
1825
|
"readBranchHistory",
|
|
1669
1826
|
"readRefHead",
|
|
1670
1827
|
"inspectBranchOperation",
|
|
1671
|
-
"abandonBranch"
|
|
1828
|
+
"abandonBranch",
|
|
1829
|
+
"requestSchemaUpdate",
|
|
1830
|
+
"readSchemaUpdateRequest"
|
|
1672
1831
|
]);
|
|
1673
1832
|
function entries3() {
|
|
1674
1833
|
return BRANCHES_ROUTE_NAMES.map((name) => ROUTES[name]);
|
|
@@ -1739,7 +1898,15 @@ function exploreViewAddress(address, state) {
|
|
|
1739
1898
|
function projectAddress(organisationId, projectId, ref) {
|
|
1740
1899
|
return withSubject(projectBase(organisationId, projectId), { ref, q: null });
|
|
1741
1900
|
}
|
|
1742
|
-
var ORGANISATION_ADMIN_PAGES = Object.freeze([
|
|
1901
|
+
var ORGANISATION_ADMIN_PAGES = Object.freeze([
|
|
1902
|
+
"members",
|
|
1903
|
+
"service-identities",
|
|
1904
|
+
"clients",
|
|
1905
|
+
"agent-model",
|
|
1906
|
+
"connections",
|
|
1907
|
+
"refs",
|
|
1908
|
+
"projects/new"
|
|
1909
|
+
]);
|
|
1743
1910
|
function organisationAdminAddress(organisationId, page) {
|
|
1744
1911
|
return `/orgs/${encodeURIComponent(organisationId)}/${page}`;
|
|
1745
1912
|
}
|
|
@@ -1756,6 +1923,12 @@ function branchDiffAddress(organisationId, projectId, ref) {
|
|
|
1756
1923
|
|
|
1757
1924
|
// packages/addresses/dist/links.js
|
|
1758
1925
|
var ORGANISATION_PAGES = Object.freeze([...ORGANISATION_ADMIN_PAGES, "settings"]);
|
|
1926
|
+
function isLinkRef(ref, projectId) {
|
|
1927
|
+
if (ref === "main")
|
|
1928
|
+
return true;
|
|
1929
|
+
const parts = ref.split("/");
|
|
1930
|
+
return parts.length === 2 && parts[0] !== "" && parts[1] !== "" && (projectId === void 0 || parts[0] === projectId);
|
|
1931
|
+
}
|
|
1759
1932
|
var ADMITTED_PAGES = new Set(ORGANISATION_PAGES);
|
|
1760
1933
|
function isOrganisationPage(value) {
|
|
1761
1934
|
return ADMITTED_PAGES.has(value);
|
|
@@ -1872,7 +2045,8 @@ var OBJECTS_ROUTE_NAMES = [
|
|
|
1872
2045
|
"listComments",
|
|
1873
2046
|
"addComment",
|
|
1874
2047
|
"readApp",
|
|
1875
|
-
"listApps"
|
|
2048
|
+
"listApps",
|
|
2049
|
+
"setObjectLock"
|
|
1876
2050
|
];
|
|
1877
2051
|
function entries4() {
|
|
1878
2052
|
return OBJECTS_ROUTE_NAMES.map((name) => ROUTES[name]);
|
|
@@ -2804,14 +2978,14 @@ function explanationLines(heading, explanation) {
|
|
|
2804
2978
|
}
|
|
2805
2979
|
return lines;
|
|
2806
2980
|
}
|
|
2807
|
-
function refusalLines(refusal2,
|
|
2981
|
+
function refusalLines(refusal2, settle2, request3, host, reference) {
|
|
2808
2982
|
const lines = explanationLines(refusalHeading(refusal2), refusal2);
|
|
2809
2983
|
const allowed = allowedFieldOf(refusal2, request3);
|
|
2810
2984
|
if (request3 !== void 0 && allowed !== null && allowed.allowedKinds.length > 0 && allowed.discriminator !== void 0) {
|
|
2811
2985
|
lines.push(`allowed ${allowed.discriminator}: ${allowed.allowedKinds.join(", ")}`, `${request3.command} --help shows each shape`);
|
|
2812
2986
|
}
|
|
2813
2987
|
if (refusal2.kind === "unknown-outcome") {
|
|
2814
|
-
lines.push(`The operation may or may not have taken effect, and openeng will not repeat it. Settle it with: ${
|
|
2988
|
+
lines.push(`The operation may or may not have taken effect, and openeng will not repeat it. Settle it with: ${settle2}`);
|
|
2815
2989
|
}
|
|
2816
2990
|
if (refusal2.kind === "protocol-mismatch" && host !== void 0) {
|
|
2817
2991
|
const versions = `this CLI speaks protocol ${PROTOCOL_VERSION}; the host at ${host} speaks ${refusal2.versions.host}`;
|
|
@@ -2827,13 +3001,13 @@ function refusalLines(refusal2, settle, request3, host, reference) {
|
|
|
2827
3001
|
}
|
|
2828
3002
|
return lines;
|
|
2829
3003
|
}
|
|
2830
|
-
function refusalValue(refusal2,
|
|
3004
|
+
function refusalValue(refusal2, settle2, request3, host, reference) {
|
|
2831
3005
|
const referenced = reference === void 0 ? {} : { reference };
|
|
2832
3006
|
if (refusal2.kind === "protocol-mismatch") {
|
|
2833
3007
|
return { ...refusal2, clientVersion: PROTOCOL_VERSION, ...host === void 0 ? {} : { host }, ...referenced };
|
|
2834
3008
|
}
|
|
2835
3009
|
const allowed = allowedFieldOf(refusal2, request3);
|
|
2836
|
-
const settled = refusal2.kind === "unknown-outcome" ? { ...refusal2, settle } : refusal2;
|
|
3010
|
+
const settled = refusal2.kind === "unknown-outcome" ? { ...refusal2, settle: settle2 } : refusal2;
|
|
2837
3011
|
return allowed === null || allowed.allowedKinds.length === 0 ? { ...settled, ...referenced } : { ...settled, allowedKinds: allowed.allowedKinds, ...referenced };
|
|
2838
3012
|
}
|
|
2839
3013
|
function jsonLine(value) {
|
|
@@ -2937,12 +3111,12 @@ var render = (outcome, json, scope, host) => {
|
|
|
2937
3111
|
function failure(kind, exitCode, message, json) {
|
|
2938
3112
|
return json ? { exitCode, stdout: jsonLine({ error: { kind, message } }), stderr: "" } : { exitCode, stdout: "", stderr: textBlock([message]) };
|
|
2939
3113
|
}
|
|
2940
|
-
var outcomeOfEnvelope = (envelope,
|
|
3114
|
+
var outcomeOfEnvelope = (envelope, settle2, text, request3) => {
|
|
2941
3115
|
if ("refusal" in envelope) {
|
|
2942
3116
|
return {
|
|
2943
3117
|
kind: "refusal",
|
|
2944
3118
|
refusal: envelope.refusal,
|
|
2945
|
-
settle,
|
|
3119
|
+
settle: settle2,
|
|
2946
3120
|
...request3 === void 0 ? {} : { request: request3 },
|
|
2947
3121
|
...typeof envelope.correlationId === "string" ? { reference: envelope.correlationId } : {}
|
|
2948
3122
|
};
|
|
@@ -2960,9 +3134,9 @@ var outcomeOfRefusedResult = (result) => isRefusedResult2(result) ? { kind: "ref
|
|
|
2960
3134
|
function isRefusedResult2(value) {
|
|
2961
3135
|
return typeof value === "object" && value !== null && "kind" in value && value.kind === "refused" && "explanation" in value && "explains" in value;
|
|
2962
3136
|
}
|
|
2963
|
-
function outcomeOfRouteRefusal(refusal2,
|
|
3137
|
+
function outcomeOfRouteRefusal(refusal2, settle2, correlationId) {
|
|
2964
3138
|
if ("explanation" in refusal2 && "explains" in refusal2) {
|
|
2965
|
-
return { kind: "refusal", refusal: refusal2, settle, ...correlationId === null ? {} : { reference: correlationId } };
|
|
3139
|
+
return { kind: "refusal", refusal: refusal2, settle: settle2, ...correlationId === null ? {} : { reference: correlationId } };
|
|
2966
3140
|
}
|
|
2967
3141
|
return { kind: "internal-failure", message: `the host refused with ${refusal2.kind} and the SDK attached no explanation` };
|
|
2968
3142
|
}
|
|
@@ -2988,18 +3162,18 @@ var STORE_NEXT_STEPS = {
|
|
|
2988
3162
|
function storeFailureMessage(store, operation, nextStep) {
|
|
2989
3163
|
return `the ${STORE_LABELS[store]} session store ${STORE_OPERATION_FAILURES[operation]}; ${STORE_NEXT_STEPS[nextStep]}`;
|
|
2990
3164
|
}
|
|
2991
|
-
var outcomeOfSessionFailure = (failure2,
|
|
3165
|
+
var outcomeOfSessionFailure = (failure2, settle2) => {
|
|
2992
3166
|
switch (failure2.reason) {
|
|
2993
3167
|
case "not-signed-in":
|
|
2994
3168
|
return { kind: "unauthenticated", message: notSignedInMessage(failure2.hostKey, failure2.store) };
|
|
2995
3169
|
case "refresh-refused":
|
|
2996
|
-
return outcomeOfRouteRefusal(failure2.refusal,
|
|
3170
|
+
return outcomeOfRouteRefusal(failure2.refusal, settle2, failure2.correlationId);
|
|
2997
3171
|
case "store-failed":
|
|
2998
3172
|
return { kind: "client-refusal", message: storeFailureMessage(failure2.store, failure2.operation, failure2.nextStep) };
|
|
2999
3173
|
case "transport-failed":
|
|
3000
3174
|
return { kind: "transport-failure", message: failure2.message };
|
|
3001
3175
|
case "outcome-unknown":
|
|
3002
|
-
return { kind: "unknown-outcome-no-answer", message: failure2.message, settle };
|
|
3176
|
+
return { kind: "unknown-outcome-no-answer", message: failure2.message, settle: settle2 };
|
|
3003
3177
|
}
|
|
3004
3178
|
};
|
|
3005
3179
|
var outcomeOfHostRefusal = (refusal2) => ({
|
|
@@ -3051,7 +3225,7 @@ var outcomeOfLogout = (outcome) => {
|
|
|
3051
3225
|
return outcomeOfSessionFailure(outcome.failure, "openeng whoami");
|
|
3052
3226
|
}
|
|
3053
3227
|
};
|
|
3054
|
-
var outcomeOfOrganisationSwitch = (outcome,
|
|
3228
|
+
var outcomeOfOrganisationSwitch = (outcome, settle2) => {
|
|
3055
3229
|
switch (outcome.kind) {
|
|
3056
3230
|
case "switched":
|
|
3057
3231
|
return {
|
|
@@ -3060,9 +3234,9 @@ var outcomeOfOrganisationSwitch = (outcome, settle) => {
|
|
|
3060
3234
|
text: outcome.organisation === null ? "detached from its organisation" : `attached to ${outcome.organisation.name} (${outcome.organisation.id})`
|
|
3061
3235
|
};
|
|
3062
3236
|
case "refused":
|
|
3063
|
-
return outcomeOfRouteRefusal(outcome.refusal,
|
|
3237
|
+
return outcomeOfRouteRefusal(outcome.refusal, settle2, outcome.correlationId);
|
|
3064
3238
|
case "failed":
|
|
3065
|
-
return outcomeOfSessionFailure(outcome.failure,
|
|
3239
|
+
return outcomeOfSessionFailure(outcome.failure, settle2);
|
|
3066
3240
|
case "unexpected":
|
|
3067
3241
|
return { kind: "internal-failure", message: outcome.message };
|
|
3068
3242
|
}
|
|
@@ -4013,7 +4187,7 @@ async function runGenerated(entry2, context) {
|
|
|
4013
4187
|
if (body.correlationMinted) {
|
|
4014
4188
|
context.note("correlation: minted by the host");
|
|
4015
4189
|
}
|
|
4016
|
-
const
|
|
4190
|
+
const settle2 = settleOf(entry2, key.key);
|
|
4017
4191
|
let run2;
|
|
4018
4192
|
try {
|
|
4019
4193
|
run2 = await runAuthenticated(context.host, context.deps, async (clients) => {
|
|
@@ -4046,12 +4220,12 @@ async function runGenerated(entry2, context) {
|
|
|
4046
4220
|
message: REFRESH_UNANSWERED_ADVICE
|
|
4047
4221
|
};
|
|
4048
4222
|
}
|
|
4049
|
-
return { kind: "unknown-outcome-no-answer", message: error.message, settle };
|
|
4223
|
+
return { kind: "unknown-outcome-no-answer", message: error.message, settle: settle2 };
|
|
4050
4224
|
}
|
|
4051
4225
|
throw error;
|
|
4052
4226
|
}
|
|
4053
4227
|
if (!run2.ok) {
|
|
4054
|
-
return outcomeOfSessionFailure(run2.failure,
|
|
4228
|
+
return outcomeOfSessionFailure(run2.failure, settle2);
|
|
4055
4229
|
}
|
|
4056
4230
|
const answer = run2.answer;
|
|
4057
4231
|
if ("unavailable" in answer && typeof answer.unavailable === "string") {
|
|
@@ -4064,7 +4238,7 @@ async function runGenerated(entry2, context) {
|
|
|
4064
4238
|
if (replayed) {
|
|
4065
4239
|
context.note("the host answered a replay of an earlier request that carried this idempotency key");
|
|
4066
4240
|
}
|
|
4067
|
-
return outcomeOfEnvelope(replayed ? withoutReplay(answer) : answer,
|
|
4241
|
+
return outcomeOfEnvelope(replayed ? withoutReplay(answer) : answer, settle2, (result) => JSON.stringify(result, null, 2), {
|
|
4068
4242
|
command: `openeng ${entry2.module} ${entry2.name}`,
|
|
4069
4243
|
schemas: schemasOf(entry2),
|
|
4070
4244
|
sent: body.body
|
|
@@ -4166,13 +4340,13 @@ var orgCreate = {
|
|
|
4166
4340
|
if (options.idempotencyKey === void 0) {
|
|
4167
4341
|
note(`idempotency key: ${key}`);
|
|
4168
4342
|
}
|
|
4169
|
-
const
|
|
4343
|
+
const settle2 = `repeat this command with --idempotency-key ${key}, to retrieve a recorded outcome or retry an attempt that never reached the host`;
|
|
4170
4344
|
const run2 = await runAuthenticated(host, deps, (clients) => clients.admin.createOrganisation({ input: { name } }, key));
|
|
4171
4345
|
if (!run2.ok) {
|
|
4172
|
-
return outcomeOfSessionFailure(run2.failure,
|
|
4346
|
+
return outcomeOfSessionFailure(run2.failure, settle2);
|
|
4173
4347
|
}
|
|
4174
4348
|
if ("refusal" in run2.answer) {
|
|
4175
|
-
return outcomeOfRouteRefusal(run2.answer.refusal,
|
|
4349
|
+
return outcomeOfRouteRefusal(run2.answer.refusal, settle2, run2.answer.correlationId);
|
|
4176
4350
|
}
|
|
4177
4351
|
return { kind: "success", value: run2.answer.result, text: `created organisation ${name} (${run2.answer.result.organisationId})` };
|
|
4178
4352
|
}
|
|
@@ -8357,7 +8531,7 @@ var typesIcons = {
|
|
|
8357
8531
|
}
|
|
8358
8532
|
};
|
|
8359
8533
|
|
|
8360
|
-
// packages/demo-
|
|
8534
|
+
// packages/demo-player/dist/definition.js
|
|
8361
8535
|
var STRING = { kind: "string" };
|
|
8362
8536
|
var NUMBER = { kind: "number" };
|
|
8363
8537
|
var PERSON = { kind: "person" };
|
|
@@ -8672,7 +8846,7 @@ function worldSteps(size, ownerPersonId, data) {
|
|
|
8672
8846
|
}
|
|
8673
8847
|
var DEMO_TYPE_VERSION = 1;
|
|
8674
8848
|
|
|
8675
|
-
// packages/demo-
|
|
8849
|
+
// packages/demo-player/dist/ocgt-world.js
|
|
8676
8850
|
var SYSTEM_TREE = [
|
|
8677
8851
|
{ identifier: "OCGT", name: "Open Cycle Gas Turbine Plant", parent: null },
|
|
8678
8852
|
{ identifier: "GT", name: "Gas Turbine", parent: "OCGT" },
|
|
@@ -8897,7 +9071,7 @@ var OCGT_WORLD = {
|
|
|
8897
9071
|
})
|
|
8898
9072
|
};
|
|
8899
9073
|
|
|
8900
|
-
// packages/demo-
|
|
9074
|
+
// packages/demo-player/dist/player.js
|
|
8901
9075
|
var TRUNK_REF = "main";
|
|
8902
9076
|
var IDEMPOTENCY_PREFIX = "demo-seed";
|
|
8903
9077
|
var DemoRouteRefusedError = class extends Error {
|
|
@@ -8925,6 +9099,20 @@ var DemoForeignChangeSetError = class extends Error {
|
|
|
8925
9099
|
this.name = "DemoForeignChangeSetError";
|
|
8926
9100
|
}
|
|
8927
9101
|
};
|
|
9102
|
+
var CATALOGUE_CATEGORY_LABELS = {
|
|
9103
|
+
object: "an object type",
|
|
9104
|
+
edge: "an edge type",
|
|
9105
|
+
verb: "a verb type"
|
|
9106
|
+
};
|
|
9107
|
+
var DemoCatalogueClashError = class extends Error {
|
|
9108
|
+
clashes;
|
|
9109
|
+
constructor(clashes) {
|
|
9110
|
+
const categories = clashes.map(({ typeKey, typeCategory, version }) => `${typeKey} is ${CATALOGUE_CATEGORY_LABELS[typeCategory]} at version ${String(version)}`).join(", ");
|
|
9111
|
+
super(`the organisation's catalogue already holds demo types the demo world cannot play into (${categories}); seed into an organisation whose catalogue does not hold these types`);
|
|
9112
|
+
this.name = "DemoCatalogueClashError";
|
|
9113
|
+
this.clashes = clashes;
|
|
9114
|
+
}
|
|
9115
|
+
};
|
|
8928
9116
|
function demoRailGroups() {
|
|
8929
9117
|
return DEMO_RAIL_GROUPS.map(({ name }) => name);
|
|
8930
9118
|
}
|
|
@@ -9061,6 +9249,22 @@ async function playDemoWorld(clients, target, size, data) {
|
|
|
9061
9249
|
throw new Error("the demo world declares no object type to check for an existing play");
|
|
9062
9250
|
}
|
|
9063
9251
|
const published = resultOf(await clients.objects.readCatalogue({ selector: { projectId: target.projectId }, input: {} }), "readCatalogue");
|
|
9252
|
+
const catalogueTypes = [...published.objects, ...published.edges, ...published.verbs];
|
|
9253
|
+
const demoTypes = [
|
|
9254
|
+
...DEMO_OBJECT_TYPES.map(({ typeKey }) => ({ typeKey, typeCategory: "object" })),
|
|
9255
|
+
...DEMO_EDGE_TYPES.map(({ typeKey }) => ({ typeKey, typeCategory: "edge" }))
|
|
9256
|
+
];
|
|
9257
|
+
const clashes = [];
|
|
9258
|
+
for (const demoType of demoTypes) {
|
|
9259
|
+
for (const catalogueType of catalogueTypes) {
|
|
9260
|
+
if (catalogueType.typeKey === demoType.typeKey && (catalogueType.typeCategory !== demoType.typeCategory || catalogueType.version !== DEMO_TYPE_VERSION)) {
|
|
9261
|
+
clashes.push({ typeKey: demoType.typeKey, typeCategory: catalogueType.typeCategory, version: catalogueType.version });
|
|
9262
|
+
}
|
|
9263
|
+
}
|
|
9264
|
+
}
|
|
9265
|
+
if (clashes.length > 0) {
|
|
9266
|
+
throw new DemoCatalogueClashError(clashes);
|
|
9267
|
+
}
|
|
9064
9268
|
if (!published.objects.some((one) => one.typeKey === firstObjectType.typeKey)) {
|
|
9065
9269
|
await publishDemoTypes(clients.ontology, target.organisationId);
|
|
9066
9270
|
}
|
|
@@ -9104,10 +9308,10 @@ async function playDemoWorld(clients, target, size, data) {
|
|
|
9104
9308
|
// packages/cli/src/commands/demo-shared.ts
|
|
9105
9309
|
async function runDemoSeed(context, projectId, size, world, data) {
|
|
9106
9310
|
const { host, deps } = context;
|
|
9107
|
-
const
|
|
9311
|
+
const settle2 = `openeng types list --project ${projectId}, then repeat openeng demo seed, which completes what is left`;
|
|
9108
9312
|
const signedIn = await freshSession(host, deps);
|
|
9109
9313
|
if (!signedIn.ok) {
|
|
9110
|
-
return outcomeOfSessionFailure(signedIn.failure,
|
|
9314
|
+
return outcomeOfSessionFailure(signedIn.failure, settle2);
|
|
9111
9315
|
}
|
|
9112
9316
|
const ownerPersonId = signedIn.session.principalId;
|
|
9113
9317
|
const run2 = await runAuthenticated(host, deps, async (clients) => {
|
|
@@ -9134,15 +9338,18 @@ async function runDemoSeed(context, projectId, size, world, data) {
|
|
|
9134
9338
|
if (error instanceof DemoForeignChangeSetError) {
|
|
9135
9339
|
return { foreignChangeSet: error.message };
|
|
9136
9340
|
}
|
|
9341
|
+
if (error instanceof DemoCatalogueClashError) {
|
|
9342
|
+
return { catalogueClash: error.message };
|
|
9343
|
+
}
|
|
9137
9344
|
throw error;
|
|
9138
9345
|
}
|
|
9139
9346
|
});
|
|
9140
9347
|
if (!run2.ok) {
|
|
9141
|
-
return outcomeOfSessionFailure(run2.failure,
|
|
9348
|
+
return outcomeOfSessionFailure(run2.failure, settle2);
|
|
9142
9349
|
}
|
|
9143
9350
|
const answer = run2.answer;
|
|
9144
9351
|
if ("refusal" in answer) {
|
|
9145
|
-
return outcomeOfRouteRefusal(answer.refusal,
|
|
9352
|
+
return outcomeOfRouteRefusal(answer.refusal, settle2, answer.correlationId);
|
|
9146
9353
|
}
|
|
9147
9354
|
if ("refusedResult" in answer) {
|
|
9148
9355
|
return outcomeOfRefusedResult(answer.refusedResult);
|
|
@@ -9150,6 +9357,9 @@ async function runDemoSeed(context, projectId, size, world, data) {
|
|
|
9150
9357
|
if ("foreignChangeSet" in answer) {
|
|
9151
9358
|
return { kind: "client-refusal", message: answer.foreignChangeSet };
|
|
9152
9359
|
}
|
|
9360
|
+
if ("catalogueClash" in answer) {
|
|
9361
|
+
return { kind: "client-refusal", message: answer.catalogueClash };
|
|
9362
|
+
}
|
|
9153
9363
|
if ("absent" in answer) {
|
|
9154
9364
|
return { kind: "client-refusal", message: `the project ${projectId} is not among the projects you may list; create it with openeng projects create` };
|
|
9155
9365
|
}
|
|
@@ -9216,13 +9426,13 @@ function createSecretPrompt(input, output) {
|
|
|
9216
9426
|
return new Promise((resolve, reject) => {
|
|
9217
9427
|
let value = "";
|
|
9218
9428
|
let finished = false;
|
|
9219
|
-
const finish = (
|
|
9429
|
+
const finish = (settle2) => {
|
|
9220
9430
|
finished = true;
|
|
9221
9431
|
input.off("data", onData);
|
|
9222
9432
|
input.setRawMode(false);
|
|
9223
9433
|
input.pause();
|
|
9224
9434
|
output.write("\n");
|
|
9225
|
-
|
|
9435
|
+
settle2();
|
|
9226
9436
|
};
|
|
9227
9437
|
const consume = (text) => {
|
|
9228
9438
|
const characters = [...text];
|
|
@@ -9331,14 +9541,14 @@ var connectorCreate = {
|
|
|
9331
9541
|
if (!chosen.ok) {
|
|
9332
9542
|
return chosen.outcome;
|
|
9333
9543
|
}
|
|
9334
|
-
const
|
|
9544
|
+
const settle2 = "openeng admin-sdk listConnections, which only reads, shows whether the connection exists";
|
|
9335
9545
|
context.note(CONNECTOR_DISCLOSURE);
|
|
9336
9546
|
const run2 = await runAuthenticated(
|
|
9337
9547
|
context.host,
|
|
9338
9548
|
context.deps,
|
|
9339
9549
|
(clients) => clients.admin.createConnection({ input: { name, system, stack, companyId: company === void 0 ? null : company, selection: chosen.selection } })
|
|
9340
9550
|
);
|
|
9341
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
9551
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, createdText) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9342
9552
|
}
|
|
9343
9553
|
};
|
|
9344
9554
|
function selectorOf(context) {
|
|
@@ -9381,14 +9591,14 @@ var connectorSetCredential = {
|
|
|
9381
9591
|
if (secretKey === null || secretKey === "") {
|
|
9382
9592
|
return { kind: "client-refusal", message: "openeng connector set-credential needs the secret key typed at a terminal prompt" };
|
|
9383
9593
|
}
|
|
9384
|
-
const
|
|
9594
|
+
const settle2 = "openeng connector set-credential again; a repeat replaces the stored credential";
|
|
9385
9595
|
const run2 = await runAuthenticated(
|
|
9386
9596
|
context.host,
|
|
9387
9597
|
context.deps,
|
|
9388
9598
|
(clients) => clients.admin.setConnectionCredential({ selector, input: { credential: { kind: "api-key", accessKey: toCredential(accessKey), secretKey: toCredential(secretKey) } } })
|
|
9389
9599
|
);
|
|
9390
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
9391
|
-
${CONNECTOR_DISCLOSURE}`) : outcomeOfSessionFailure(run2.failure,
|
|
9600
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (set) => `credential set for Onshape account ${set.upstreamIdentity} at ${set.setAt}
|
|
9601
|
+
${CONNECTOR_DISCLOSURE}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9392
9602
|
}
|
|
9393
9603
|
};
|
|
9394
9604
|
var connectorDraftTypes = {
|
|
@@ -9406,9 +9616,9 @@ var connectorDraftTypes = {
|
|
|
9406
9616
|
],
|
|
9407
9617
|
run: async (context) => {
|
|
9408
9618
|
const selector = selectorOf(context);
|
|
9409
|
-
const
|
|
9619
|
+
const settle2 = "openeng types draft current, which only reads, shows whether a change set is open";
|
|
9410
9620
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.admin.draftConnectorTypes({ selector, input: {} }));
|
|
9411
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
9621
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, typesText) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9412
9622
|
}
|
|
9413
9623
|
};
|
|
9414
9624
|
var connectorRevoke = {
|
|
@@ -9427,9 +9637,9 @@ var connectorRevoke = {
|
|
|
9427
9637
|
run: async (context) => {
|
|
9428
9638
|
const selector = selectorOf(context);
|
|
9429
9639
|
const { connectionId } = selector;
|
|
9430
|
-
const
|
|
9640
|
+
const settle2 = "openeng admin-sdk listConnections, which only reads, shows the connection's state";
|
|
9431
9641
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.admin.revokeConnection({ selector, input: {} }));
|
|
9432
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
9642
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, () => `revoked connection ${connectionId}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9433
9643
|
}
|
|
9434
9644
|
};
|
|
9435
9645
|
var connectorRun = {
|
|
@@ -9448,9 +9658,9 @@ var connectorRun = {
|
|
|
9448
9658
|
run: async (context) => {
|
|
9449
9659
|
const selector = selectorOf(context);
|
|
9450
9660
|
const { connectionId } = selector;
|
|
9451
|
-
const
|
|
9661
|
+
const settle2 = `openeng connector runs ${connectionId}, which only reads`;
|
|
9452
9662
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.admin.startImportRun({ selector, input: {} }));
|
|
9453
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
9663
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (started) => `started run ${started.runId}: read it with openeng connector runs ${connectionId}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9454
9664
|
}
|
|
9455
9665
|
};
|
|
9456
9666
|
var runText = (record) => {
|
|
@@ -9474,9 +9684,9 @@ var connectorRuns = {
|
|
|
9474
9684
|
],
|
|
9475
9685
|
run: async (context) => {
|
|
9476
9686
|
const selector = selectorOf(context);
|
|
9477
|
-
const
|
|
9687
|
+
const settle2 = "repeat openeng connector runs, which only reads";
|
|
9478
9688
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.admin.listImportRuns({ selector, input: {} }));
|
|
9479
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
9689
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (records) => records.length === 0 ? "no runs" : records.map(runText).join("\n")) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9480
9690
|
}
|
|
9481
9691
|
};
|
|
9482
9692
|
|
|
@@ -9514,6 +9724,9 @@ var SCOPE_OF_KIND = Object.freeze({
|
|
|
9514
9724
|
});
|
|
9515
9725
|
var UNREAD = "";
|
|
9516
9726
|
function scopeOf2(kind, project, ref) {
|
|
9727
|
+
if (SCOPE_OF_KIND[kind] !== "none" && ref !== void 0 && !isLinkRef(ref, SCOPE_OF_KIND[kind] === "project-and-ref" ? project : void 0)) {
|
|
9728
|
+
return "--ref takes main or <projectId>/<branch>, the ref the platform returns; its project must match --project when given";
|
|
9729
|
+
}
|
|
9517
9730
|
switch (SCOPE_OF_KIND[kind]) {
|
|
9518
9731
|
case "project-and-ref":
|
|
9519
9732
|
return project === void 0 || project === "" || ref === void 0 || ref === "" ? "needs --project <id> and --ref <ref>" : { project, ref };
|
|
@@ -9526,6 +9739,64 @@ function scopeOf2(kind, project, ref) {
|
|
|
9526
9739
|
return project !== void 0 || ref !== void 0 ? "takes neither --project nor --ref" : { project: UNREAD, ref: UNREAD };
|
|
9527
9740
|
}
|
|
9528
9741
|
}
|
|
9742
|
+
function checkedRead(pending, reason, contains) {
|
|
9743
|
+
return pending.then((answer) => {
|
|
9744
|
+
if ("refusal" in answer) {
|
|
9745
|
+
return { answer, missing: answer.refusal.kind === "not-found" ? reason : null };
|
|
9746
|
+
}
|
|
9747
|
+
if (answer.replayed === true) return { answer, missing: null };
|
|
9748
|
+
return { answer, missing: contains !== void 0 && !contains(answer.result) ? reason : null };
|
|
9749
|
+
});
|
|
9750
|
+
}
|
|
9751
|
+
function subjectReads(clients, subject, scope) {
|
|
9752
|
+
const reads = [];
|
|
9753
|
+
if (scope.ref !== "main" && SCOPE_OF_KIND[subject.kind] !== "none") {
|
|
9754
|
+
const slash = scope.ref.indexOf("/");
|
|
9755
|
+
const projectId = scope.ref.slice(0, slash);
|
|
9756
|
+
const name = scope.ref.slice(slash + 1);
|
|
9757
|
+
reads.push(checkedRead(
|
|
9758
|
+
clients.branches.readRefHead({ selector: { projectId }, input: { name } }),
|
|
9759
|
+
`no ref ${scope.ref} in project ${projectId}`
|
|
9760
|
+
));
|
|
9761
|
+
} else if (SCOPE_OF_KIND[subject.kind] === "project-and-ref") {
|
|
9762
|
+
reads.push(checkedRead(
|
|
9763
|
+
clients.branches.readRefHead({ selector: { projectId: scope.project }, input: { name: "main" } }),
|
|
9764
|
+
`no ref main in project ${scope.project}`
|
|
9765
|
+
));
|
|
9766
|
+
}
|
|
9767
|
+
switch (subject.kind) {
|
|
9768
|
+
case "object":
|
|
9769
|
+
reads.push(checkedRead(
|
|
9770
|
+
clients.objects.readObject({ selector: { projectId: scope.project, ref: scope.ref }, input: { objectId: subject.objectId } }),
|
|
9771
|
+
`no object ${subject.objectId} in project ${scope.project} on ref ${scope.ref}`
|
|
9772
|
+
));
|
|
9773
|
+
break;
|
|
9774
|
+
case "type":
|
|
9775
|
+
reads.push(checkedRead(
|
|
9776
|
+
clients.objects.readCatalogue({ selector: { projectId: scope.project }, input: {} }),
|
|
9777
|
+
`no type ${subject.typeKey} in project ${scope.project}`,
|
|
9778
|
+
(catalogue) => catalogue.objects.some((type) => type.typeKey === subject.typeKey)
|
|
9779
|
+
));
|
|
9780
|
+
break;
|
|
9781
|
+
case "app":
|
|
9782
|
+
reads.push(checkedRead(clients.objects.readApp({ input: { appKey: subject.appKey } }), `no app ${subject.appKey}`));
|
|
9783
|
+
break;
|
|
9784
|
+
case "app-page":
|
|
9785
|
+
reads.push(checkedRead(
|
|
9786
|
+
clients.objects.readApp({ input: { appKey: subject.appKey } }),
|
|
9787
|
+
`no page ${subject.pageKey} in app ${subject.appKey}`,
|
|
9788
|
+
(app) => app.document.pages.some((page) => page.key === subject.pageKey)
|
|
9789
|
+
));
|
|
9790
|
+
break;
|
|
9791
|
+
case "proposal":
|
|
9792
|
+
reads.push(checkedRead(
|
|
9793
|
+
clients.branches.readProposal({ selector: { projectId: scope.project }, input: { proposalId: subject.proposalId } }),
|
|
9794
|
+
`no proposal ${subject.proposalId} in project ${scope.project}`
|
|
9795
|
+
));
|
|
9796
|
+
break;
|
|
9797
|
+
}
|
|
9798
|
+
return reads;
|
|
9799
|
+
}
|
|
9529
9800
|
async function link(context) {
|
|
9530
9801
|
const { host, deps, options, args } = context;
|
|
9531
9802
|
const read = await readStoredEntry(host, deps.store);
|
|
@@ -9567,13 +9838,28 @@ async function link(context) {
|
|
|
9567
9838
|
return refusal(`openeng link ${subject.kind} ${scope}`);
|
|
9568
9839
|
}
|
|
9569
9840
|
const path = linkPath(organisation.id, scope.project, subject, scope.ref);
|
|
9570
|
-
const run2 = await runAuthenticated(host, deps, (clients) =>
|
|
9841
|
+
const run2 = await runAuthenticated(host, deps, async (clients) => {
|
|
9842
|
+
const [origin, checks] = await Promise.all([
|
|
9843
|
+
clients.admin.readWebOrigin({ input: {} }),
|
|
9844
|
+
Promise.all(subjectReads(clients, subject, scope))
|
|
9845
|
+
]);
|
|
9846
|
+
const blocked = checks.find((check) => check.missing === null && ("refusal" in check.answer || check.answer.replayed === true));
|
|
9847
|
+
if (blocked !== void 0) return blocked.answer;
|
|
9848
|
+
if ("refusal" in origin) {
|
|
9849
|
+
return origin.refusal.kind === "not-found" ? refusal("the host's web application was not found") : origin;
|
|
9850
|
+
}
|
|
9851
|
+
if (origin.replayed === true) return origin;
|
|
9852
|
+
const missing = checks.find((check) => check.missing !== null);
|
|
9853
|
+
if (missing !== void 0 && missing.missing !== null) return refusal(missing.missing);
|
|
9854
|
+
return { kind: "link-ready", webOrigin: origin.result.webOrigin };
|
|
9855
|
+
});
|
|
9571
9856
|
if (!run2.ok) {
|
|
9572
9857
|
return outcomeOfSessionFailure(run2.failure, SETTLE2);
|
|
9573
9858
|
}
|
|
9574
9859
|
const { answer } = run2;
|
|
9575
|
-
if (
|
|
9576
|
-
|
|
9860
|
+
if ("kind" in answer) {
|
|
9861
|
+
if (answer.kind === "client-refusal") return answer;
|
|
9862
|
+
const { webOrigin } = answer;
|
|
9577
9863
|
if (webOrigin === null) {
|
|
9578
9864
|
return refusal("this host has no web application configured, so it has no page to link to");
|
|
9579
9865
|
}
|
|
@@ -9590,7 +9876,9 @@ var spec = (argumentCount, usage) => ({
|
|
|
9590
9876
|
usage,
|
|
9591
9877
|
help: [
|
|
9592
9878
|
...LINK_HELP,
|
|
9593
|
-
"does:
|
|
9879
|
+
"does: reads the page's subject before printing its web address for the attached organisation",
|
|
9880
|
+
"ref: --ref takes main or <projectId>/<branch>, the ref the platform returns; match --project when given",
|
|
9881
|
+
"refusal: a subject not found by the page's own read prints no address",
|
|
9594
9882
|
"example: openeng link explore --project proj_abc123 --ref main",
|
|
9595
9883
|
"output: the address on one line; under --json an object with link"
|
|
9596
9884
|
],
|
|
@@ -9649,6 +9937,347 @@ var projectsCreate = {
|
|
|
9649
9937
|
}
|
|
9650
9938
|
};
|
|
9651
9939
|
|
|
9940
|
+
// packages/cli/src/commands/protection-help.ts
|
|
9941
|
+
var SCOPE_LABELS = Object.freeze({
|
|
9942
|
+
project: "on the selected project",
|
|
9943
|
+
organisation: "in the attached organisation",
|
|
9944
|
+
"branch-home-project": "on the branch's home project",
|
|
9945
|
+
"organisation-ref": "for an organisation ref",
|
|
9946
|
+
ref: "on the selected ref"
|
|
9947
|
+
});
|
|
9948
|
+
function protectionCapabilityHelp(...routes) {
|
|
9949
|
+
const requirements = routes.flatMap((route2) => PROTECTION_ROUTE_CAPABILITIES[route2].map((requirement) => "visibility" in requirement ? "none; only the caller's own requests in the token's organisation; no project read required" : `${requirement.capability} ${SCOPE_LABELS[requirement.scope]}`));
|
|
9950
|
+
return `capability: ${[...new Set(requirements)].join(" or ")}`;
|
|
9951
|
+
}
|
|
9952
|
+
|
|
9953
|
+
// packages/cli/src/commands/rules.ts
|
|
9954
|
+
var CONSEQUENCES = ["merge-only", "locked-rows-only"];
|
|
9955
|
+
var settleWith = (project) => project === void 0 ? "repeat openeng rules list --organisation, which only reads" : `repeat openeng rules list --project ${project}, which only reads`;
|
|
9956
|
+
var ruleText = (rule) => `rule ${rule.ruleId} ${rule.pattern} ${rule.consequence}`;
|
|
9957
|
+
var rulesOutcome = (outcome) => outcome.kind === "success" ? { ...outcome, value: { value: outcome.value } } : outcome;
|
|
9958
|
+
var scopeMessage = "choose exactly one of --project <id> or --organisation";
|
|
9959
|
+
var rulesAdd = {
|
|
9960
|
+
words: ["rules", "add"],
|
|
9961
|
+
organisation: "required",
|
|
9962
|
+
usage: "openeng rules add (--project <id>|--organisation) --pattern <pattern> --consequence <value>",
|
|
9963
|
+
help: [
|
|
9964
|
+
"openeng rules add (--project <id>|--organisation) --pattern <pattern> --consequence <merge-only|locked-rows-only>",
|
|
9965
|
+
"does: adds a project or organisation ref rule; repeating the same content returns the existing rule",
|
|
9966
|
+
protectionCapabilityHelp("addRefRule", "addOrganisationRule"),
|
|
9967
|
+
"example: openeng rules add --organisation --pattern release-v1 --consequence merge-only",
|
|
9968
|
+
"output: the rule id, pattern and consequence; under --json { scope, value }, with the full RefRule in value"
|
|
9969
|
+
],
|
|
9970
|
+
run: async ({ host, deps, options }) => {
|
|
9971
|
+
const { project, organisation, pattern } = options;
|
|
9972
|
+
if (project !== void 0 === organisation) {
|
|
9973
|
+
return { kind: "client-refusal", message: scopeMessage };
|
|
9974
|
+
}
|
|
9975
|
+
if (pattern === void 0 || options.consequence === void 0) {
|
|
9976
|
+
return {
|
|
9977
|
+
kind: "client-refusal",
|
|
9978
|
+
message: "openeng rules add needs --pattern <pattern> and --consequence <merge-only|locked-rows-only>"
|
|
9979
|
+
};
|
|
9980
|
+
}
|
|
9981
|
+
const consequence = CONSEQUENCES.find((value) => value === options.consequence);
|
|
9982
|
+
if (consequence === void 0) {
|
|
9983
|
+
return { kind: "client-refusal", message: "--consequence must be merge-only or locked-rows-only" };
|
|
9984
|
+
}
|
|
9985
|
+
const settle2 = settleWith(project);
|
|
9986
|
+
const run2 = await runAuthenticated(host, deps, (clients) => project === void 0 ? clients.admin.addOrganisationRule({ input: { pattern, consequence } }) : clients.admin.addRefRule({ selector: { projectId: project }, input: { pattern, consequence } }));
|
|
9987
|
+
return run2.ok ? rulesOutcome(outcomeOfEnvelope(run2.answer, settle2, ruleText)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9988
|
+
}
|
|
9989
|
+
};
|
|
9990
|
+
var rulesList = {
|
|
9991
|
+
words: ["rules", "list"],
|
|
9992
|
+
organisation: "required",
|
|
9993
|
+
usage: "openeng rules list (--project <id>|--organisation)",
|
|
9994
|
+
help: [
|
|
9995
|
+
"openeng rules list (--project <id>|--organisation)",
|
|
9996
|
+
"does: lists visible ref protection rules for the project or attached organisation",
|
|
9997
|
+
protectionCapabilityHelp("listRefRules", "listOrganisationRules"),
|
|
9998
|
+
"example: openeng rules list --organisation --json",
|
|
9999
|
+
"output: id, pattern and consequence per rule, or no rules; --json { scope, value }, value is a RefRule array"
|
|
10000
|
+
],
|
|
10001
|
+
run: async ({ host, deps, options }) => {
|
|
10002
|
+
const { project, organisation } = options;
|
|
10003
|
+
if (project !== void 0 === organisation) {
|
|
10004
|
+
return { kind: "client-refusal", message: scopeMessage };
|
|
10005
|
+
}
|
|
10006
|
+
const settle2 = settleWith(project);
|
|
10007
|
+
const run2 = await runAuthenticated(host, deps, (clients) => project === void 0 ? clients.admin.listOrganisationRules({ input: {} }) : clients.admin.listRefRules({ selector: { projectId: project }, input: {} }));
|
|
10008
|
+
return run2.ok ? rulesOutcome(outcomeOfEnvelope(
|
|
10009
|
+
run2.answer,
|
|
10010
|
+
settle2,
|
|
10011
|
+
(rules) => rules.length === 0 ? "no rules" : rules.map(ruleText).join("\n")
|
|
10012
|
+
)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10013
|
+
}
|
|
10014
|
+
};
|
|
10015
|
+
var rulesRemove = {
|
|
10016
|
+
words: ["rules", "remove"],
|
|
10017
|
+
organisation: "required",
|
|
10018
|
+
usage: "openeng rules remove (--project <id>|--organisation) --rule-id <id>",
|
|
10019
|
+
help: [
|
|
10020
|
+
"openeng rules remove (--project <id>|--organisation) --rule-id <id>",
|
|
10021
|
+
"does: removes one rule from the project or attached organisation by its identifier",
|
|
10022
|
+
protectionCapabilityHelp("removeRefRule", "removeOrganisationRule"),
|
|
10023
|
+
"example: openeng rules remove --organisation --rule-id rule-one",
|
|
10024
|
+
"output: the removed rule id; under --json { scope, value }, with { ruleId } in value"
|
|
10025
|
+
],
|
|
10026
|
+
run: async ({ host, deps, options }) => {
|
|
10027
|
+
const { project, organisation, ruleId } = options;
|
|
10028
|
+
if (project !== void 0 === organisation) {
|
|
10029
|
+
return { kind: "client-refusal", message: scopeMessage };
|
|
10030
|
+
}
|
|
10031
|
+
if (ruleId === void 0) {
|
|
10032
|
+
return { kind: "client-refusal", message: "openeng rules remove needs --rule-id <id>" };
|
|
10033
|
+
}
|
|
10034
|
+
const settle2 = settleWith(project);
|
|
10035
|
+
const run2 = await runAuthenticated(host, deps, (clients) => project === void 0 ? clients.admin.removeOrganisationRule({ input: { ruleId } }) : clients.admin.removeRefRule({ selector: { projectId: project }, input: { ruleId } }));
|
|
10036
|
+
return run2.ok ? rulesOutcome(outcomeOfEnvelope(run2.answer, settle2, (removed) => `removed rule ${removed.ruleId}`)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10037
|
+
}
|
|
10038
|
+
};
|
|
10039
|
+
|
|
10040
|
+
// packages/cli/src/commands/org-refs.ts
|
|
10041
|
+
var settle = "repeat openeng org-refs list, which only reads";
|
|
10042
|
+
var refText = (ref) => `ref ${ref.name} ${ref.readOnly ? "read-only" : "writable"}`;
|
|
10043
|
+
var refsOutcome = (outcome) => outcome.kind === "success" ? { ...outcome, value: { value: outcome.value } } : outcome;
|
|
10044
|
+
var orgRefsCreate = {
|
|
10045
|
+
words: ["org-refs", "create"],
|
|
10046
|
+
organisation: "required",
|
|
10047
|
+
usage: "openeng org-refs create --name <name> [--read-only]",
|
|
10048
|
+
help: [
|
|
10049
|
+
"openeng org-refs create --name <name> [--read-only]",
|
|
10050
|
+
"does: creates a ref in the attached organisation, optionally read-only",
|
|
10051
|
+
protectionCapabilityHelp("createOrganisationRef"),
|
|
10052
|
+
"example: openeng org-refs create --name release-v1 --read-only",
|
|
10053
|
+
"output: the ref name and write state; under --json { scope, value }, with the full OrganisationRef in value"
|
|
10054
|
+
],
|
|
10055
|
+
run: async ({ host, deps, options }) => {
|
|
10056
|
+
const { name, readOnly } = options;
|
|
10057
|
+
if (name === void 0) {
|
|
10058
|
+
return { kind: "client-refusal", message: "openeng org-refs create needs --name <name>" };
|
|
10059
|
+
}
|
|
10060
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.admin.createOrganisationRef({
|
|
10061
|
+
input: { name, readOnly }
|
|
10062
|
+
}));
|
|
10063
|
+
return run2.ok ? refsOutcome(outcomeOfEnvelope(run2.answer, settle, refText)) : outcomeOfSessionFailure(run2.failure, settle);
|
|
10064
|
+
}
|
|
10065
|
+
};
|
|
10066
|
+
var orgRefsList = {
|
|
10067
|
+
words: ["org-refs", "list"],
|
|
10068
|
+
organisation: "required",
|
|
10069
|
+
usage: "openeng org-refs list",
|
|
10070
|
+
help: [
|
|
10071
|
+
"openeng org-refs list",
|
|
10072
|
+
"does: lists visible refs in the attached organisation",
|
|
10073
|
+
protectionCapabilityHelp("listOrganisationRefs"),
|
|
10074
|
+
"example: openeng org-refs list --json",
|
|
10075
|
+
"output: each ref's name and write state, or no refs; under --json { scope, value }, value is an array"
|
|
10076
|
+
],
|
|
10077
|
+
run: async ({ host, deps }) => {
|
|
10078
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.admin.listOrganisationRefs({ input: {} }));
|
|
10079
|
+
return run2.ok ? refsOutcome(outcomeOfEnvelope(
|
|
10080
|
+
run2.answer,
|
|
10081
|
+
settle,
|
|
10082
|
+
(refs) => refs.length === 0 ? "no refs" : refs.map(refText).join("\n")
|
|
10083
|
+
)) : outcomeOfSessionFailure(run2.failure, settle);
|
|
10084
|
+
}
|
|
10085
|
+
};
|
|
10086
|
+
var orgRefsDelete = {
|
|
10087
|
+
words: ["org-refs", "delete"],
|
|
10088
|
+
organisation: "required",
|
|
10089
|
+
usage: "openeng org-refs delete --name <name>",
|
|
10090
|
+
help: [
|
|
10091
|
+
"openeng org-refs delete --name <name>",
|
|
10092
|
+
"does: deletes a writable ref from the attached organisation",
|
|
10093
|
+
protectionCapabilityHelp("deleteOrganisationRef"),
|
|
10094
|
+
"example: openeng org-refs delete --name review",
|
|
10095
|
+
"output: the deleted ref name; under --json { scope, value }, with { name } in value"
|
|
10096
|
+
],
|
|
10097
|
+
run: async ({ host, deps, options }) => {
|
|
10098
|
+
const { name } = options;
|
|
10099
|
+
if (name === void 0) {
|
|
10100
|
+
return { kind: "client-refusal", message: "openeng org-refs delete needs --name <name>" };
|
|
10101
|
+
}
|
|
10102
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.admin.deleteOrganisationRef({
|
|
10103
|
+
input: { name }
|
|
10104
|
+
}));
|
|
10105
|
+
return run2.ok ? refsOutcome(outcomeOfEnvelope(run2.answer, settle, (deleted) => `deleted ref ${deleted.name}`)) : outcomeOfSessionFailure(run2.failure, settle);
|
|
10106
|
+
}
|
|
10107
|
+
};
|
|
10108
|
+
var orgRefsMarkReadOnly = {
|
|
10109
|
+
words: ["org-refs", "mark-read-only"],
|
|
10110
|
+
organisation: "required",
|
|
10111
|
+
usage: "openeng org-refs mark-read-only --name <name>",
|
|
10112
|
+
help: [
|
|
10113
|
+
"openeng org-refs mark-read-only --name <name>",
|
|
10114
|
+
"does: marks a ref in the attached organisation read-only",
|
|
10115
|
+
protectionCapabilityHelp("markOrganisationRefReadOnly"),
|
|
10116
|
+
"example: openeng org-refs mark-read-only --name release-v1",
|
|
10117
|
+
"output: the ref name and write state; under --json { scope, value }, with the full OrganisationRef in value"
|
|
10118
|
+
],
|
|
10119
|
+
run: async ({ host, deps, options }) => {
|
|
10120
|
+
const { name } = options;
|
|
10121
|
+
if (name === void 0) {
|
|
10122
|
+
return { kind: "client-refusal", message: "openeng org-refs mark-read-only needs --name <name>" };
|
|
10123
|
+
}
|
|
10124
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.admin.markOrganisationRefReadOnly({
|
|
10125
|
+
input: { name }
|
|
10126
|
+
}));
|
|
10127
|
+
return run2.ok ? refsOutcome(outcomeOfEnvelope(run2.answer, settle, refText)) : outcomeOfSessionFailure(run2.failure, settle);
|
|
10128
|
+
}
|
|
10129
|
+
};
|
|
10130
|
+
|
|
10131
|
+
// packages/cli/src/commands/locks.ts
|
|
10132
|
+
var LOCKS = ["none", "merge-only", "frozen"];
|
|
10133
|
+
var lockOutcome = (outcome) => outcome.kind === "success" ? { ...outcome, value: { value: outcome.value } } : outcome;
|
|
10134
|
+
var locksSet = {
|
|
10135
|
+
words: ["locks", "set"],
|
|
10136
|
+
organisation: "required",
|
|
10137
|
+
usage: "openeng locks set --project <id> --ref <ref> --object <objectId> --lock <none|merge-only|frozen>",
|
|
10138
|
+
help: [
|
|
10139
|
+
"openeng locks set --project <id> --ref <ref> --object <objectId> --lock <none|merge-only|frozen>",
|
|
10140
|
+
"does: sets or lifts an object's lock on the selected project ref",
|
|
10141
|
+
protectionCapabilityHelp("setObjectLock"),
|
|
10142
|
+
"example: openeng locks set --project project-one --ref main --object object-one --lock frozen",
|
|
10143
|
+
"output: the object identifier and lock; under --json { scope, value }, with { objectId, lock } in value"
|
|
10144
|
+
],
|
|
10145
|
+
run: async ({ host, deps, options }) => {
|
|
10146
|
+
const { project, ref, object } = options;
|
|
10147
|
+
if (project === void 0 || ref === void 0 || object === void 0 || options.lock === void 0) {
|
|
10148
|
+
return {
|
|
10149
|
+
kind: "client-refusal",
|
|
10150
|
+
message: "openeng locks set needs --project <id>, --ref <ref>, --object <objectId> and --lock <none|merge-only|frozen>"
|
|
10151
|
+
};
|
|
10152
|
+
}
|
|
10153
|
+
const lock = LOCKS.find((value) => value === options.lock);
|
|
10154
|
+
if (lock === void 0) {
|
|
10155
|
+
return { kind: "client-refusal", message: "--lock must be none, merge-only or frozen" };
|
|
10156
|
+
}
|
|
10157
|
+
const selector = { projectId: project, ref };
|
|
10158
|
+
const input = { objectId: object, lock };
|
|
10159
|
+
const settle2 = `repeat openeng locks set --project ${project} --ref ${ref} --object ${object} --lock ${lock}, which sets the same lock again`;
|
|
10160
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.objects.setObjectLock({ selector, input }));
|
|
10161
|
+
return run2.ok ? lockOutcome(outcomeOfEnvelope(run2.answer, settle2, (value) => `object ${value.objectId} lock ${value.lock}`)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10162
|
+
}
|
|
10163
|
+
};
|
|
10164
|
+
|
|
10165
|
+
// packages/cli/src/commands/ceiling.ts
|
|
10166
|
+
var CEILINGS = ["contributor", "maintainer"];
|
|
10167
|
+
var settleWith2 = (project) => `repeat openeng ceiling show --project ${project}, which only reads`;
|
|
10168
|
+
var ceilingText = (value) => `ceiling ${value.ceiling}`;
|
|
10169
|
+
var ceilingOutcome = (outcome) => outcome.kind === "success" ? { ...outcome, value: { value: outcome.value } } : outcome;
|
|
10170
|
+
var ceilingShow = {
|
|
10171
|
+
words: ["ceiling", "show"],
|
|
10172
|
+
organisation: "required",
|
|
10173
|
+
usage: "openeng ceiling show --project <id>",
|
|
10174
|
+
help: [
|
|
10175
|
+
"openeng ceiling show --project <id>",
|
|
10176
|
+
"does: reads the maximum role an agent can hold in the project",
|
|
10177
|
+
protectionCapabilityHelp("readAgentCeiling"),
|
|
10178
|
+
"example: openeng ceiling show --project project-one --json",
|
|
10179
|
+
"output: the ceiling role; under --json { scope, value }, with { ceiling } in value"
|
|
10180
|
+
],
|
|
10181
|
+
run: async ({ host, deps, options }) => {
|
|
10182
|
+
const { project } = options;
|
|
10183
|
+
if (project === void 0) {
|
|
10184
|
+
return { kind: "client-refusal", message: "openeng ceiling show needs --project <id>" };
|
|
10185
|
+
}
|
|
10186
|
+
const settle2 = settleWith2(project);
|
|
10187
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.admin.readAgentCeiling({
|
|
10188
|
+
selector: { projectId: project },
|
|
10189
|
+
input: {}
|
|
10190
|
+
}));
|
|
10191
|
+
return run2.ok ? ceilingOutcome(outcomeOfEnvelope(run2.answer, settle2, ceilingText)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10192
|
+
}
|
|
10193
|
+
};
|
|
10194
|
+
var ceilingSet = {
|
|
10195
|
+
words: ["ceiling", "set"],
|
|
10196
|
+
organisation: "required",
|
|
10197
|
+
usage: "openeng ceiling set --project <id> --ceiling <contributor|maintainer>",
|
|
10198
|
+
help: [
|
|
10199
|
+
"openeng ceiling set --project <id> --ceiling <contributor|maintainer>",
|
|
10200
|
+
"does: sets the maximum role an agent can hold in the project",
|
|
10201
|
+
protectionCapabilityHelp("setAgentCeiling"),
|
|
10202
|
+
"example: openeng ceiling set --project project-one --ceiling contributor",
|
|
10203
|
+
"output: the ceiling role; under --json { scope, value }, with { ceiling } in value"
|
|
10204
|
+
],
|
|
10205
|
+
run: async ({ host, deps, options }) => {
|
|
10206
|
+
const { project } = options;
|
|
10207
|
+
if (project === void 0 || options.ceiling === void 0) {
|
|
10208
|
+
return {
|
|
10209
|
+
kind: "client-refusal",
|
|
10210
|
+
message: "openeng ceiling set needs --project <id> and --ceiling <contributor|maintainer>"
|
|
10211
|
+
};
|
|
10212
|
+
}
|
|
10213
|
+
const ceiling = CEILINGS.find((value) => value === options.ceiling);
|
|
10214
|
+
if (ceiling === void 0) {
|
|
10215
|
+
return { kind: "client-refusal", message: "--ceiling must be contributor or maintainer" };
|
|
10216
|
+
}
|
|
10217
|
+
const settle2 = settleWith2(project);
|
|
10218
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.admin.setAgentCeiling({
|
|
10219
|
+
selector: { projectId: project },
|
|
10220
|
+
input: { ceiling }
|
|
10221
|
+
}));
|
|
10222
|
+
return run2.ok ? ceilingOutcome(outcomeOfEnvelope(run2.answer, settle2, ceilingText)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10223
|
+
}
|
|
10224
|
+
};
|
|
10225
|
+
|
|
10226
|
+
// packages/cli/src/commands/schema-update.ts
|
|
10227
|
+
var settleWith3 = (ref) => `repeat openeng schema-update show --ref ${ref}, which only reads`;
|
|
10228
|
+
var requestText = (value) => `schema update ${value.ref} ${value.state}`;
|
|
10229
|
+
var schemaOutcome = (outcome) => outcome.kind === "success" ? { ...outcome, value: { value: outcome.value } } : outcome;
|
|
10230
|
+
var schemaUpdateRequest = {
|
|
10231
|
+
words: ["schema-update", "request"],
|
|
10232
|
+
organisation: "required",
|
|
10233
|
+
usage: "openeng schema-update request --ref <ref>",
|
|
10234
|
+
help: [
|
|
10235
|
+
"openeng schema-update request --ref <ref>",
|
|
10236
|
+
"does: records a schema update request for the ref; execution is separate",
|
|
10237
|
+
protectionCapabilityHelp("requestSchemaUpdate"),
|
|
10238
|
+
"example: openeng schema-update request --ref project-one/work",
|
|
10239
|
+
"output: the ref and request state; under --json { scope, value }, with the full SchemaUpdateRequest in value"
|
|
10240
|
+
],
|
|
10241
|
+
run: async ({ host, deps, options }) => {
|
|
10242
|
+
const { ref } = options;
|
|
10243
|
+
if (ref === void 0) {
|
|
10244
|
+
return { kind: "client-refusal", message: "openeng schema-update request needs --ref <ref>" };
|
|
10245
|
+
}
|
|
10246
|
+
const settle2 = settleWith3(ref);
|
|
10247
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.branches.requestSchemaUpdate({
|
|
10248
|
+
input: { ref }
|
|
10249
|
+
}));
|
|
10250
|
+
return run2.ok ? schemaOutcome(outcomeOfEnvelope(run2.answer, settle2, requestText)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10251
|
+
}
|
|
10252
|
+
};
|
|
10253
|
+
var schemaUpdateShow = {
|
|
10254
|
+
words: ["schema-update", "show"],
|
|
10255
|
+
organisation: "required",
|
|
10256
|
+
usage: "openeng schema-update show --ref <ref>",
|
|
10257
|
+
help: [
|
|
10258
|
+
"openeng schema-update show --ref <ref>",
|
|
10259
|
+
"does: reads the latest visible schema update request for the ref",
|
|
10260
|
+
protectionCapabilityHelp("readSchemaUpdateRequest"),
|
|
10261
|
+
"example: openeng schema-update show --ref project-one/work --json",
|
|
10262
|
+
"output: the ref and state, or no request; under --json { scope, value }, value is SchemaUpdateRequest or null"
|
|
10263
|
+
],
|
|
10264
|
+
run: async ({ host, deps, options }) => {
|
|
10265
|
+
const { ref } = options;
|
|
10266
|
+
if (ref === void 0) {
|
|
10267
|
+
return { kind: "client-refusal", message: "openeng schema-update show needs --ref <ref>" };
|
|
10268
|
+
}
|
|
10269
|
+
const settle2 = settleWith3(ref);
|
|
10270
|
+
const run2 = await runAuthenticated(host, deps, (clients) => clients.branches.readSchemaUpdateRequest({
|
|
10271
|
+
input: { ref }
|
|
10272
|
+
}));
|
|
10273
|
+
return run2.ok ? schemaOutcome(outcomeOfEnvelope(
|
|
10274
|
+
run2.answer,
|
|
10275
|
+
settle2,
|
|
10276
|
+
(value) => value === null ? "no request" : requestText(value)
|
|
10277
|
+
)) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10278
|
+
}
|
|
10279
|
+
};
|
|
10280
|
+
|
|
9652
10281
|
// packages/cli/src/commands/types.ts
|
|
9653
10282
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
9654
10283
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
@@ -9766,9 +10395,9 @@ var typesList = {
|
|
|
9766
10395
|
return flags.outcome;
|
|
9767
10396
|
}
|
|
9768
10397
|
const projectId = flags.values.project;
|
|
9769
|
-
const
|
|
10398
|
+
const settle2 = "repeat openeng types list, which only reads";
|
|
9770
10399
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.objects.readCatalogue({ selector: { projectId }, input: {} }));
|
|
9771
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
10400
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, catalogueText) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9772
10401
|
}
|
|
9773
10402
|
};
|
|
9774
10403
|
var typesDraftOpen = {
|
|
@@ -9782,9 +10411,9 @@ var typesDraftOpen = {
|
|
|
9782
10411
|
"output: one line with the change set id and revision; under --json an object with changeSetId and revision"
|
|
9783
10412
|
],
|
|
9784
10413
|
run: async (context) => {
|
|
9785
|
-
const
|
|
10414
|
+
const settle2 = "openeng types draft current";
|
|
9786
10415
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.ontology.openChangeSet({ input: {} }));
|
|
9787
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
10416
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (opened) => `opened change set ${opened.changeSetId} at revision ${opened.revision}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9788
10417
|
}
|
|
9789
10418
|
};
|
|
9790
10419
|
var typesDraftCurrent = {
|
|
@@ -9798,9 +10427,9 @@ var typesDraftCurrent = {
|
|
|
9798
10427
|
"output: one line naming the change set and revision, or that none is open; under --json an object with changeSetId, revision and scope, or {scope, value: null} when none is open"
|
|
9799
10428
|
],
|
|
9800
10429
|
run: async (context) => {
|
|
9801
|
-
const
|
|
10430
|
+
const settle2 = "repeat openeng types draft current, which only reads";
|
|
9802
10431
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.ontology.readCurrentChangeSet({ input: {} }));
|
|
9803
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
10432
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (current) => current === null ? "no change set is open" : `change set ${current.changeSetId} at revision ${current.revision}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9804
10433
|
}
|
|
9805
10434
|
};
|
|
9806
10435
|
function listingOf(catalogue) {
|
|
@@ -9869,7 +10498,7 @@ var typesDraftShow = {
|
|
|
9869
10498
|
}
|
|
9870
10499
|
const changeSetId = flags.values.changeSet;
|
|
9871
10500
|
const projectId = context.options.project;
|
|
9872
|
-
const
|
|
10501
|
+
const settle2 = "repeat openeng types draft show, which only reads";
|
|
9873
10502
|
const run2 = await runAuthenticated(context.host, context.deps, async (clients) => {
|
|
9874
10503
|
const read2 = await clients.ontology.readChangeSet({ input: { changeSetId } });
|
|
9875
10504
|
if ("refusal" in read2) {
|
|
@@ -9891,11 +10520,11 @@ var typesDraftShow = {
|
|
|
9891
10520
|
return { read: read2.result, catalogue: catalogue2.result };
|
|
9892
10521
|
});
|
|
9893
10522
|
if (!run2.ok) {
|
|
9894
|
-
return outcomeOfSessionFailure(run2.failure,
|
|
10523
|
+
return outcomeOfSessionFailure(run2.failure, settle2);
|
|
9895
10524
|
}
|
|
9896
10525
|
const answer = run2.answer;
|
|
9897
10526
|
if ("refusal" in answer) {
|
|
9898
|
-
return outcomeOfRouteRefusal(answer.refusal,
|
|
10527
|
+
return outcomeOfRouteRefusal(answer.refusal, settle2, answer.correlationId);
|
|
9899
10528
|
}
|
|
9900
10529
|
const { read, catalogue } = answer;
|
|
9901
10530
|
if (catalogue === null) {
|
|
@@ -9944,14 +10573,14 @@ var typesExport = {
|
|
|
9944
10573
|
return flags.outcome;
|
|
9945
10574
|
}
|
|
9946
10575
|
const projectId = flags.values.project;
|
|
9947
|
-
const
|
|
10576
|
+
const settle2 = "repeat openeng types export, which only reads";
|
|
9948
10577
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.objects.readCatalogue({ selector: { projectId }, input: {} }));
|
|
9949
10578
|
if (!run2.ok) {
|
|
9950
|
-
return outcomeOfSessionFailure(run2.failure,
|
|
10579
|
+
return outcomeOfSessionFailure(run2.failure, settle2);
|
|
9951
10580
|
}
|
|
9952
10581
|
const envelope = run2.answer;
|
|
9953
10582
|
if ("refusal" in envelope) {
|
|
9954
|
-
return outcomeOfRouteRefusal(envelope.refusal,
|
|
10583
|
+
return outcomeOfRouteRefusal(envelope.refusal, settle2, envelope.correlationId);
|
|
9955
10584
|
}
|
|
9956
10585
|
if (envelope.replayed === true) {
|
|
9957
10586
|
return { kind: "internal-failure", message: "the host answered a replay to a read that carried no idempotency key" };
|
|
@@ -9980,9 +10609,9 @@ var typesDraftState = {
|
|
|
9980
10609
|
return flags.outcome;
|
|
9981
10610
|
}
|
|
9982
10611
|
const changeSetId = flags.values.changeSet;
|
|
9983
|
-
const
|
|
10612
|
+
const settle2 = "repeat openeng types draft state, which only reads";
|
|
9984
10613
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.ontology.readChangeSetState({ input: { changeSetId } }));
|
|
9985
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
10614
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (state) => `change set ${changeSetId} is ${state.state} at revision ${state.revision}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
9986
10615
|
}
|
|
9987
10616
|
};
|
|
9988
10617
|
function changesOfFile(path) {
|
|
@@ -10056,13 +10685,13 @@ var typesDraftRevise = {
|
|
|
10056
10685
|
return groups.outcome;
|
|
10057
10686
|
}
|
|
10058
10687
|
const { railGroups } = groups;
|
|
10059
|
-
const
|
|
10688
|
+
const settle2 = settleChangeSet(changeSetId);
|
|
10060
10689
|
const run2 = await runAuthenticated(
|
|
10061
10690
|
context.host,
|
|
10062
10691
|
context.deps,
|
|
10063
10692
|
(clients) => clients.ontology.reviseChangeSet({ input: { changeSetId, expectedRevision, changes, ...railGroups === void 0 ? {} : { railGroups } } })
|
|
10064
10693
|
);
|
|
10065
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
10694
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (revised) => `revised change set ${changeSetId} to revision ${revised.revision}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10066
10695
|
}
|
|
10067
10696
|
};
|
|
10068
10697
|
var typesDraftValidate = {
|
|
@@ -10081,13 +10710,13 @@ var typesDraftValidate = {
|
|
|
10081
10710
|
return flags.outcome;
|
|
10082
10711
|
}
|
|
10083
10712
|
const { changeSet: changeSetId, revision } = flags.values;
|
|
10084
|
-
const
|
|
10713
|
+
const settle2 = "repeat openeng types draft validate, which only reads";
|
|
10085
10714
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.ontology.validateChangeSet({ input: { changeSetId, revision } }));
|
|
10086
10715
|
if (!run2.ok) {
|
|
10087
|
-
return outcomeOfSessionFailure(run2.failure,
|
|
10716
|
+
return outcomeOfSessionFailure(run2.failure, settle2);
|
|
10088
10717
|
}
|
|
10089
10718
|
let violated = false;
|
|
10090
|
-
const outcome = outcomeOfEnvelope(run2.answer,
|
|
10719
|
+
const outcome = outcomeOfEnvelope(run2.answer, settle2, (validated) => {
|
|
10091
10720
|
violated = validated.violations.length > 0;
|
|
10092
10721
|
return violated ? [`${String(validated.violations.length)} ${validated.violations.length === 1 ? "violation" : "violations"}`, ...validated.violations.map((violation) => ` ${JSON.stringify(violation)}`)].join("\n") : `change set ${changeSetId} at revision ${revision} has no violations`;
|
|
10093
10722
|
});
|
|
@@ -10110,9 +10739,9 @@ var typesDraftDiscard = {
|
|
|
10110
10739
|
return flags.outcome;
|
|
10111
10740
|
}
|
|
10112
10741
|
const changeSetId = flags.values.changeSet;
|
|
10113
|
-
const
|
|
10742
|
+
const settle2 = settleChangeSet(changeSetId);
|
|
10114
10743
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.ontology.discardChangeSet({ input: { changeSetId } }));
|
|
10115
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
10744
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, () => `discarded change set ${changeSetId}`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10116
10745
|
}
|
|
10117
10746
|
};
|
|
10118
10747
|
var typesDraftAccept = {
|
|
@@ -10131,10 +10760,10 @@ var typesDraftAccept = {
|
|
|
10131
10760
|
return flags.outcome;
|
|
10132
10761
|
}
|
|
10133
10762
|
const { changeSet: changeSetId, revision } = flags.values;
|
|
10134
|
-
const
|
|
10763
|
+
const settle2 = settleChangeSet(changeSetId);
|
|
10135
10764
|
const key = randomUUID4();
|
|
10136
10765
|
const run2 = await runAuthenticated(context.host, context.deps, (clients) => clients.ontology.acceptChangeSet({ input: { changeSetId, revision } }, key));
|
|
10137
|
-
return run2.ok ? outcomeOfEnvelope(run2.answer,
|
|
10766
|
+
return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (accepted) => `accepted change set ${changeSetId}: ${String(accepted.versionIds.length)} type versions published`) : outcomeOfSessionFailure(run2.failure, settle2);
|
|
10138
10767
|
}
|
|
10139
10768
|
};
|
|
10140
10769
|
|
|
@@ -10200,6 +10829,18 @@ var PUBLIC_HAND_WRITTEN_COMMANDS = [
|
|
|
10200
10829
|
orgCurrent,
|
|
10201
10830
|
projectsList,
|
|
10202
10831
|
projectsCreate,
|
|
10832
|
+
rulesAdd,
|
|
10833
|
+
rulesList,
|
|
10834
|
+
rulesRemove,
|
|
10835
|
+
orgRefsCreate,
|
|
10836
|
+
orgRefsList,
|
|
10837
|
+
orgRefsDelete,
|
|
10838
|
+
orgRefsMarkReadOnly,
|
|
10839
|
+
locksSet,
|
|
10840
|
+
ceilingShow,
|
|
10841
|
+
ceilingSet,
|
|
10842
|
+
schemaUpdateRequest,
|
|
10843
|
+
schemaUpdateShow,
|
|
10203
10844
|
typesList,
|
|
10204
10845
|
typesExport,
|
|
10205
10846
|
typesDraftOpen,
|
|
@@ -10240,6 +10881,14 @@ var CLI_OPTIONS = {
|
|
|
10240
10881
|
json: { type: "boolean" },
|
|
10241
10882
|
"no-open": { type: "boolean" },
|
|
10242
10883
|
project: { type: "string" },
|
|
10884
|
+
organisation: { type: "boolean" },
|
|
10885
|
+
"read-only": { type: "boolean" },
|
|
10886
|
+
object: { type: "string" },
|
|
10887
|
+
lock: { type: "string" },
|
|
10888
|
+
ceiling: { type: "string" },
|
|
10889
|
+
pattern: { type: "string" },
|
|
10890
|
+
consequence: { type: "string" },
|
|
10891
|
+
"rule-id": { type: "string" },
|
|
10243
10892
|
ref: { type: "string" },
|
|
10244
10893
|
name: { type: "string" },
|
|
10245
10894
|
"change-set": { type: "string" },
|
|
@@ -10263,7 +10912,7 @@ var CLI_OPTIONS = {
|
|
|
10263
10912
|
};
|
|
10264
10913
|
|
|
10265
10914
|
// packages/cli/src/cli-version.ts
|
|
10266
|
-
var PATCH_VERSION =
|
|
10915
|
+
var PATCH_VERSION = 4;
|
|
10267
10916
|
var CLI_VERSION = `0.${PROTOCOL_VERSION}.${PATCH_VERSION}`;
|
|
10268
10917
|
|
|
10269
10918
|
// packages/cli/src/environment.ts
|
|
@@ -10377,6 +11026,14 @@ function parseInvocation(argv) {
|
|
|
10377
11026
|
json: values.json === true,
|
|
10378
11027
|
open: values["no-open"] !== true,
|
|
10379
11028
|
project: values.project,
|
|
11029
|
+
organisation: values.organisation === true,
|
|
11030
|
+
readOnly: values["read-only"] === true,
|
|
11031
|
+
object: values.object,
|
|
11032
|
+
lock: values.lock,
|
|
11033
|
+
ceiling: values.ceiling,
|
|
11034
|
+
pattern: values.pattern,
|
|
11035
|
+
consequence: values.consequence,
|
|
11036
|
+
ruleId: values["rule-id"],
|
|
10380
11037
|
ref: values.ref,
|
|
10381
11038
|
name: values.name,
|
|
10382
11039
|
changeSet: values["change-set"],
|