@openengio/cli 0.27.1 → 0.33.0

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.
@@ -51,9 +51,24 @@ var IMPORT_FAILURE_TEXT = Object.freeze({
51
51
  "mirror-row-unreadable": "a row the connector wrote in the mirror project has lost a value the connector stamps on it (its upstream identifier, upstream document identifier or upstream status); a person who writes the mirror project restores it or deletes the row, and the next run creates it again"
52
52
  });
53
53
 
54
- // packages/api-contract/dist/query-parser.js
54
+ // packages/api-contract/dist/description-parsing.js
55
55
  var LINK_DIRECTIONS = Object.freeze(["outgoing", "incoming", "to-children", "to-parent"]);
56
- var AGGREGATE_OPERATIONS = Object.freeze(["count", "min", "max", "sum"]);
56
+
57
+ // packages/api-contract/dist/query-parser.js
58
+ var SET_OPERATORS = Object.freeze(["union", "intersection", "difference"]);
59
+ var AGGREGATE_OPERATIONS = Object.freeze(["count", "min", "max", "sum", "average"]);
60
+
61
+ // packages/api-contract/dist/entry-form.js
62
+ function verbEntry(type) {
63
+ const subjects = type.allowedSubjectTypes;
64
+ return { ...type, allowedSubjectTypes: subjects.kind === "none" ? "none" : subjects.types };
65
+ }
66
+ function entryTypeOf(type) {
67
+ return type.typeCategory === "verb" ? verbEntry(type) : type;
68
+ }
69
+ function entryChangesOf(changes) {
70
+ return Object.freeze(Object.fromEntries(Object.entries(changes).map(([key, type]) => [key, entryTypeOf(type)])));
71
+ }
57
72
 
58
73
  // packages/api-contract/dist/refusal-catalogue.js
59
74
  function entry(meaning, ...next) {
@@ -64,6 +79,14 @@ var FIX_REQUEST = { option: "Correct the request and send it again." };
64
79
  var ASK_ADMINISTRATOR = { option: "Ask an administrator of the organisation to make the change or to grant the permission." };
65
80
  var SIGN_IN_AGAIN = { option: "Sign in again." };
66
81
  var RULE_ENTRIES = {
82
+ "unsupported-content": entry("The file's content or name is not an admitted attachment format.", FIX_REQUEST),
83
+ "too-large": entry("The attachment exceeds the per-file byte limit.", FIX_REQUEST),
84
+ "not-an-attachment-property": entry("The object's stored type version does not declare this property as an attachment.", FIX_REQUEST),
85
+ "no-attachment": entry("The property holds no attachment."),
86
+ "attachment-unavailable": entry("The attachment's stored bytes are unavailable.", { option: "Ask an administrator to restore the attachment." }),
87
+ "unknown-attachment": entry("The changed attachment has not been staged for you in this project.", FIX_REQUEST),
88
+ "attachment-precondition": entry("The attachment's media type or byte count differs from its stored metadata.", FIX_REQUEST),
89
+ "attachment-class-mismatch": entry("The attachment's class is not admitted by this property.", FIX_REQUEST),
67
90
  "not-permitted": entry("The operation was refused. What the request names may not exist, or you may not have permission for it; the answer is the same either way.", { option: "Check that the request names something you can reach; if it does, ask an administrator for the permission." }),
68
91
  "grant-scope": entry("The application was not given the permission this operation needs; the refusal names that permission.", { option: "Ask the person to connect the application again with the permission the refusal names." }),
69
92
  "not-in-this-release": entry("This operation is not available in this release."),
@@ -80,6 +103,7 @@ var RULE_ENTRIES = {
80
103
  read: "readChangeSet"
81
104
  }),
82
105
  "version-conflict": entry("Another change already published a version of a type that this change set also publishes.", { option: "Read the change set and the published types, then revise the change set to the next version.", read: "readChangeSet" }),
106
+ "owned-type-not-presentation": entry("A connector-owned type permits only presentation changes to a later object or edge version. First versions and verbs are refused; the detail names the requested type key and the refused column.", { option: "Keep the type's data fields unchanged and publish only the permitted presentation changes." }),
83
107
  "key-under-another-kind": entry("A type key in the change set is already used by a type of another kind.", { option: "Read the change set, choose a different key and revise it.", read: "readChangeSet" }),
84
108
  "namespace-not-active": entry("The organisation's types are not active, so nothing can be published to them.", ASK_ADMINISTRATOR),
85
109
  "invalid-configuration": entry("The agent is not set up for this request.", ASK_ADMINISTRATOR),
@@ -89,13 +113,14 @@ var RULE_ENTRIES = {
89
113
  "plan-superseded": entry("A newer plan replaced this one.", { option: "Read the agent session.", read: "readAgentSession" }),
90
114
  "plan-closed": entry("The plan is closed, so it takes no further change.", { option: "Read the agent session.", read: "readAgentSession" }),
91
115
  "plan-not-open": entry("The plan is not open.", { option: "Read the agent session.", read: "readAgentSession" }),
116
+ "unknown-role": entry("The role key is unknown to this deployment.", { option: "Choose a role key from roleKeys and send the request again." }),
92
117
  "above-caller-role": entry("The request would give a role that is higher than your own, or change one.", ASK_ADMINISTRATOR),
93
118
  "last-administrator": entry("The change would leave no administrator.", { option: "Name another administrator first." }),
94
119
  "erasure-not-permitted": entry("The erasure is not permitted.", ASK_ADMINISTRATOR),
95
120
  "no-such-membership": entry("The membership the request names is not one you may change.", FIX_REQUEST),
96
121
  "capability-missing": entry("You do not have the permission this operation needs.", ASK_ADMINISTRATOR),
97
- "window-out-of-range": entry("A time window in the request is outside the allowed range.", FIX_REQUEST),
98
- "max-session-out-of-range": entry("The sign-in length in the request is outside the allowed range.", FIX_REQUEST),
122
+ "window-out-of-range": entry("The requested session-refresh window must be from 1 through 60,000 milliseconds.", FIX_REQUEST),
123
+ "max-session-out-of-range": entry("The requested session lifetime must be from 1 through 2,592,000 seconds.", FIX_REQUEST),
99
124
  "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
125
  "already-invited": entry("The organisation already has a pending invitation to this address.", { option: "List the pending invitations.", read: "listInvitations" }),
101
126
  "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" }),
@@ -108,6 +133,7 @@ var RULE_ENTRIES = {
108
133
  "service_identity.revoke": entry("The service account was not revoked: you do not administer it.", ASK_ADMINISTRATOR),
109
134
  "duplicate-name": entry("The name is already in use.", { option: "Choose another name." }),
110
135
  "unknown-credential": entry("The credential was not accepted.", { option: "Check the credential and send it again, or ask for a new one." }),
136
+ "token-kind-not-admitted": entry("This operation does not take this kind of token. Its reference lists the kinds of token it takes.", { option: "Use a kind of token this operation takes." }),
111
137
  secret: entry("The credential was not accepted.", { option: "Check the credential and send it again, or ask for a new one." }),
112
138
  kind: entry("The sign-in was refused for this kind of account.", ASK_ADMINISTRATOR),
113
139
  lifecycle: entry("The sign-in was refused because of the state of this account.", ASK_ADMINISTRATOR),
@@ -122,14 +148,15 @@ var RULE_ENTRIES = {
122
148
  expiry: entry("The sign-in token has expired.", SIGN_IN_AGAIN),
123
149
  algorithm: entry("The sign-in token was not accepted.", SIGN_IN_AGAIN),
124
150
  claims: entry("The sign-in token was not accepted.", SIGN_IN_AGAIN),
125
- "malformed-query": entry("The query is not one the platform can run.", FIX_REQUEST),
151
+ "malformed-query": entry("The query is not one the platform can run; the refusal identifies the path of the invalid field.", FIX_REQUEST),
126
152
  "view-not-drawable": entry("The published view steps over an edge type that has no parent end, so it places no object under another and cannot be drawn as a tree.", { option: "Ask the type's author to change the view, or to step over an edge type that has a parent end." }),
127
153
  "text-search-unavailable": entry("Text search is a filter of kind text, not a search key.", { option: "Send the term as a filter of kind text." }),
128
154
  "search-too-wide": entry("The text match names more properties than one query may match.", { option: "Name the object type the match is over." }),
129
155
  "invalid-continuation": entry("The paging token is not one the platform issued for this request.", { option: "Start the read again from its first page." }),
130
156
  "stale-continuation": entry("The paging token was issued for an earlier state.", { option: "Start the read again from its first page." }),
131
157
  "head-moved": entry("The branch changed while the pages were being read.", { option: "Start the read again from its first page." }),
132
- "over-bound": entry("The request is larger than the platform allows.", FIX_REQUEST),
158
+ "cycle-in-reach": entry("A per-path repeat reach returned to an object already in that path's ancestors; the refusal names the readable object.", { option: "Remove the cycle, or use distinct multiplicity, which admits cycles." }),
159
+ "over-bound": entry("The request exceeds a graph, structure, path, or query limit.", FIX_REQUEST),
133
160
  "malformed-history-request": entry("The history request is not one the platform can run.", FIX_REQUEST),
134
161
  "protected-ref": entry("This branch is protected, so an agent cannot write to it.", { option: "Write to another branch." }),
135
162
  immutable: entry("The record's type is immutable, so it cannot be changed or deleted on any branch.", { option: "Leave the record unchanged." }),
@@ -137,10 +164,11 @@ var RULE_ENTRIES = {
137
164
  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
165
  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
166
  "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." }),
167
+ "stale-source": entry("The source commit is not the current commit on the named branch.", { option: "Read a branch you can use and merge its current commit." }),
140
168
  "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
169
  "organisation-not-ready": entry("The organisation's trunk is not ready yet.", { option: "Try again shortly." }),
142
170
  "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" }),
171
+ "ref-exists": entry("An organisation branch or baseline of that name already exists.", { option: "List the organisation's branches and baselines.", read: "listOrganisationRefs" }),
144
172
  "concurrent-change": entry("Another write changed the record first, so nothing was applied.", { option: "Try again shortly." }),
145
173
  "lock-unavailable": entry("The lock could not be taken now, so nothing was applied.", { option: "Try again shortly." }),
146
174
  "organisation-not-active": entry("The organisation is not active.", ASK_ADMINISTRATOR),
@@ -168,8 +196,8 @@ var RULE_ENTRIES = {
168
196
  "connector-template-missing": entry("This deployment holds no type template for the connector's system.")
169
197
  };
170
198
  var KIND_ENTRIES = {
171
- unauthenticated: entry("The request carried no sign-in it can use: none, an invalid or expired one, or one of a kind this request does not take.", { option: "Sign in, or use the kind of token this route takes, and send the request again." }),
172
- "not-found": entry("What the request names does not exist, or you may not reach it; the answer is the same either way.", { option: "Check the identifiers; list what you may read.", read: "listProjects" }),
199
+ unauthenticated: entry("The request carried no sign-in it can use: none, or an invalid or expired one.", { option: "Sign in and send the request again." }),
200
+ "not-found": entry("What the request names does not exist, or you may not reach it; the answer is the same either way.", { option: "Check the identifiers; list what you may read.", read: "listProjects" }, { option: "If the request names a verb, list the verbs available for the object.", read: "discoverVerbs" }),
173
201
  "session-moved": entry("Your sign-in is attached to another organisation than the one the token names.", { option: "Sign in again to the organisation your sign-in is attached to." }),
174
202
  "not-attached": entry("Your sign-in is attached to no organisation, and this request acts inside one.", { option: "Attach your sign-in to an organisation, then send the request again." }),
175
203
  "invalid-request": entry("The request is not in the shape the call takes.", FIX_REQUEST),
@@ -187,13 +215,15 @@ var CLASS_ENTRIES = {
187
215
  };
188
216
  var API_RULE_ENTRIES = {
189
217
  "not-found": KIND_ENTRIES["not-found"],
218
+ "token-kind-not-admitted": RULE_ENTRIES["token-kind-not-admitted"],
190
219
  immutable: RULE_ENTRIES.immutable,
191
220
  owned: RULE_ENTRIES.owned,
192
221
  frozen: RULE_ENTRIES.frozen,
193
222
  protected: RULE_ENTRIES.protected,
194
223
  "branch-needs-schema-update": RULE_ENTRIES["branch-needs-schema-update"],
195
224
  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." }),
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" }),
225
+ "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" }, { option: "If looking for a verb, list the verbs available for the object.", read: "discoverVerbs" }),
226
+ "unknown-verb": entry("The object has no verb with that name.", { option: "List the verbs available for the object.", read: "discoverVerbs" }),
197
227
  "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." }),
198
228
  "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." }),
199
229
  "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." }),
@@ -239,7 +269,8 @@ var API_REFUSAL_RULES = Object.freeze([
239
269
  "cross-organisation-edge",
240
270
  "project-not-an-endpoint",
241
271
  "self-parent",
242
- "descendant-parent"
272
+ "descendant-parent",
273
+ "token-kind-not-admitted"
243
274
  ]);
244
275
  var SHIM_COLLIDING_API_RULES = Object.freeze(["write-refused"]);
245
276
 
@@ -267,13 +298,30 @@ var PROTECTION_ROUTE_CAPABILITIES = Object.freeze({
267
298
  ]),
268
299
  readSchemaUpdateRequest: Object.freeze([Object.freeze({ visibility: "requester-in-token-organisation" })])
269
300
  });
270
- var SIGNED_IN = ["unauthenticated", "invalid-request", "bound-exceeded", "internal"];
301
+ var SIGNED_IN = [
302
+ "unauthenticated",
303
+ "token-kind-not-admitted",
304
+ "invalid-request",
305
+ "bound-exceeded",
306
+ "internal"
307
+ ];
271
308
  var SCOPED = [...SIGNED_IN, "not-found", "not-permitted"];
272
309
  var WRITE = [...SCOPED, "in-flight", "unknown-outcome"];
273
310
  var REF_READ = [...SCOPED, "organisation-not-ready", "branch-needs-schema-update"];
274
311
  var REF_WRITE = [...REF_READ, "in-flight", "unknown-outcome"];
312
+ var ATTACHMENT_SCOPED = [
313
+ ...SIGNED_IN,
314
+ "protocol-mismatch",
315
+ "not-found",
316
+ "not-attached",
317
+ "session-moved",
318
+ "grant-scope"
319
+ ];
275
320
  var OBJECT_WRITE = [
276
321
  ...REF_WRITE,
322
+ "unknown-attachment",
323
+ "attachment-precondition",
324
+ "attachment-class-mismatch",
277
325
  "immutable",
278
326
  "owned",
279
327
  "frozen",
@@ -284,14 +332,15 @@ var OBJECT_WRITE = [
284
332
  ];
285
333
  var PUBLIC = ["invalid-request", "bound-exceeded", "internal"];
286
334
  var CHANGE_SET = [...SIGNED_IN, "not-permitted", "stale-revision", "not-open"];
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.';
335
+ var QUERY_PROJECT_SCOPE = 'Without input.projects, it reads every project the caller can read on the selected branch or baseline; selector.projectId does not narrow the set. To limit it to one project, include "projects":["<projectId>"] in input.';
336
+ var GRAPH_QUERY_PROJECT_SCOPE = 'Without input.start.projects, it reads every project the caller can read on the selected ref; selector.projectId does not narrow the set. To limit it to some projects, include "projects":["<projectId>"] in input.start.';
288
337
  function doc(does, refuses) {
289
338
  return Object.freeze({ does, refuses: Object.freeze([...refuses]) });
290
339
  }
291
340
  var ROUTE_DOCS = Object.freeze({
292
341
  createObjectSet: doc("Saves a named set of 1 to 200 object addresses in the caller's organisation. Concurrent retries with one key return the same saved set and revision.", [...SCOPED, "head-moved"]),
293
342
  listObjectSets: doc("Lists the organisation's saved sets, newest update first, without members or counts.", SIGNED_IN),
294
- readObjectSet: doc("Reads a saved set's visible objects on the selected ref, a count of missing visible members and one bit for members outside the caller's scope.", [...SCOPED, "head-moved"]),
343
+ readObjectSet: doc("Reads a saved set's visible objects on the selected branch or baseline, a count of missing visible members and one bit for members outside the caller's scope.", [...SCOPED, "head-moved"]),
295
344
  updateObjectSet: doc("Renames a saved set or replaces its readable members at the expected revision. Members outside the caller's scope remain. A success raises the revision by one.", [...SCOPED, "stale-revision", "head-moved"]),
296
345
  deleteObjectSet: doc("Deletes a saved set and every member at the expected revision.", [...SCOPED, "stale-revision"]),
297
346
  health: doc("Answers whether the host is running.", PUBLIC),
@@ -312,8 +361,10 @@ var ROUTE_DOCS = Object.freeze({
312
361
  decideConsent: doc("Approves or denies a pending authorization request.", SCOPED),
313
362
  listConnectedApps: doc("Lists the applications the caller has connected.", SIGNED_IN),
314
363
  revokeConnectedApp: doc("Disconnects an application: every grant the caller holds for it stops.", SCOPED),
315
- readObject: doc("Reads one object at a ref.", REF_READ),
316
- queryObjects: doc(`Runs a filtered, ordered, paged query over the objects of a ref. ${QUERY_PROJECT_SCOPE}`, [
364
+ stageAttachment: doc("Stages attachment bytes for the selected project and ref without writing an engineering row. Admits user, service, client and run-apply tokens.", [...ATTACHMENT_SCOPED, "unsupported-content", "too-large"]),
365
+ readAttachment: doc("Downloads the attachment held by an object's property at its stored type version. Admits user, service, client, run-explore and run-apply tokens.", [...ATTACHMENT_SCOPED, "organisation-not-ready", "branch-needs-schema-update", "not-an-attachment-property", "no-attachment", "attachment-unavailable"]),
366
+ readObject: doc("Reads one object at a branch or baseline.", REF_READ),
367
+ queryObjects: doc(`Runs a filtered, ordered, paged query over the objects of a branch or baseline, or pages the union, intersection or difference of two plain object-set descriptions on that ref. ${QUERY_PROJECT_SCOPE}`, [
317
368
  ...REF_READ,
318
369
  "malformed-query",
319
370
  "over-bound",
@@ -323,10 +374,11 @@ var ROUTE_DOCS = Object.freeze({
323
374
  "stale-continuation",
324
375
  "head-moved"
325
376
  ]),
326
- 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"]),
377
+ queryRows: doc("Answers rows of named cells over a start set and up to three hops, or groups with counts, sums, minimums, maximums and weighted sums. Each hop names edgeTypeKeys as any or 1 through 8 names; optional targetTypeKeys also takes 1 through 8 names. Empty lists are malformed-query; more than 8 names is over-bound. A final hop may repeat to depth 1 through 3, without filters or targetTypeKeys, and answers groups only; a depth above 3 is over-bound, while 0, non-integers and non-numbers are malformed-query. A parent group key may name a repeat alias and uses its own edgeTypeKeys and optional parents filter. Each parent edge contributes a membership; a child with no matching parent forms no group. Parent keys carry address and readable, including readable: false for unreadable parents; hidden reached objects are counted per level including project, never keyed. After a successful walk, parent reads batch 100 children, at most 60 statements per key or 120 for two keys; an overflowing walk runs none. A weighted sum requires a final repeat hop and names 1 through 8 contributing types in over, an edge weight property and per-path or distinct multiplicity; the start never contributes. On an ancestor return, count and per-path sum or weightedSum refuse cycle-in-reach naming the readable object; distinct measures, min and max admit cycles. Repeat answers carry deeper, unvalued and unweighted; missing values and weights are counted separately. Every measure over a path names ends: visible or all. With any all measure, hidden counts appear per hop, on each group when every key names start, and on the answer otherwise; values still measure readable objects. Hidden counts deduplicate far identities including project per hop. countDistinct cannot be combined with sum, min or max. A property group key cannot mix numeric and nonnumeric declarations across its alias types. Distinct-count answers ordered by a measure or filtered by having, and hidden start-group merges, require complete reads: truncation refuses over-bound instead of returning a bounded prefix. " + GRAPH_QUERY_PROJECT_SCOPE, [...REF_READ, "malformed-query", "over-bound", "search-too-wide", "invalid-continuation", "stale-continuation", "head-moved", "cycle-in-reach"]),
378
+ aggregateObjects: doc(`Deprecated: use queryRows for graph aggregates. Runs an aggregate over the objects of a branch or baseline: a count, or a minimum, maximum, sum or average of one numeric property, answered as one value (an average also carries its count), or, with groupBy, a count, sum or average 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"]),
327
379
  discoverVerbs: doc("Lists the verbs an object may be given.", REF_READ),
328
380
  readHistory: doc("Reads one object's history of changes.", [...REF_READ, "invalid-continuation", "stale-continuation", "malformed-history-request"]),
329
- 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"]),
381
+ mutate: doc('Creates, changes or deletes an object on the selected writable branch. 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"]),
330
382
  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"]),
331
383
  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"]),
332
384
  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),
@@ -340,7 +392,7 @@ var ROUTE_DOCS = Object.freeze({
340
392
  previewDelete: doc("Previews deleting an object: the links the delete would remove, or the refusal it would meet. Changes nothing.", [...OBJECT_WRITE, "plan-closed"]),
341
393
  recover: doc("Finds what an interrupted mutation did and finishes its record.", REF_READ),
342
394
  executeVerb: doc("Runs a verb on an object and records its result.", [...OBJECT_WRITE, "plan-closed"]),
343
- createBranch: doc("Creates a branch from a ref or an admitted current ref head.", [
395
+ createBranch: doc("Creates a project branch from a branch, a baseline or an admitted current head.", [
344
396
  ...REF_WRITE,
345
397
  "plan-closed",
346
398
  "ref-exists",
@@ -349,15 +401,11 @@ var ROUTE_DOCS = Object.freeze({
349
401
  "lock-unavailable",
350
402
  "not-a-ref-head"
351
403
  ]),
352
- 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"]),
353
- readMergeConflicts: doc("Reads the conflicts a merge refused on.", REF_READ),
354
- disposeRef: doc("Disposes a branch that is no longer wanted.", [
355
- ...WRITE,
356
- "concurrent-change",
357
- "lock-unavailable"
358
- ]),
404
+ merge: doc("Merges a reviewed head of a project branch or an organisation branch or baseline source into main, or into the writable branch the optional target names; absent target means main. For a proposal, send its reviewedHash as sourceHash. A successful merge into main completes every pending proposal in the project that reviewed that hash. Optional name is checked against the source branch's bound head and is refused stale-source when it differs.", [...REF_WRITE, "read-only-ref", "concurrent-change", "lock-unavailable", "not-a-ref-head", "stale-source"]),
405
+ readMergeConflicts: doc("Reads conflicts for the source branch named in input.name, always comparing it with main. For each field, base is the common value before either side changed it, ours is main, and theirs is the source branch. If the merge targeted another branch, this read still compares with main and does not report that merge's conflicts.", REF_READ),
406
+ disposeRef: doc("Disposes a branch that is no longer wanted: a writer of the branch when no proposal on it is pending, otherwise a merger of the project.", [...WRITE, "concurrent-change", "lock-unavailable"]),
359
407
  listProjects: doc("Lists every project the caller may read in the organisation the session is attached to, with its namespace.", SIGNED_IN),
360
- 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"]),
408
+ listRefs: doc("Lists the branches of a project, each with its head: readable with a hash, withheld when the caller may not read the branch, or unread past the first 50 branches.", [...SCOPED, "organisation-not-ready"]),
361
409
  readCatalogue: doc("Reads the published catalogue of a project's namespace.", SCOPED),
362
410
  readPendingProposal: doc("Reads the proposal waiting for review on a branch, if any.", SCOPED),
363
411
  submitProposal: doc("Submits a branch for review.", [...REF_READ, "proposal-open", "no-commits"]),
@@ -365,23 +413,34 @@ var ROUTE_DOCS = Object.freeze({
365
413
  revokeServiceIdentity: doc("Revokes a service identity.", [...SIGNED_IN, "not-permitted", "service_identity.revoke"]),
366
414
  issueServiceCredential: doc("Issues a credential for a service identity.", [...SIGNED_IN, "not-permitted", "capability-missing"]),
367
415
  revokeServiceCredential: doc("Revokes a service identity's credential.", [...SIGNED_IN, "not-permitted", "capability-missing"]),
368
- grantMembership: doc("Grants a principal a role in a scope.", [...SIGNED_IN, "not-permitted", "above-caller-role", "membership-exists", "no-such-principal"]),
416
+ grantMembership: doc("Grants a principal a role in a scope. An unknown role answers unknown-role with the deployment's roleKeys.", [...SIGNED_IN, "not-permitted", "above-caller-role", "unknown-role", "membership-exists", "no-such-principal"]),
369
417
  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"]),
370
418
  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"]),
419
+ setModelId: doc("Changes the model an organisation's agents use, keeping the key it holds, for a caller who administers agents.", [...SIGNED_IN, "not-permitted", "model-not-configured"]),
420
+ readModelConfigurationStatus: doc("Reads whether the caller's organisation has a model configured, and its provider, model and the time it was set, for a caller who administers agents. The key is never answered.", [...SIGNED_IN, "not-permitted"]),
421
+ readAccount: doc("Reads the caller's own principal identifier, display name and registered email.", SIGNED_IN),
371
422
  readDisplayNames: doc("Reads the display names of principals the caller may see.", SIGNED_IN),
372
423
  listMembers: doc("Lists the members of a project.", SCOPED),
373
- changeMembershipRole: doc("Changes a principal's role in a scope.", [...SIGNED_IN, "not-permitted", "above-caller-role", "last-administrator", "no-such-membership"]),
424
+ changeMembershipRole: doc("Changes a principal's role in a scope.", [...SIGNED_IN, "not-permitted", "above-caller-role", "unknown-role", "last-administrator", "no-such-membership"]),
374
425
  listOrganisationMembers: doc("Lists the memberships of the caller's organisation and of the projects of it the caller may read.", SCOPED),
375
426
  searchPeople: doc("Finds the people of the caller's organisation whose name has a word starting with the query.", [...SIGNED_IN, "invalid-query"]),
376
- searchObjectReaders: doc("Finds the people who can read an object on a ref, by a name prefix.", [...REF_READ, "invalid-query", "invalid-ref"]),
427
+ searchObjectReaders: doc("Finds the people who can read an object on a branch or baseline, by a name prefix.", [...REF_READ, "invalid-query", "invalid-ref"]),
377
428
  listSubscribers: doc("Lists the subscriptions on an object.", REF_READ),
378
429
  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"]),
379
430
  removeSubscriber: doc("Removes a person's subscription to an object in a role.", [...REF_READ, "subscription-absent", "not-permitted", "invalid-ref"]),
380
431
  listComments: doc("Lists the comments on an object, oldest first, a page at a time.", [...REF_READ, "invalid-query"]),
381
432
  addComment: doc("Adds a comment to an object, naming the people it mentions.", [...REF_WRITE, "invalid-body", "invalid-mention", "unknown-person", "invalid-ref"]),
382
433
  listServiceIdentities: doc("Lists the service identities of the caller's organisation, for a caller who administers them.", SCOPED),
383
- 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"]),
384
- listInvitations: doc("Lists the pending invitations of the caller's organisation, for a caller who administers its members.", [...SIGNED_IN, "capability-missing"]),
434
+ createInvitation: doc("Invites an address in an organisation role with up to 50 optional projectRoles, each a projectId and roleKey. Every project must belong to the invitation's organisation. The caller must administer members there and on each project. An unknown role answers unknown-role with the deployment's roleKeys; a known role above the caller's answers above-caller-role.", [
435
+ ...SIGNED_IN,
436
+ "capability-missing",
437
+ "above-caller-role",
438
+ "unknown-role",
439
+ "invalid-email",
440
+ "already-invited",
441
+ "domain-not-allowed"
442
+ ]),
443
+ listInvitations: doc("Lists pending invitations of the caller's organisation, including each invitation's projectRoles, for a caller who administers its members.", [...SIGNED_IN, "capability-missing"]),
385
444
  revokeInvitation: doc("Revokes a pending invitation of the caller's organisation, for a caller who administers its members.", [...SIGNED_IN, "capability-missing", "no-such-invitation", "invitation-not-pending"]),
386
445
  readInvitationDomainRule: doc("Reads the domains the caller's organisation invites from, for an owner.", [...SIGNED_IN, "capability-missing"]),
387
446
  setInvitationDomainRule: doc("Replaces the domains the caller's organisation invites from, for an owner.", [...SIGNED_IN, "capability-missing", "invalid-domain"]),
@@ -392,8 +451,8 @@ var ROUTE_DOCS = Object.freeze({
392
451
  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"]),
393
452
  readWebOrigin: doc("Reads the origin of the deployment's web application, or null when the host is given none.", SIGNED_IN),
394
453
  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]),
395
- 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"]),
396
- 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.", [
454
+ queryGraph: doc(`Walks the edges from a start of addresses or an object set, and answers the objects reached with every hop among them. Example: one start address and one hop step of depth 1 reads that object's connections, with a marker for each kind of connection whose far object the caller cannot read. A start takes at most 200 addresses or set members; a walk takes at most 3 steps and 3 total levels. An explicit edgeTypeKeys list holds at most 8 edge types per step; when edgeTypeKeys is absent, the step traverses every edge type. objectLimit is at most 200 and hopLimit at most 400. A continuation reads the next page in the one-object form. For an object-set start, omitting input.start.set.projects reads every project the caller can read on the selected branch or baseline; selector.projectId does not narrow the 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"]),
455
+ 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. Example: a forest anchor with maxDepth 1 reads its roots and their children. maxDepth is at most 32 and occurrenceLimit at most 2000. The answer reports whether it is complete or bounded, and a bounded answer says whether the limit was occurrences, depth or level rows; the route does not page. Narrow the walk with maxDepth and occurrenceLimit. A chosen relationship or one-step view places the type itself, and the types above it follow their own declared relationships.", [
397
456
  ...REF_READ,
398
457
  "malformed-query",
399
458
  "view-not-drawable",
@@ -404,31 +463,31 @@ var ROUTE_DOCS = Object.freeze({
404
463
  listProposals: doc("Lists the proposals of a project.", SCOPED),
405
464
  readProposal: doc("Reads one proposal.", SCOPED),
406
465
  refuseProposal: doc("Refuses a proposal and returns its branch to its author.", [...SCOPED, "proposal-not-pending"]),
407
- readBranchDiff: doc("Reads what a proposal's branch changes against its target.", REF_READ),
408
- diffBranches: doc("Reads what one ref changes against another.", REF_READ),
466
+ readBranchDiff: doc("Reads the objects and edges a proposal's branch changes against its target.", REF_READ),
467
+ diffBranches: doc("Reads the objects and edges one branch or baseline changes against another.", REF_READ),
409
468
  readBranchHistory: doc("Reads a branch's history of commits.", [...SCOPED, "invalid-continuation", "stale-continuation", "malformed-history-request"]),
410
469
  listAudit: doc("Lists the audit records of a project.", [...SCOPED, "invalid-continuation"]),
411
- readRefHead: doc("Reads the head of a ref.", REF_READ),
470
+ readRefHead: doc("Reads the head of a branch or baseline.", REF_READ),
412
471
  inspectBranchOperation: doc("Reads the state of a branch operation the caller started.", SCOPED),
413
472
  abandonBranch: doc("Refuses branch abandonment because this operation is not available in this release.", [
414
473
  ...WRITE,
415
474
  "not-in-this-release"
416
475
  ]),
417
- 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),
418
- listRefRules: doc("Lists only the selected project's visible ref protection rules, including each rule's identifier, pattern and consequence.", SCOPED),
476
+ addRefRule: doc("Adds a branch 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),
477
+ listRefRules: doc("Lists only the selected project's visible branch protection rules, including each rule's identifier, pattern and consequence.", SCOPED),
419
478
  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),
420
- 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),
421
- listOrganisationRules: doc("Lists the attached organisation's visible ref rules, including identifier, pattern and consequence.", SCOPED),
479
+ addOrganisationRule: doc("Adds a branch 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),
480
+ listOrganisationRules: doc("Lists the attached organisation's visible branch rules, including identifier, pattern and consequence.", SCOPED),
422
481
  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),
423
- 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"]),
424
- listOrganisationRefs: doc("Lists visible refs in the attached organisation, including each name, readOnly and creation attribution.", SCOPED),
425
- 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"]),
426
- 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),
427
- 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"]),
482
+ createOrganisationRef: doc("Creates a branch or baseline 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 name segment.", [...WRITE, "ref-exists", "read-only-ref", "organisation-not-ready"]),
483
+ listOrganisationRefs: doc("Lists visible branches and baselines in the attached organisation, including each name, readOnly and creation attribution.", SCOPED),
484
+ deleteOrganisationRef: doc("Deletes a writable branch from the attached organisation and answers its name. A baseline cannot be deleted.", [...REF_WRITE, "read-only-ref"]),
485
+ markOrganisationRefReadOnly: doc("Marks an organisation branch read-only as a baseline and answers its full record. An absent or unreadable name answers not-found.", SCOPED),
486
+ setObjectLock: doc("Sets an object's lock on the selected project branch 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 writable branch are not thereby frozen. Use a baseline for a fixed snapshot. An unknown lock answers invalid-request at lock.", [...REF_WRITE, "read-only-ref", "concurrent-change", "lock-unavailable"]),
428
487
  readAgentCeiling: doc("Reads the selected project's maximum agent role as { ceiling }: contributor or maintainer. An absent or unreadable project answers not-found.", SCOPED),
429
488
  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),
430
- 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),
431
- 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),
489
+ requestSchemaUpdate: doc("Records a schema update request for a project branch or organisation branch or baseline 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 branch or baseline answers not-found.", SCOPED),
490
+ readSchemaUpdateRequest: doc("Reads the caller's latest schema update request for the branch or baseline 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),
432
491
  openAgentSession: doc("Opens an agent session on a project.", [...SCOPED, "invalid-configuration"]),
433
492
  listAgentSessions: doc("Lists the caller's agent sessions on a project.", SCOPED),
434
493
  readAgentSession: doc("Reads one agent session and its runs.", SCOPED),
@@ -454,6 +513,7 @@ var ROUTE_DOCS = Object.freeze({
454
513
  "invalid-catalogue",
455
514
  "version-conflict",
456
515
  "key-under-another-kind",
516
+ "owned-type-not-presentation",
457
517
  "namespace-not-active"
458
518
  ]),
459
519
  readApp: doc("Reads a published version of an app, the latest where none is named, with the app's history of versions.", [...SIGNED_IN, "not-found"]),
@@ -476,6 +536,23 @@ function deepFreeze(value) {
476
536
  }
477
537
  return value;
478
538
  }
539
+ var BINARY_REQUESTS = {
540
+ stageAttachment: {
541
+ "contentType": "application/octet-stream",
542
+ "selectorHeader": "x-oe2-selector",
543
+ "selectorEncoding": "json",
544
+ "nameHeader": "x-oe2-attachment-name",
545
+ "nameEncoding": "rfc8187"
546
+ }
547
+ };
548
+ var BINARY_REQUEST_INPUTS = deepFreeze(BINARY_REQUESTS);
549
+ var BINARY_RESPONSES = {
550
+ readAttachment: {
551
+ "contentType": "attachment",
552
+ "headers": "attachmentResponseHeaders"
553
+ }
554
+ };
555
+ var BINARY_RESPONSE_OUTPUTS = deepFreeze(BINARY_RESPONSES);
479
556
  var SCHEMAS = {
480
557
  createObjectSet: { "type": "object", "properties": { "name": { "type": "string" }, "members": { "type": "array", "items": { "type": "object", "properties": { "objectId": { "type": "string" }, "projectId": { "type": "string" } }, "required": ["objectId", "projectId"], "additionalProperties": false } } }, "required": ["name", "members"], "additionalProperties": false },
481
558
  listObjectSets: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
@@ -500,9 +577,26 @@ var SCHEMAS = {
500
577
  decideConsent: { "oneOf": [{ "type": "object", "properties": { "interactionId": { "type": "string" }, "decision": { "const": "approve" }, "approvedScopes": { "type": "array", "items": { "enum": ["objects.read", "objects.write", "branches.read", "branches.write", "branches.manage", "offline_access"] } } }, "required": ["interactionId", "decision", "approvedScopes"], "additionalProperties": false }, { "type": "object", "properties": { "interactionId": { "type": "string" }, "decision": { "const": "deny" } }, "required": ["interactionId", "decision"], "additionalProperties": false }] },
501
578
  listConnectedApps: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
502
579
  revokeConnectedApp: { "type": "object", "properties": { "clientId": { "type": "string" } }, "required": ["clientId"], "additionalProperties": false },
580
+ readAttachment: {
581
+ "type": "object",
582
+ "properties": {
583
+ "objectId": {
584
+ "type": "string"
585
+ },
586
+ "property": {
587
+ "type": "string"
588
+ }
589
+ },
590
+ "required": [
591
+ "objectId",
592
+ "property"
593
+ ],
594
+ "additionalProperties": false
595
+ },
503
596
  readObject: { "type": "object", "properties": { "objectId": { "type": "string" } }, "required": ["objectId"], "additionalProperties": false },
504
- queryObjects: { "type": "object", "properties": { "kind": { "const": "objects" }, "typeKey": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "projects": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "steps": { "type": "array", "items": { "type": "object", "properties": { "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "targetTypeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } } }, "required": ["edgeTypeKey", "direction", "targetTypeKey"], "additionalProperties": false } }, "sort": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "property", "direction"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "direction"], "additionalProperties": false }] }, "limit": { "type": "number" }, "continuation": { "oneOf": [{ "type": "string" }, { "type": "null" }] } }, "required": ["kind", "typeKey", "limit", "continuation"], "additionalProperties": false },
505
- aggregateObjects: { "type": "object", "properties": { "kind": { "const": "aggregate" }, "typeKey": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "projects": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "steps": { "type": "array", "items": { "type": "object", "properties": { "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "targetTypeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } } }, "required": ["edgeTypeKey", "direction", "targetTypeKey"], "additionalProperties": false } }, "operation": { "enum": ["count", "min", "max", "sum"] }, "property": { "type": "string" }, "groupBy": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "type" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" } }, "required": ["kind", "property"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "parent" }, "edgeTypeKeys": { "type": "array", "items": { "type": "string" } }, "multiplicity": { "enum": ["per-path", "distinct"] }, "ends": { "enum": ["visible", "all"] }, "parents": { "type": "array", "items": { "type": "object", "properties": { "objectId": { "type": "string" }, "projectId": { "type": "string" } }, "required": ["objectId", "projectId"], "additionalProperties": false } } }, "required": ["kind", "edgeTypeKeys", "multiplicity", "ends"], "additionalProperties": false }] } }, "required": ["kind", "typeKey", "operation"], "additionalProperties": false },
597
+ queryObjects: { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "objects" }, "typeKey": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "projects": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "steps": { "type": "array", "items": { "type": "object", "properties": { "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "targetTypeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } } }, "required": ["edgeTypeKey", "direction", "targetTypeKey"], "additionalProperties": false } }, "sort": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "property", "direction"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "direction"], "additionalProperties": false }] }, "limit": { "type": "number" }, "continuation": { "oneOf": [{ "type": "string" }, { "type": "null" }] } }, "required": ["kind", "typeKey", "limit", "continuation"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "set" }, "op": { "enum": ["union", "intersection", "difference"] }, "left": { "type": "object", "properties": { "kind": { "const": "objects" }, "typeKey": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "projects": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "steps": { "type": "array", "items": { "type": "object", "properties": { "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "targetTypeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } } }, "required": ["edgeTypeKey", "direction", "targetTypeKey"], "additionalProperties": false } }, "sort": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "property", "direction"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "direction"], "additionalProperties": false }] } }, "required": ["kind", "typeKey"], "additionalProperties": false }, "right": { "type": "object", "properties": { "kind": { "const": "objects" }, "typeKey": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "projects": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "steps": { "type": "array", "items": { "type": "object", "properties": { "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "targetTypeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } } }, "required": ["edgeTypeKey", "direction", "targetTypeKey"], "additionalProperties": false } }, "sort": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "property", "direction"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "direction"], "additionalProperties": false }] } }, "required": ["kind", "typeKey"], "additionalProperties": false }, "limit": { "type": "number" }, "continuation": { "oneOf": [{ "type": "string" }, { "type": "null" }] } }, "required": ["kind", "op", "left", "right", "limit", "continuation"], "additionalProperties": false }] },
598
+ queryRows: { "type": "object", "properties": { "kind": { "const": "graph-query" }, "start": { "type": "object", "properties": { "typeKey": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "projects": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } } }, "required": ["typeKey"], "additionalProperties": false }, "path": { "type": "array", "items": { "type": "object", "properties": { "alias": { "type": "string" }, "edgeTypeKeys": { "oneOf": [{ "const": "any" }, { "type": "array", "items": { "type": "string" } }] }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "targetTypeKeys": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "repeat": { "type": "object", "properties": { "depth": { "type": "number" } }, "required": ["depth"], "additionalProperties": false } }, "required": ["alias", "edgeTypeKeys", "direction"], "additionalProperties": false } }, "answer": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "rows" }, "columns": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "enum": ["identity", "typeKey"] }, "alias": { "type": "string" } }, "required": ["kind", "alias"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "alias": { "type": "string" }, "property": { "type": "string" } }, "required": ["kind", "alias", "property"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "alias": { "type": "string" }, "field": { "enum": ["identity", "typeKey"] } }, "required": ["kind", "alias", "field"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge-property" }, "alias": { "type": "string" }, "property": { "type": "string" } }, "required": ["kind", "alias", "property"], "additionalProperties": false }] } }, "order": { "type": "object", "properties": { "alias": { "type": "string" }, "property": { "type": "string" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["alias", "property", "direction"], "additionalProperties": false }, "limit": { "type": "number" }, "continuation": { "oneOf": [{ "type": "string" }, { "type": "null" }] } }, "required": ["kind", "columns", "limit", "continuation"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "groups" }, "keys": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "enum": ["identity", "typeKey"] }, "alias": { "type": "string" } }, "required": ["kind", "alias"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "alias": { "type": "string" }, "property": { "type": "string" } }, "required": ["kind", "alias", "property"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "parent" }, "alias": { "type": "string" }, "edgeTypeKeys": { "type": "array", "items": { "type": "string" } }, "parents": { "type": "array", "items": { "type": "object", "properties": { "objectId": { "type": "string" }, "projectId": { "type": "string" } }, "required": ["objectId", "projectId"], "additionalProperties": false } } }, "required": ["kind", "alias", "edgeTypeKeys"], "additionalProperties": false }] } }, "measures": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "count" }, "over": { "type": "array", "items": { "type": "string" } }, "ends": { "enum": ["visible", "all"] } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "countDistinct" }, "alias": { "type": "string" }, "over": { "type": "array", "items": { "type": "string" } }, "ends": { "enum": ["visible", "all"] } }, "required": ["kind", "alias"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "sum" }, "alias": { "type": "string" }, "property": { "type": "string" }, "over": { "type": "array", "items": { "type": "string" } }, "multiplicity": { "enum": ["per-path", "distinct"] }, "ends": { "enum": ["visible", "all"] } }, "required": ["kind", "alias", "property"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "enum": ["min", "max"] }, "alias": { "type": "string" }, "property": { "type": "string" }, "over": { "type": "array", "items": { "type": "string" } }, "ends": { "enum": ["visible", "all"] } }, "required": ["kind", "alias", "property"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "weightedSum" }, "alias": { "type": "string" }, "property": { "type": "string" }, "weight": { "type": "string" }, "over": { "type": "array", "items": { "type": "string" } }, "multiplicity": { "enum": ["per-path", "distinct"] }, "ends": { "enum": ["visible", "all"] } }, "required": ["kind", "alias", "weight", "over", "multiplicity", "ends"], "additionalProperties": false }] } }, "having": { "type": "array", "items": { "type": "object", "properties": { "measure": { "type": "number" }, "op": { "enum": ["=", ">", ">=", "<", "<="] }, "value": { "type": "number" } }, "required": ["measure", "op", "value"], "additionalProperties": false } }, "order": { "type": "object", "properties": { "by": { "enum": ["key", "measure"] }, "index": { "type": "number" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["by", "index", "direction"], "additionalProperties": false }, "limit": { "type": "number" } }, "required": ["kind", "keys", "measures"], "additionalProperties": false }] } }, "required": ["kind", "start", "answer"], "additionalProperties": false },
599
+ aggregateObjects: { "type": "object", "properties": { "kind": { "const": "aggregate" }, "typeKey": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "projects": { "type": "array", "items": { "type": "string" } }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "steps": { "type": "array", "items": { "type": "object", "properties": { "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "targetTypeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "or" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "=" }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": [">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "string" }, { "type": "number" }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "edge" }, "edgeTypeKey": { "type": "string" }, "direction": { "enum": ["outgoing", "incoming", "to-children", "to-parent"] }, "has": { "type": "boolean" } }, "required": ["kind", "edgeTypeKey", "direction", "has"], "additionalProperties": false }] } } }, "required": ["kind", "filters"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "type": "string" }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } } }, "required": ["edgeTypeKey", "direction", "targetTypeKey"], "additionalProperties": false } }, "operation": { "enum": ["count", "min", "max", "sum", "average"] }, "property": { "type": "string" }, "groupBy": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "type" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" } }, "required": ["kind", "property"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "parent" }, "edgeTypeKeys": { "type": "array", "items": { "type": "string" } }, "multiplicity": { "enum": ["per-path", "distinct"] }, "ends": { "enum": ["visible", "all"] }, "parents": { "type": "array", "items": { "type": "object", "properties": { "objectId": { "type": "string" }, "projectId": { "type": "string" } }, "required": ["objectId", "projectId"], "additionalProperties": false } } }, "required": ["kind", "edgeTypeKeys", "multiplicity", "ends"], "additionalProperties": false }] } }, "required": ["kind", "typeKey", "operation"], "additionalProperties": false },
506
600
  discoverVerbs: { "type": "object", "properties": { "objectId": { "type": "string" } }, "required": ["objectId"], "additionalProperties": false },
507
601
  readHistory: { "type": "object", "properties": { "objectId": { "type": "string" }, "limit": { "type": "number" }, "continuation": { "oneOf": [{ "type": "string" }, { "type": "null" }] } }, "required": ["objectId", "limit", "continuation"], "additionalProperties": false },
508
602
  mutate: { "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 }] }, "operation": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "create-object" }, "typeKey": { "type": "string" }, "typeVersion": { "type": "number" }, "properties": { "type": "object", "additionalProperties": {} } }, "required": ["kind", "typeKey", "typeVersion", "properties"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "update-object" }, "objectId": { "type": "string" }, "typeVersion": { "type": "number" }, "changes": { "type": "object", "additionalProperties": { "type": "object", "properties": { "from": { "oneOf": [{ "type": "object", "properties": { "absent": { "const": true } }, "required": ["absent"], "additionalProperties": false }, { "type": "object", "properties": { "value": {} }, "required": ["value"], "additionalProperties": false }] }, "to": { "oneOf": [{ "type": "object", "properties": { "absent": { "const": true } }, "required": ["absent"], "additionalProperties": false }, { "type": "object", "properties": { "value": {} }, "required": ["value"], "additionalProperties": false }] } }, "required": ["from", "to"], "additionalProperties": false } } }, "required": ["kind", "objectId", "typeVersion", "changes"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "delete-object" }, "objectId": { "type": "string" } }, "required": ["kind", "objectId"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "create-edge" }, "typeKey": { "type": "string" }, "typeVersion": { "type": "number" }, "sourceObjectId": { "type": "string" }, "targetObjectId": { "type": "string" }, "properties": { "type": "object", "additionalProperties": {} } }, "required": ["kind", "typeKey", "typeVersion", "sourceObjectId", "targetObjectId", "properties"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "update-edge" }, "edgeId": { "type": "string" }, "typeVersion": { "type": "number" }, "changes": { "type": "object", "additionalProperties": { "type": "object", "properties": { "from": { "oneOf": [{ "type": "object", "properties": { "absent": { "const": true } }, "required": ["absent"], "additionalProperties": false }, { "type": "object", "properties": { "value": {} }, "required": ["value"], "additionalProperties": false }] }, "to": { "oneOf": [{ "type": "object", "properties": { "absent": { "const": true } }, "required": ["absent"], "additionalProperties": false }, { "type": "object", "properties": { "value": {} }, "required": ["value"], "additionalProperties": false }] } }, "required": ["from", "to"], "additionalProperties": false } } }, "required": ["kind", "edgeId", "typeVersion", "changes"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "delete-edge" }, "edgeId": { "type": "string" } }, "required": ["kind", "edgeId"], "additionalProperties": false }] } }, "required": ["correlation", "operation"], "additionalProperties": false },
@@ -526,14 +620,17 @@ var SCHEMAS = {
526
620
  grantMembership: { "type": "object", "properties": { "principalId": { "type": "string" }, "scopeKind": { "enum": ["organisation", "project"] }, "scopeId": { "type": "string" }, "roleKey": { "type": "string" } }, "required": ["principalId", "scopeKind", "scopeId", "roleKey"], "additionalProperties": false },
527
621
  revokeMembership: { "type": "object", "properties": { "principalId": { "type": "string" }, "scopeKind": { "enum": ["organisation", "project"] }, "scopeId": { "type": "string" } }, "required": ["principalId", "scopeKind", "scopeId"], "additionalProperties": false },
528
622
  setModelConfiguration: { "type": "object", "properties": { "model": { "type": "string" }, "apiKey": { "type": "string" } }, "required": ["model", "apiKey"], "additionalProperties": false },
623
+ setModelId: { "type": "object", "properties": { "model": { "type": "string" } }, "required": ["model"], "additionalProperties": false },
529
624
  readDisplayNames: { "type": "object", "properties": { "principalIds": { "type": "array", "items": { "type": "string" } } }, "required": ["principalIds"], "additionalProperties": false },
530
625
  listMembers: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
531
626
  changeMembershipRole: { "type": "object", "properties": { "principalId": { "type": "string" }, "scopeKind": { "enum": ["organisation", "project"] }, "scopeId": { "type": "string" }, "roleKey": { "type": "string" } }, "required": ["principalId", "scopeKind", "scopeId", "roleKey"], "additionalProperties": false },
532
627
  listOrganisationMembers: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
533
628
  listServiceIdentities: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
534
- createInvitation: { "type": "object", "properties": { "email": { "type": "string" }, "roleKey": { "type": "string" } }, "required": ["email", "roleKey"], "additionalProperties": false },
629
+ createInvitation: { "type": "object", "properties": { "email": { "type": "string" }, "roleKey": { "type": "string" }, "projectRoles": { "type": "array", "items": { "type": "object", "properties": { "projectId": { "type": "string" }, "roleKey": { "type": "string" } }, "required": ["projectId", "roleKey"], "additionalProperties": false }, "maxItems": 50 } }, "required": ["email", "roleKey"], "additionalProperties": false },
535
630
  listInvitations: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
536
631
  revokeInvitation: { "type": "object", "properties": { "invitationId": { "type": "string" } }, "required": ["invitationId"], "additionalProperties": false },
632
+ readModelConfigurationStatus: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
633
+ readAccount: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
537
634
  readInvitationDomainRule: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
538
635
  setInvitationDomainRule: { "type": "object", "properties": { "restricted": { "type": "boolean" }, "domains": { "type": "array", "items": { "type": "string" } } }, "required": ["restricted", "domains"], "additionalProperties": false },
539
636
  reissueInvitation: { "type": "object", "properties": { "invitationId": { "type": "string" } }, "required": ["invitationId"], "additionalProperties": false },
@@ -586,7 +683,7 @@ var SCHEMAS = {
586
683
  readCurrentChangeSet: { "type": "object", "properties": {}, "required": [], "additionalProperties": false },
587
684
  readChangeSet: { "type": "object", "properties": { "changeSetId": { "type": "string" } }, "required": ["changeSetId"], "additionalProperties": false },
588
685
  readChangeSetState: { "type": "object", "properties": { "changeSetId": { "type": "string" } }, "required": ["changeSetId"], "additionalProperties": false },
589
- reviseChangeSet: { "type": "object", "properties": { "changeSetId": { "type": "string" }, "expectedRevision": { "type": "string" }, "changes": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "object", "properties": { "typeCategory": { "const": "object" }, "typeKey": { "type": "string" }, "version": { "type": "number" }, "displayName": { "type": "string" }, "description": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "schemaLanguageVersion": { "type": "string" }, "propertyDefinitions": { "type": "object", "additionalProperties": {} }, "requiredPropertyKeys": { "type": "array", "items": { "type": "string" } }, "presentationBindings": { "type": "object", "properties": { "views": { "type": "object", "properties": { "object": { "type": "object", "properties": { "root": { "type": "string" }, "elements": { "type": "object", "additionalProperties": { "type": "object", "properties": { "type": { "type": "string" }, "props": { "type": "object", "additionalProperties": {} }, "children": { "type": "array", "items": { "type": "string" } }, "repeat": { "type": "object", "properties": { "statePath": { "type": "string" }, "key": { "type": "string" } }, "required": ["statePath"], "additionalProperties": false }, "on": { "type": "object", "properties": { "press": { "oneOf": [{ "type": "object", "properties": { "action": { "const": "set-properties" }, "params": { "type": "object", "properties": { "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "object", "properties": { "$state": { "type": "string" } }, "required": ["$state"], "additionalProperties": false }] } } }, "required": ["properties"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }, { "type": "object", "properties": { "action": { "const": "run-verb" }, "params": { "type": "object", "properties": { "verb": { "type": "string" } }, "required": ["verb"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }] } }, "required": ["press"], "additionalProperties": false } }, "required": ["type", "props", "children"], "additionalProperties": false } } }, "required": ["root", "elements"], "additionalProperties": false }, "app": { "type": "object", "properties": { "root": { "type": "string" }, "elements": { "type": "object", "additionalProperties": { "type": "object", "properties": { "type": { "type": "string" }, "props": { "type": "object", "additionalProperties": {} }, "children": { "type": "array", "items": { "type": "string" } }, "repeat": { "type": "object", "properties": { "statePath": { "type": "string" }, "key": { "type": "string" } }, "required": ["statePath"], "additionalProperties": false }, "on": { "type": "object", "properties": { "press": { "oneOf": [{ "type": "object", "properties": { "action": { "const": "set-properties" }, "params": { "type": "object", "properties": { "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "object", "properties": { "$state": { "type": "string" } }, "required": ["$state"], "additionalProperties": false }] } } }, "required": ["properties"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }, { "type": "object", "properties": { "action": { "const": "run-verb" }, "params": { "type": "object", "properties": { "verb": { "type": "string" } }, "required": ["verb"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }] } }, "required": ["press"], "additionalProperties": false } }, "required": ["type", "props", "children"], "additionalProperties": false } } }, "required": ["root", "elements"], "additionalProperties": false }, "card": { "type": "object", "properties": { "root": { "type": "string" }, "elements": { "type": "object", "additionalProperties": { "type": "object", "properties": { "type": { "type": "string" }, "props": { "type": "object", "additionalProperties": {} }, "children": { "type": "array", "items": { "type": "string" } }, "repeat": { "type": "object", "properties": { "statePath": { "type": "string" }, "key": { "type": "string" } }, "required": ["statePath"], "additionalProperties": false }, "on": { "type": "object", "properties": { "press": { "oneOf": [{ "type": "object", "properties": { "action": { "const": "set-properties" }, "params": { "type": "object", "properties": { "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "object", "properties": { "$state": { "type": "string" } }, "required": ["$state"], "additionalProperties": false }] } } }, "required": ["properties"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }, { "type": "object", "properties": { "action": { "const": "run-verb" }, "params": { "type": "object", "properties": { "verb": { "type": "string" } }, "required": ["verb"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }] } }, "required": ["press"], "additionalProperties": false } }, "required": ["type", "props", "children"], "additionalProperties": false } } }, "required": ["root", "elements"], "additionalProperties": false } }, "required": [], "additionalProperties": false }, "title": { "type": "string" }, "summary": { "type": "string" }, "icon": { "type": "string" }, "typeIcon": { "type": "string" }, "rail": { "type": "object", "properties": { "group": { "type": "string" }, "order": { "type": "number" } }, "required": ["group", "order"], "additionalProperties": false } }, "required": [], "additionalProperties": false }, "structureDeclaration": { "type": "object", "properties": { "relationships": { "type": "array", "items": { "type": "string" } }, "views": { "type": "array", "items": { "type": "object", "properties": { "key": { "type": "string" }, "label": { "type": "string" }, "steps": { "type": "array", "items": { "type": "string" } }, "decoration": { "type": "array", "items": { "type": "object", "properties": { "key": { "type": "string" }, "label": { "type": "string" } }, "required": ["key", "label"], "additionalProperties": false } } }, "required": ["key", "label", "steps"], "additionalProperties": false } } }, "required": [], "additionalProperties": false }, "subscriptionRoles": { "type": "object", "properties": { "owner": { "type": "object", "properties": { "max": { "type": "number" } }, "required": [], "additionalProperties": false }, "approver": { "type": "object", "properties": { "max": { "type": "number" } }, "required": [], "additionalProperties": false }, "watcher": { "type": "object", "properties": { "max": { "type": "number" } }, "required": [], "additionalProperties": false } }, "required": [], "additionalProperties": false } }, "required": ["typeCategory", "typeKey", "version", "displayName", "description", "schemaLanguageVersion", "propertyDefinitions", "requiredPropertyKeys"], "additionalProperties": false }, { "type": "object", "properties": { "typeCategory": { "const": "edge" }, "typeKey": { "type": "string" }, "version": { "type": "number" }, "displayName": { "type": "string" }, "sourceObjectType": { "type": "string" }, "targetObjectType": { "type": "string" }, "kind": { "enum": ["structural", "traceability"] }, "subjectEnd": { "enum": ["source", "target"] }, "parentEnd": { "oneOf": [{ "const": "source" }, { "const": "target" }, { "type": "null" }] }, "sourceLabel": { "type": "string" }, "targetLabel": { "type": "string" }, "schemaLanguageVersion": { "type": "string" }, "propertyDefinitions": { "type": "object", "additionalProperties": {} }, "requiredPropertyKeys": { "type": "array", "items": { "type": "string" } }, "readRule": { "enum": ["both-endpoints", "either-endpoint"] }, "writeRule": { "enum": ["both-endpoints", "either-endpoint"] } }, "required": ["typeCategory", "typeKey", "version", "displayName", "sourceObjectType", "targetObjectType", "kind", "subjectEnd", "parentEnd", "sourceLabel", "targetLabel", "schemaLanguageVersion", "propertyDefinitions", "requiredPropertyKeys", "readRule", "writeRule"], "additionalProperties": false }, { "type": "object", "properties": { "typeCategory": { "const": "verb" }, "typeKey": { "type": "string" }, "version": { "type": "number" }, "displayName": { "type": "string" }, "description": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "allowedSubjectTypes": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "none" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "types" }, "types": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "types"], "additionalProperties": false }] }, "inputSchema": {}, "resultSchema": {}, "handlerKey": { "type": "string" }, "template": { "type": "object", "properties": { "query": { "type": "object", "properties": { "typeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": ["=", ">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }] }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "sort": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "property", "direction"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "direction"], "additionalProperties": false }] }, "limit": { "type": "number" } }, "required": ["typeKey", "limit"], "additionalProperties": false }, "operations": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "create-object" }, "typeKey": { "type": "string" }, "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } } }, "required": ["kind", "typeKey", "properties"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "update-object" }, "typeKey": { "type": "string" }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] }, "changes": { "type": "object", "additionalProperties": { "type": "object", "properties": { "from": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "absent" } }, "required": ["slot"], "additionalProperties": false }] }, "to": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "absent" } }, "required": ["slot"], "additionalProperties": false }] } }, "required": ["from", "to"], "additionalProperties": false } } }, "required": ["kind", "typeKey", "target", "changes"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "delete-object" }, "typeKey": { "type": "string" }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } }, "required": ["kind", "typeKey", "target"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "create-edge" }, "typeKey": { "type": "string" }, "source": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] }, "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } } }, "required": ["kind", "typeKey", "source", "target", "properties"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "delete-edge" }, "typeKey": { "type": "string" }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } }, "required": ["kind", "typeKey", "target"], "additionalProperties": false }] } } }, "required": ["operations"], "additionalProperties": false }, "schemaLanguageVersion": { "type": "string" } }, "required": ["typeCategory", "typeKey", "version", "displayName", "description", "allowedSubjectTypes", "inputSchema", "resultSchema", "schemaLanguageVersion"], "additionalProperties": false }] } }, "railGroups": { "type": "array", "items": { "type": "string" } } }, "required": ["changeSetId", "expectedRevision", "changes"], "additionalProperties": false },
686
+ reviseChangeSet: { "type": "object", "properties": { "changeSetId": { "type": "string" }, "expectedRevision": { "type": "string" }, "changes": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "object", "properties": { "typeCategory": { "const": "object" }, "typeKey": { "type": "string" }, "version": { "type": "number" }, "displayName": { "type": "string" }, "description": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "schemaLanguageVersion": { "type": "string" }, "propertyDefinitions": { "type": "object", "additionalProperties": {} }, "requiredPropertyKeys": { "type": "array", "items": { "type": "string" } }, "presentationBindings": { "type": "object", "properties": { "views": { "type": "object", "properties": { "object": { "type": "object", "properties": { "root": { "type": "string" }, "elements": { "type": "object", "additionalProperties": { "type": "object", "properties": { "type": { "type": "string" }, "props": { "type": "object", "additionalProperties": {} }, "children": { "type": "array", "items": { "type": "string" } }, "repeat": { "type": "object", "properties": { "statePath": { "type": "string" }, "key": { "type": "string" } }, "required": ["statePath"], "additionalProperties": false }, "on": { "type": "object", "properties": { "press": { "oneOf": [{ "type": "object", "properties": { "action": { "const": "set-properties" }, "params": { "type": "object", "properties": { "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "object", "properties": { "$state": { "type": "string" } }, "required": ["$state"], "additionalProperties": false }] } } }, "required": ["properties"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }, { "type": "object", "properties": { "action": { "const": "run-verb" }, "params": { "type": "object", "properties": { "verb": { "type": "string" } }, "required": ["verb"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }] } }, "required": ["press"], "additionalProperties": false } }, "required": ["type", "props", "children"], "additionalProperties": false } } }, "required": ["root", "elements"], "additionalProperties": false }, "app": { "type": "object", "properties": { "root": { "type": "string" }, "elements": { "type": "object", "additionalProperties": { "type": "object", "properties": { "type": { "type": "string" }, "props": { "type": "object", "additionalProperties": {} }, "children": { "type": "array", "items": { "type": "string" } }, "repeat": { "type": "object", "properties": { "statePath": { "type": "string" }, "key": { "type": "string" } }, "required": ["statePath"], "additionalProperties": false }, "on": { "type": "object", "properties": { "press": { "oneOf": [{ "type": "object", "properties": { "action": { "const": "set-properties" }, "params": { "type": "object", "properties": { "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "object", "properties": { "$state": { "type": "string" } }, "required": ["$state"], "additionalProperties": false }] } } }, "required": ["properties"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }, { "type": "object", "properties": { "action": { "const": "run-verb" }, "params": { "type": "object", "properties": { "verb": { "type": "string" } }, "required": ["verb"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }] } }, "required": ["press"], "additionalProperties": false } }, "required": ["type", "props", "children"], "additionalProperties": false } } }, "required": ["root", "elements"], "additionalProperties": false }, "card": { "type": "object", "properties": { "root": { "type": "string" }, "elements": { "type": "object", "additionalProperties": { "type": "object", "properties": { "type": { "type": "string" }, "props": { "type": "object", "additionalProperties": {} }, "children": { "type": "array", "items": { "type": "string" } }, "repeat": { "type": "object", "properties": { "statePath": { "type": "string" }, "key": { "type": "string" } }, "required": ["statePath"], "additionalProperties": false }, "on": { "type": "object", "properties": { "press": { "oneOf": [{ "type": "object", "properties": { "action": { "const": "set-properties" }, "params": { "type": "object", "properties": { "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" }, { "type": "null" }, { "type": "object", "properties": { "$state": { "type": "string" } }, "required": ["$state"], "additionalProperties": false }] } } }, "required": ["properties"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }, { "type": "object", "properties": { "action": { "const": "run-verb" }, "params": { "type": "object", "properties": { "verb": { "type": "string" } }, "required": ["verb"], "additionalProperties": false } }, "required": ["action", "params"], "additionalProperties": false }] } }, "required": ["press"], "additionalProperties": false } }, "required": ["type", "props", "children"], "additionalProperties": false } } }, "required": ["root", "elements"], "additionalProperties": false } }, "required": [], "additionalProperties": false }, "title": { "type": "string" }, "summary": { "type": "string" }, "icon": { "type": "string" }, "typeIcon": { "type": "string" }, "propertyLabels": { "type": "object", "additionalProperties": { "type": "string" } }, "propertyOrder": { "type": "array", "items": { "type": "string" } }, "rail": { "type": "object", "properties": { "group": { "type": "string" }, "order": { "type": "number" } }, "required": ["group", "order"], "additionalProperties": false } }, "required": [], "additionalProperties": false }, "structureDeclaration": { "type": "object", "properties": { "relationships": { "type": "array", "items": { "type": "string" } }, "views": { "type": "array", "items": { "type": "object", "properties": { "key": { "type": "string" }, "label": { "type": "string" }, "steps": { "type": "array", "items": { "type": "string" } }, "decoration": { "type": "array", "items": { "type": "object", "properties": { "key": { "type": "string" }, "label": { "type": "string" } }, "required": ["key", "label"], "additionalProperties": false } } }, "required": ["key", "label", "steps"], "additionalProperties": false } } }, "required": [], "additionalProperties": false }, "subscriptionRoles": { "type": "object", "properties": { "owner": { "type": "object", "properties": { "max": { "type": "number" } }, "required": [], "additionalProperties": false }, "approver": { "type": "object", "properties": { "max": { "type": "number" } }, "required": [], "additionalProperties": false }, "watcher": { "type": "object", "properties": { "max": { "type": "number" } }, "required": [], "additionalProperties": false } }, "required": [], "additionalProperties": false } }, "required": ["typeCategory", "typeKey", "version", "displayName", "description", "schemaLanguageVersion", "propertyDefinitions", "requiredPropertyKeys"], "additionalProperties": false }, { "type": "object", "properties": { "typeCategory": { "const": "edge" }, "typeKey": { "type": "string" }, "version": { "type": "number" }, "displayName": { "type": "string" }, "sourceObjectType": { "type": "string" }, "targetObjectType": { "type": "string" }, "kind": { "enum": ["structural", "traceability"] }, "subjectEnd": { "enum": ["source", "target"] }, "parentEnd": { "oneOf": [{ "const": "source" }, { "const": "target" }, { "type": "null" }] }, "sourceLabel": { "type": "string" }, "targetLabel": { "type": "string" }, "schemaLanguageVersion": { "type": "string" }, "propertyDefinitions": { "type": "object", "additionalProperties": {} }, "requiredPropertyKeys": { "type": "array", "items": { "type": "string" } }, "readRule": { "enum": ["both-endpoints", "either-endpoint"] }, "writeRule": { "enum": ["both-endpoints", "either-endpoint"] } }, "required": ["typeCategory", "typeKey", "version", "displayName", "sourceObjectType", "targetObjectType", "kind", "subjectEnd", "parentEnd", "sourceLabel", "targetLabel", "schemaLanguageVersion", "propertyDefinitions", "requiredPropertyKeys", "readRule", "writeRule"], "additionalProperties": false }, { "type": "object", "properties": { "typeCategory": { "const": "verb" }, "typeKey": { "type": "string" }, "version": { "type": "number" }, "displayName": { "type": "string" }, "description": { "oneOf": [{ "type": "string" }, { "type": "null" }] }, "allowedSubjectTypes": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "none" } }, "required": ["kind"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "types" }, "types": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "types"], "additionalProperties": false }] }, "inputSchema": {}, "resultSchema": {}, "handlerKey": { "type": "string" }, "template": { "type": "object", "properties": { "query": { "type": "object", "properties": { "typeKey": { "type": "string" }, "filters": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "enum": ["=", ">", ">=", "<", "<="] }, "value": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }] } }, "required": ["kind", "property", "op", "value"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "op": { "const": "in" }, "values": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }] } } }, "required": ["kind", "property", "op", "values"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "text" }, "term": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }] }, "properties": { "type": "array", "items": { "type": "string" } } }, "required": ["kind", "term"], "additionalProperties": false }] } }, "sort": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "property" }, "property": { "type": "string" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "property", "direction"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "identity" }, "direction": { "enum": ["asc", "desc"] } }, "required": ["kind", "direction"], "additionalProperties": false }] }, "limit": { "type": "number" } }, "required": ["typeKey", "limit"], "additionalProperties": false }, "operations": { "type": "array", "items": { "oneOf": [{ "type": "object", "properties": { "kind": { "const": "create-object" }, "typeKey": { "type": "string" }, "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } } }, "required": ["kind", "typeKey", "properties"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "update-object" }, "typeKey": { "type": "string" }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] }, "changes": { "type": "object", "additionalProperties": { "type": "object", "properties": { "from": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "absent" } }, "required": ["slot"], "additionalProperties": false }] }, "to": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "absent" } }, "required": ["slot"], "additionalProperties": false }] } }, "required": ["from", "to"], "additionalProperties": false } } }, "required": ["kind", "typeKey", "target", "changes"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "delete-object" }, "typeKey": { "type": "string" }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } }, "required": ["kind", "typeKey", "target"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "create-edge" }, "typeKey": { "type": "string" }, "source": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] }, "properties": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "literal" }, "value": {} }, "required": ["slot", "value"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" }, "property": { "type": "string" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } } }, "required": ["kind", "typeKey", "source", "target", "properties"], "additionalProperties": false }, { "type": "object", "properties": { "kind": { "const": "delete-edge" }, "typeKey": { "type": "string" }, "target": { "oneOf": [{ "type": "object", "properties": { "slot": { "const": "input" }, "key": { "type": "string" } }, "required": ["slot", "key"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "subject" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "item" } }, "required": ["slot"], "additionalProperties": false }, { "type": "object", "properties": { "slot": { "const": "step" }, "index": { "type": "number" } }, "required": ["slot", "index"], "additionalProperties": false }] } }, "required": ["kind", "typeKey", "target"], "additionalProperties": false }] } } }, "required": ["operations"], "additionalProperties": false }, "schemaLanguageVersion": { "type": "string" } }, "required": ["typeCategory", "typeKey", "version", "displayName", "description", "allowedSubjectTypes", "inputSchema", "resultSchema", "schemaLanguageVersion"], "additionalProperties": false }] } }, "railGroups": { "type": "array", "items": { "type": "string" } } }, "required": ["changeSetId", "expectedRevision", "changes"], "additionalProperties": false },
590
687
  validateChangeSet: { "type": "object", "properties": { "changeSetId": { "type": "string" }, "revision": { "type": "string" } }, "required": ["changeSetId", "revision"], "additionalProperties": false },
591
688
  discardChangeSet: { "type": "object", "properties": { "changeSetId": { "type": "string" } }, "required": ["changeSetId"], "additionalProperties": false },
592
689
  acceptChangeSet: { "type": "object", "properties": { "changeSetId": { "type": "string" }, "revision": { "type": "string" }, "correlationId": { "type": "string" } }, "required": ["changeSetId", "revision"], "additionalProperties": false },
@@ -646,8 +743,13 @@ var EXAMPLES = {
646
743
  decideConsent: { "interactionId": "<interactionId>", "decision": "approve", "approvedScopes": [] },
647
744
  listConnectedApps: {},
648
745
  revokeConnectedApp: { "clientId": "<clientId>" },
746
+ readAttachment: {
747
+ "objectId": "<objectId>",
748
+ "property": "<property>"
749
+ },
649
750
  readObject: { "objectId": "<objectId>" },
650
751
  queryObjects: { "kind": "objects", "typeKey": null, "limit": 1, "continuation": null },
752
+ queryRows: { "kind": "graph-query", "start": { "typeKey": null }, "answer": { "kind": "rows", "columns": [], "limit": 1, "continuation": null } },
651
753
  aggregateObjects: { "kind": "aggregate", "typeKey": null, "operation": "count" },
652
754
  discoverVerbs: { "objectId": "<objectId>" },
653
755
  readHistory: { "objectId": "<objectId>", "limit": 1, "continuation": null },
@@ -672,6 +774,7 @@ var EXAMPLES = {
672
774
  grantMembership: { "principalId": "<principalId>", "scopeKind": "organisation", "scopeId": "<scopeId>", "roleKey": "<roleKey>" },
673
775
  revokeMembership: { "principalId": "<principalId>", "scopeKind": "organisation", "scopeId": "<scopeId>" },
674
776
  setModelConfiguration: { "model": "<model>", "apiKey": "<apiKey>" },
777
+ setModelId: { "model": "<model>" },
675
778
  readDisplayNames: { "principalIds": [] },
676
779
  listMembers: {},
677
780
  changeMembershipRole: { "principalId": "<principalId>", "scopeKind": "organisation", "scopeId": "<scopeId>", "roleKey": "<roleKey>" },
@@ -680,6 +783,8 @@ var EXAMPLES = {
680
783
  createInvitation: { "email": "<email>", "roleKey": "<roleKey>" },
681
784
  listInvitations: {},
682
785
  revokeInvitation: { "invitationId": "<invitationId>" },
786
+ readModelConfigurationStatus: {},
787
+ readAccount: {},
683
788
  readInvitationDomainRule: {},
684
789
  setInvitationDomainRule: { "restricted": false, "domains": [] },
685
790
  reissueInvitation: { "invitationId": "<invitationId>" },
@@ -764,11 +869,16 @@ var EXAMPLES = {
764
869
  var ROUTE_INPUT_EXAMPLES = deepFreeze(EXAMPLES);
765
870
 
766
871
  // packages/api-contract/dist/routes.js
767
- var PROTOCOL_VERSION = 27;
872
+ var PROTOCOL_VERSION = 33;
768
873
  var VERSION_HEADER = "oe2-protocol-version";
769
874
  var TOKEN_HEADER = "authorization";
770
875
  var IDEMPOTENCY_HEADER = "oe2-idempotency-key";
771
876
  var STREAMED_ROUTE_NAMES = Object.freeze(["sendMessageStreamed", "answerPlanStreamed"]);
877
+ var BINARY_REQUEST_ROUTE_NAMES = Object.freeze(["stageAttachment"]);
878
+ var BINARY_RESPONSE_ROUTE_NAMES = Object.freeze(["readAttachment"]);
879
+ function isBinaryRequestRoute(name) {
880
+ return BINARY_REQUEST_ROUTE_NAMES.some((binary) => binary === name);
881
+ }
772
882
  var OMITTABLE_GROUPS = Object.freeze([
773
883
  "read",
774
884
  "history",
@@ -813,8 +923,47 @@ var ROUTES = Object.freeze({
813
923
  decideConsent: route({ name: "decideConsent", method: "POST", path: "/consent-decisions", group: "platform", selector: "none", subject: "platform", idempotent: false, admission: admitting("user"), versioned: true, module: "web-sdk", capability: "web.consentDecision" }),
814
924
  listConnectedApps: route({ name: "listConnectedApps", method: "POST", path: "/connected-apps", group: "platform", selector: "none", subject: "platform", idempotent: false, admission: admitting("user"), versioned: true, module: "web-sdk", capability: "web.connectedApps" }),
815
925
  revokeConnectedApp: route({ name: "revokeConnectedApp", method: "POST", path: "/connected-app-revocations", group: "platform", selector: "none", subject: "platform", idempotent: false, admission: admitting("user"), versioned: true, module: "web-sdk", capability: "web.connectedAppRevocation" }),
926
+ stageAttachment: route({
927
+ name: "stageAttachment",
928
+ method: "POST",
929
+ path: "/attachments/stage",
930
+ group: "write",
931
+ selector: "object",
932
+ subject: "project",
933
+ idempotent: false,
934
+ admission: admitting("user", "service", "client", "run-apply"),
935
+ versioned: true,
936
+ module: "objects-sdk",
937
+ capability: "objects.write"
938
+ }),
939
+ readAttachment: route({
940
+ name: "readAttachment",
941
+ method: "POST",
942
+ path: "/attachments/read",
943
+ group: "read",
944
+ selector: "object",
945
+ subject: "project",
946
+ idempotent: false,
947
+ admission: admitting("user", "service", "client", "run-explore", "run-apply"),
948
+ versioned: true,
949
+ module: "objects-sdk",
950
+ capability: "objects.read"
951
+ }),
816
952
  readObject: route({ name: "readObject", method: "POST", path: "/objects/read", group: "read", selector: "object", subject: "project", idempotent: false, admission: admitting("user", "service", "run-explore", "run-apply", "client"), versioned: true, module: "objects-sdk", capability: "objects.read" }),
817
953
  queryObjects: route({ name: "queryObjects", method: "POST", path: "/objects/query", group: "read", selector: "object", subject: "project", idempotent: false, admission: admitting("user", "service", "run-explore", "run-apply", "run-types", "client"), versioned: true, module: "objects-sdk", capability: "objects.query" }),
954
+ queryRows: route({
955
+ name: "queryRows",
956
+ method: "POST",
957
+ path: "/objects/rows",
958
+ group: "read",
959
+ selector: "object",
960
+ subject: "project",
961
+ idempotent: false,
962
+ admission: admitting("user", "service", "run-explore", "run-apply", "run-types", "client"),
963
+ versioned: true,
964
+ module: "objects-sdk",
965
+ capability: "objects.query"
966
+ }),
818
967
  aggregateObjects: route({ name: "aggregateObjects", method: "POST", path: "/objects/aggregate", group: "read", selector: "object", subject: "project", idempotent: false, admission: admitting("user", "service", "client"), versioned: true, module: "objects-sdk", capability: "objects.aggregate" }),
819
968
  discoverVerbs: route({ name: "discoverVerbs", method: "POST", path: "/objects/verbs", group: "read", selector: "object", subject: "project", idempotent: false, admission: admitting("user", "service", "run-explore", "run-apply", "client"), versioned: true, module: "objects-sdk", capability: "objects.read" }),
820
969
  readHistory: route({ name: "readHistory", method: "POST", path: "/objects/history", group: "history", selector: "object", subject: "project", idempotent: false, admission: admitting("user", "service", "run-explore", "run-apply", "client"), versioned: true, module: "objects-sdk", capability: "objects.history" }),
@@ -839,6 +988,9 @@ var ROUTES = Object.freeze({
839
988
  grantMembership: route({ name: "grantMembership", method: "POST", path: "/memberships", group: "administration", selector: "none", subject: "membership-scope", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.membership" }),
840
989
  revokeMembership: route({ name: "revokeMembership", method: "POST", path: "/membership-revocations", group: "administration", selector: "none", subject: "membership-scope", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.membershipRevocation" }),
841
990
  setModelConfiguration: route({ name: "setModelConfiguration", method: "POST", path: "/model-configuration", group: "administration", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.modelConfiguration" }),
991
+ setModelId: route({ name: "setModelId", method: "POST", path: "/model-configuration/model", group: "administration", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.modelId" }),
992
+ readModelConfigurationStatus: route({ name: "readModelConfigurationStatus", method: "POST", path: "/model-configuration/status", group: "read", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.modelConfigurationStatus" }),
993
+ readAccount: route({ name: "readAccount", method: "POST", path: "/account", group: "read", selector: "none", subject: "none", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.account" }),
842
994
  readDisplayNames: route({ name: "readDisplayNames", method: "POST", path: "/principals/names", group: "read", selector: "none", subject: "display-names", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.displayNames" }),
843
995
  listMembers: route({ name: "listMembers", method: "POST", path: "/projects/members", group: "read", selector: "project", subject: "project", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.members" }),
844
996
  changeMembershipRole: route({ name: "changeMembershipRole", method: "POST", path: "/membership-roles", group: "administration", selector: "none", subject: "membership-scope", idempotent: false, admission: admitting("user"), versioned: true, module: "admin-sdk", capability: "admin.membershipRole" }),
@@ -952,8 +1104,11 @@ var ROUTE_CARRIES_CREDENTIAL = Object.freeze({
952
1104
  decideConsent: false,
953
1105
  listConnectedApps: false,
954
1106
  revokeConnectedApp: false,
1107
+ stageAttachment: false,
1108
+ readAttachment: false,
955
1109
  readObject: false,
956
1110
  queryObjects: false,
1111
+ queryRows: false,
957
1112
  aggregateObjects: false,
958
1113
  discoverVerbs: false,
959
1114
  readHistory: false,
@@ -978,6 +1133,9 @@ var ROUTE_CARRIES_CREDENTIAL = Object.freeze({
978
1133
  grantMembership: false,
979
1134
  revokeMembership: false,
980
1135
  setModelConfiguration: true,
1136
+ setModelId: false,
1137
+ readModelConfigurationStatus: false,
1138
+ readAccount: false,
981
1139
  readDisplayNames: false,
982
1140
  listMembers: false,
983
1141
  changeMembershipRole: false,
@@ -1082,12 +1240,92 @@ var CLIENT_SCOPES = Object.freeze({
1082
1240
  offline_access: Object.freeze({ capabilities: Object.freeze([]), consentLine: "Stay connected when you are away, until you disconnect it." })
1083
1241
  });
1084
1242
 
1243
+ // packages/api-contract/dist/attachment-headers.js
1244
+ var ATTACHMENT_SELECTOR_HEADER = "x-oe2-selector";
1245
+ var ATTACHMENT_NAME_HEADER = "x-oe2-attachment-name";
1246
+ function attachmentNameHeader(name) {
1247
+ return `UTF-8''${encodeURIComponent(name).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`)}`;
1248
+ }
1249
+
1250
+ // packages/sdk-dispatch/dist/response.js
1251
+ function responseOf(status, body, reason, headers = {}) {
1252
+ let read = false;
1253
+ const claim = () => {
1254
+ if (read)
1255
+ throw new Error("the response body has already been read");
1256
+ read = true;
1257
+ };
1258
+ const source = async function* () {
1259
+ if (typeof body === "string")
1260
+ yield Buffer.from(body, "utf8");
1261
+ else if (body instanceof Uint8Array)
1262
+ yield body;
1263
+ else
1264
+ yield* body;
1265
+ };
1266
+ const members = {
1267
+ status,
1268
+ ...reason === void 0 || reason === "" ? {} : { reason },
1269
+ header: (name) => {
1270
+ const entry2 = Object.entries(headers).find(([key]) => key.toLowerCase() === name.toLowerCase());
1271
+ const value = entry2?.[1];
1272
+ return value === void 0 ? null : typeof value === "string" || typeof value === "number" ? String(value) : value.join(", ");
1273
+ },
1274
+ bytes: () => {
1275
+ claim();
1276
+ let iterated = false;
1277
+ return {
1278
+ async *[Symbol.asyncIterator]() {
1279
+ if (iterated)
1280
+ throw new Error("the response body has already been read");
1281
+ iterated = true;
1282
+ yield* source();
1283
+ }
1284
+ };
1285
+ },
1286
+ json: async () => {
1287
+ claim();
1288
+ const chunks = [];
1289
+ for await (const chunk of source())
1290
+ chunks.push(chunk);
1291
+ const value = JSON.parse(Buffer.concat(chunks).toString("utf8"));
1292
+ return value;
1293
+ }
1294
+ };
1295
+ return new Proxy(members, {
1296
+ get(target, member) {
1297
+ if (member === "status" || member === "reason" || member === "json" || member === "header" || member === "bytes") {
1298
+ return target[member];
1299
+ }
1300
+ if (member === "then" || typeof member === "symbol")
1301
+ return void 0;
1302
+ throw new Error(`the response member ${String(member)} is not implemented`);
1303
+ }
1304
+ });
1305
+ }
1306
+
1085
1307
  // packages/sdk-dispatch/dist/explain.js
1308
+ var BOUND_LABEL = {
1309
+ "request-body": "the request-body size",
1310
+ "query-limit": "the query page size",
1311
+ "concurrency-per-principal": "the concurrent-request limit per principal",
1312
+ "rate-per-principal": "the request-rate limit per principal",
1313
+ "rate-per-address": "the request-rate limit per address",
1314
+ "resolve-in-flight": "the concurrent name-resolution limit",
1315
+ "pending-sign-ins": "the pending sign-in limit"
1316
+ };
1086
1317
  function explainKind(kind) {
1087
1318
  if (!Object.hasOwn(BY_KIND, kind)) {
1088
1319
  throw new Error(`the refusal kind ${JSON.stringify(kind)} has no entry in the refusal catalogue`);
1089
1320
  }
1090
- return Object.freeze({ explanation: BY_KIND[kind], explains: "kind" });
1321
+ const explanation = BY_KIND[kind];
1322
+ if (kind !== "bound-exceeded") {
1323
+ return Object.freeze({ explanation, explains: "kind" });
1324
+ }
1325
+ return Object.freeze({ explanation: withMeaning(explanation, "The exceeded limit is the request-body, query-page, concurrency, request-rate, address-rate, resolve-capacity or pending-sign-in limit."), explains: "kind" });
1326
+ }
1327
+ function withMeaning(explanation, detail) {
1328
+ return Object.freeze({ meaning: `${explanation.meaning} ${detail}`, next: explanation.next });
1091
1329
  }
1092
1330
  function explainClass(refusalClass) {
1093
1331
  return Object.freeze({ explanation: BY_CLASS[refusalClass], explains: "class" });
@@ -1101,17 +1339,36 @@ function explainResultRefusal(rule, refusalClass) {
1101
1339
  }
1102
1340
  return explainClass(refusalClass);
1103
1341
  }
1104
- function explainRefused(refusal2) {
1105
- if (isRefusalRule(refusal2.rule)) {
1106
- return Object.freeze({ explanation: BY_RULE[refusal2.rule], explains: "rule" });
1342
+ function explainRefused(refusal2, request3) {
1343
+ const apiRule = Object.hasOwn(BY_API_RULE, refusal2.rule);
1344
+ const hasRuleExplanation = isRefusalRule(refusal2.rule) || apiRule;
1345
+ const explanation = isRefusalRule(refusal2.rule) ? BY_RULE[refusal2.rule] : apiRule ? BY_API_RULE[refusal2.rule] : BY_CLASS[refusal2.class];
1346
+ if (refusal2.rule === "ref-exists") {
1347
+ const input = typeof request3 === "object" && request3 !== null && !Array.isArray(request3) && "input" in request3 ? request3.input : void 0;
1348
+ const name = typeof input === "object" && input !== null && !Array.isArray(input) && "name" in input ? input.name : void 0;
1349
+ if (typeof name === "string") {
1350
+ return Object.freeze({ explanation: withMeaning(explanation, `The requested ref name is ${JSON.stringify(name)}.`), explains: hasRuleExplanation ? "rule" : "class" });
1351
+ }
1352
+ }
1353
+ if (refusal2.rule === "malformed-query" && refusal2.violations.length > 0) {
1354
+ const paths = refusal2.violations.map((violation) => violation.path.join(".") || "the request").join(", ");
1355
+ return Object.freeze({ explanation: withMeaning(explanation, `Invalid field path: ${paths}.`), explains: hasRuleExplanation ? "rule" : "class" });
1356
+ }
1357
+ if (refusal2.rule === "over-bound" && refusal2.violations.length > 0) {
1358
+ const paths = refusal2.violations.map((violation) => violation.path.join(".") || "the request").join(", ");
1359
+ return Object.freeze({ explanation: withMeaning(explanation, `The exceeded limit is ${paths}.`), explains: hasRuleExplanation ? "rule" : "class" });
1107
1360
  }
1108
- return explainClass(refusal2.class);
1361
+ return hasRuleExplanation ? Object.freeze({ explanation, explains: "rule" }) : explainClass(refusal2.class);
1109
1362
  }
1110
- function explainedRefusalOf(refusal2) {
1363
+ function explainedRefusalOf(refusal2, request3) {
1111
1364
  if (refusal2.kind === "refused") {
1112
- return Object.freeze({ ...refusal2, ...explainRefused(refusal2) });
1365
+ return Object.freeze({ ...refusal2, ...explainRefused(refusal2, request3) });
1113
1366
  }
1114
- return Object.freeze({ ...refusal2, ...explainKind(refusal2.kind) });
1367
+ const explanation = explainKind(refusal2.kind);
1368
+ if (refusal2.kind === "bound-exceeded") {
1369
+ return Object.freeze({ ...refusal2, ...explanation, explanation: withMeaning(explanation.explanation, `The exceeded limit is ${BOUND_LABEL[refusal2.bound]}.`) });
1370
+ }
1371
+ return Object.freeze({ ...refusal2, ...explanation });
1115
1372
  }
1116
1373
  function isRefusedResult(value) {
1117
1374
  return typeof value === "object" && value !== null && !Array.isArray(value) && "kind" in value && value.kind === "refused";
@@ -1131,10 +1388,10 @@ function explainReplayedRefusal(replay) {
1131
1388
  }
1132
1389
  return explainResultRefusal(replay.rule, replay.class);
1133
1390
  }
1134
- function explainedEnvelopeOf(envelope) {
1391
+ function explainedEnvelopeOf(envelope, request3) {
1135
1392
  if ("refusal" in envelope) {
1136
1393
  const stamped = envelope.correlationId;
1137
- return { version: envelope.version, refusal: explainedRefusalOf(envelope.refusal), correlationId: typeof stamped === "string" ? stamped : null };
1394
+ return { version: envelope.version, refusal: explainedRefusalOf(envelope.refusal, request3), correlationId: typeof stamped === "string" ? stamped : null };
1138
1395
  }
1139
1396
  if (envelope.replayed === true) {
1140
1397
  const replay = envelope.result;
@@ -1164,39 +1421,12 @@ function unauthenticatedEnvelope() {
1164
1421
 
1165
1422
  // packages/sdk-dispatch/dist/socket-transport.js
1166
1423
  import { request } from "node:http";
1167
-
1168
- // packages/sdk-dispatch/dist/response.js
1169
- function responseOf(status, text, reason) {
1170
- let read = false;
1171
- const members = {
1172
- status,
1173
- ...reason === void 0 || reason === "" ? {} : { reason },
1174
- json: async () => {
1175
- if (read) {
1176
- throw new Error("the response body has already been read");
1177
- }
1178
- read = true;
1179
- return JSON.parse(text);
1180
- }
1181
- };
1182
- return new Proxy(members, {
1183
- get(target, member) {
1184
- if (member === "status" || member === "json") {
1185
- return target[member];
1186
- }
1187
- if (member === "reason") {
1188
- return target.reason;
1189
- }
1190
- if (member === "then" || typeof member === "symbol") {
1191
- return void 0;
1192
- }
1193
- throw new Error(`the response member ${String(member)} is not implemented`);
1194
- }
1195
- });
1196
- }
1197
-
1198
- // packages/sdk-dispatch/dist/socket-transport.js
1199
1424
  var REQUEST_DEADLINE_MS = 1e4;
1425
+ function requestDeadlineOf(path, method, override) {
1426
+ if (override !== void 0)
1427
+ return override;
1428
+ return [...BINARY_REQUEST_ROUTE_NAMES, ...BINARY_RESPONSE_ROUTE_NAMES].some((name) => ROUTES[name].path === path && ROUTES[name].method === method) ? 12e4 : REQUEST_DEADLINE_MS;
1429
+ }
1200
1430
  var HostOutcomeUnknown = class extends Error {
1201
1431
  path;
1202
1432
  reason;
@@ -1234,11 +1464,11 @@ var INIT_MEMBERS = Object.freeze(["method", "headers", "body", "signal"]);
1234
1464
  function unsupported(member) {
1235
1465
  return new Error(`the socket-bound request function does not implement ${member}`);
1236
1466
  }
1237
- function isPlainObject(value) {
1467
+ function isPlainObject2(value) {
1238
1468
  return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
1239
1469
  }
1240
1470
  function checkedInit(init) {
1241
- if (!isPlainObject(init)) {
1471
+ if (!isPlainObject2(init)) {
1242
1472
  throw unsupported("an init that is not a plain object");
1243
1473
  }
1244
1474
  for (const member of Object.keys(init)) {
@@ -1250,7 +1480,7 @@ function checkedInit(init) {
1250
1480
  if (typeof method !== "string") {
1251
1481
  throw unsupported("a method that is not a string");
1252
1482
  }
1253
- if (!isPlainObject(headers)) {
1483
+ if (!isPlainObject2(headers)) {
1254
1484
  throw unsupported("headers that are not a plain object of strings");
1255
1485
  }
1256
1486
  const sent = {};
@@ -1260,8 +1490,8 @@ function checkedInit(init) {
1260
1490
  }
1261
1491
  sent[name] = value;
1262
1492
  }
1263
- if (body !== void 0 && typeof body !== "string") {
1264
- throw unsupported("a body that is not a string");
1493
+ if (body !== void 0 && typeof body !== "string" && !(body instanceof Uint8Array)) {
1494
+ throw unsupported("a body that is neither a string nor bytes");
1265
1495
  }
1266
1496
  if (signal !== void 0 && !(signal instanceof AbortSignal)) {
1267
1497
  throw unsupported("a signal that is not an AbortSignal");
@@ -1269,7 +1499,7 @@ function checkedInit(init) {
1269
1499
  return { method, headers: sent, body: body === void 0 ? null : body, signal: signal === void 0 ? null : signal };
1270
1500
  }
1271
1501
  var SOCKET_ORIGIN = "http://localhost";
1272
- function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
1502
+ function createHostFetch(socketPath, deadlineMs) {
1273
1503
  return async (input, init) => {
1274
1504
  if (typeof input !== "string") {
1275
1505
  throw unsupported("an input that is not a string URL");
@@ -1286,7 +1516,9 @@ function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
1286
1516
  throw unsupported(`the protocol ${url.protocol}`);
1287
1517
  }
1288
1518
  const path = `${url.pathname}${url.search}`;
1519
+ const requestDeadlineMs = requestDeadlineOf(url.pathname, checked.method, deadlineMs);
1289
1520
  return new Promise((resolve, reject) => {
1521
+ let responseBody = null;
1290
1522
  let written = false;
1291
1523
  let settled = false;
1292
1524
  let deadline = null;
@@ -1306,14 +1538,28 @@ function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
1306
1538
  });
1307
1539
  };
1308
1540
  const outgoing = request({ socketPath, method: checked.method, path, headers: checked.headers }, (incoming) => {
1541
+ responseBody = incoming;
1542
+ const binary = BINARY_RESPONSE_ROUTE_NAMES.some((name) => ROUTES[name].path === url.pathname && ROUTES[name].method === checked.method);
1309
1543
  const chunks = [];
1310
- incoming.on("data", (chunk) => {
1311
- chunks.push(chunk);
1312
- });
1544
+ if (binary) {
1545
+ if (incoming.statusCode === void 0) {
1546
+ settle2(() => reject(new Error("the host's response carried no status")));
1547
+ incoming.destroy();
1548
+ return;
1549
+ }
1550
+ resolve(responseOf(incoming.statusCode, incoming, incoming.statusMessage, incoming.headers));
1551
+ } else {
1552
+ incoming.on("data", (chunk) => {
1553
+ chunks.push(chunk);
1554
+ });
1555
+ }
1313
1556
  incoming.on("error", lost);
1314
1557
  incoming.on("close", () => {
1315
1558
  if (!incoming.complete) {
1316
1559
  lost(new Error("the connection closed before the whole response arrived"));
1560
+ } else {
1561
+ settle2(() => {
1562
+ });
1317
1563
  }
1318
1564
  });
1319
1565
  incoming.on("end", () => {
@@ -1327,16 +1573,17 @@ function createHostFetch(socketPath, deadlineMs = REQUEST_DEADLINE_MS) {
1327
1573
  reject(new Error("the host's response carried no status"));
1328
1574
  return;
1329
1575
  }
1330
- resolve(responseOf(status, Buffer.concat(chunks).toString("utf8"), reason));
1576
+ if (!binary)
1577
+ resolve(responseOf(status, Buffer.concat(chunks), reason, incoming.headers));
1331
1578
  });
1332
1579
  });
1333
1580
  });
1334
1581
  deadline = setTimeout(() => {
1335
- settle2(() => {
1336
- reject(new HostOutcomeUnknown(path, "deadline", `the host did not answer ${path} within the deadline of ${String(deadlineMs)} ms`));
1337
- });
1582
+ const error = new HostOutcomeUnknown(path, "deadline", `the host did not answer ${path} within the deadline of ${String(requestDeadlineMs)} ms`);
1583
+ settle2(() => reject(error));
1584
+ responseBody?.destroy(error);
1338
1585
  outgoing.destroy();
1339
- }, deadlineMs);
1586
+ }, requestDeadlineMs);
1340
1587
  outgoing.on("finish", () => {
1341
1588
  written = true;
1342
1589
  });
@@ -1525,6 +1772,36 @@ async function readEnvelope(response, path) {
1525
1772
  }
1526
1773
  return envelope;
1527
1774
  }
1775
+ function isByteStream(value) {
1776
+ return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
1777
+ }
1778
+ async function requestBodyOf(route2, body, headers) {
1779
+ if (!isBinaryRequestRoute(route2))
1780
+ return JSON.stringify(body);
1781
+ if (typeof body !== "object" || body === null || !("selector" in body) || !("input" in body)) {
1782
+ throw new TypeError("a binary request needs a selector and upload");
1783
+ }
1784
+ const input = body.input;
1785
+ if (typeof input !== "object" || input === null || !("name" in input) || typeof input.name !== "string" || !("body" in input) || !isByteStream(input.body)) {
1786
+ throw new TypeError("a binary upload needs a name and byte stream");
1787
+ }
1788
+ headers["content-type"] = "application/octet-stream";
1789
+ headers[ATTACHMENT_SELECTOR_HEADER] = JSON.stringify(body.selector);
1790
+ headers[ATTACHMENT_NAME_HEADER] = attachmentNameHeader(input.name);
1791
+ const chunks = [];
1792
+ let length = 0;
1793
+ for await (const chunk of input.body) {
1794
+ chunks.push(chunk);
1795
+ length += chunk.byteLength;
1796
+ }
1797
+ const bytes = new Uint8Array(length);
1798
+ let offset = 0;
1799
+ for (const chunk of chunks) {
1800
+ bytes.set(chunk, offset);
1801
+ offset += chunk.byteLength;
1802
+ }
1803
+ return bytes;
1804
+ }
1528
1805
  async function call(transport, origin, route2, body, token, idempotencyKey) {
1529
1806
  const entry2 = ROUTES[route2];
1530
1807
  if (entry2.idempotent !== (idempotencyKey !== null)) {
@@ -1543,8 +1820,9 @@ async function call(transport, origin, route2, body, token, idempotencyKey) {
1543
1820
  if (idempotencyKey !== null) {
1544
1821
  headers[IDEMPOTENCY_HEADER] = idempotencyKey;
1545
1822
  }
1546
- const response = await transport(`${origin}${entry2.path}`, { method: entry2.method, headers, body: JSON.stringify(body) });
1547
- return explainedEnvelopeOf(await readEnvelope(response, entry2.path));
1823
+ const sent = await requestBodyOf(route2, body, headers);
1824
+ const response = await transport(`${origin}${entry2.path}`, { method: entry2.method, headers, body: sent });
1825
+ return explainedEnvelopeOf(await readEnvelope(response, entry2.path), body);
1548
1826
  }
1549
1827
  var StreamedRouteRefusal = class extends Error {
1550
1828
  refusal;
@@ -1594,6 +1872,60 @@ async function* callStreamed(transport, origin, route2, body, token, signal) {
1594
1872
  yield JSON.parse(line);
1595
1873
  }
1596
1874
  }
1875
+ function attachmentDescriptorOf(response) {
1876
+ const fault = () => new Error("the host answered /attachments/read with invalid attachment headers");
1877
+ const sha256 = response.header("x-oe2-attachment-sha256");
1878
+ const mediaType = response.header("content-type");
1879
+ const length = response.header("content-length");
1880
+ const disposition = response.header("content-disposition");
1881
+ const encodedName = disposition === null ? null : /;\s*filename\*=UTF-8''([^;]+)/i.exec(disposition)?.[1];
1882
+ if (sha256 === null || !/^[0-9a-f]{64}$/.test(sha256) || mediaType === null || mediaType.length === 0 || length === null || !/^(0|[1-9][0-9]*)$/.test(length) || !Number.isSafeInteger(Number(length)) || encodedName === null || encodedName === void 0)
1883
+ throw fault();
1884
+ let name;
1885
+ try {
1886
+ name = decodeURIComponent(encodedName);
1887
+ } catch (error) {
1888
+ if (!(error instanceof URIError))
1889
+ throw error;
1890
+ throw fault();
1891
+ }
1892
+ return { sha256, name, mediaType, bytes: Number(length) };
1893
+ }
1894
+ async function callAttachment(transport, origin, selector, input, token) {
1895
+ if (token === null)
1896
+ return unauthenticatedEnvelope();
1897
+ const entry2 = ROUTES.readAttachment;
1898
+ let response = await transport(`${origin}${entry2.path}`, {
1899
+ method: entry2.method,
1900
+ headers: {
1901
+ "content-type": "application/json",
1902
+ [VERSION_HEADER]: String(PROTOCOL_VERSION),
1903
+ [TOKEN_HEADER]: `Bearer ${token}`
1904
+ },
1905
+ body: JSON.stringify({ selector, input })
1906
+ });
1907
+ if ([302, 303, 307].includes(response.status)) {
1908
+ const location = response.header("location");
1909
+ if (location === null)
1910
+ throw new Error("the host answered /attachments/read with a redirect without Location");
1911
+ const target = new URL(location, origin);
1912
+ if (target.origin === new URL(origin).origin) {
1913
+ throw new Error("the host answered /attachments/read with a same-origin redirect");
1914
+ }
1915
+ const redirected = await fetch(target.href, {
1916
+ redirect: "follow",
1917
+ credentials: "omit",
1918
+ signal: AbortSignal.timeout(12e4)
1919
+ });
1920
+ if (redirected.body === null)
1921
+ throw new Error("the attachment redirect answered without a body");
1922
+ response = responseOf(redirected.status, redirected.body, redirected.statusText, Object.fromEntries(redirected.headers));
1923
+ }
1924
+ if (response.status !== 200)
1925
+ return explainedEnvelopeOf(await readEnvelope(response, entry2.path));
1926
+ const descriptor2 = attachmentDescriptorOf(response);
1927
+ return { version: PROTOCOL_VERSION, result: { descriptor: descriptor2, body: response.bytes() } };
1928
+ }
1597
1929
 
1598
1930
  // packages/sdk-dispatch/dist/module-factory.js
1599
1931
  function freezeDoc(doc2) {
@@ -1618,7 +1950,7 @@ function methodOf(entry2, transport, origin, token) {
1618
1950
  headers[IDEMPOTENCY_HEADER] = idempotencyKey;
1619
1951
  }
1620
1952
  const response = await transport(`${origin}${entry2.path}`, { method: entry2.method, headers, body: JSON.stringify(body) });
1621
- return explainedEnvelopeOf(await readEnvelope(response, entry2.path));
1953
+ return explainedEnvelopeOf(await readEnvelope(response, entry2.path), body);
1622
1954
  };
1623
1955
  return Object.freeze(Object.assign(send, { doc: freezeDoc(entry2.doc) }));
1624
1956
  }
@@ -1653,7 +1985,7 @@ function createTypedClient(names, entries6, transport, origin, token) {
1653
1985
 
1654
1986
  // packages/sdk-dispatch/dist/https-transport.js
1655
1987
  import { request as request2 } from "node:https";
1656
- function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLINE_MS) {
1988
+ function createHttpsTransport(origin, options = {}, deadlineMs) {
1657
1989
  const originUrl = new URL(origin);
1658
1990
  if (originUrl.protocol !== "https:") {
1659
1991
  throw new Error(`the origin ${origin} is not an https: URL`);
@@ -1663,7 +1995,9 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
1663
1995
  if (url.origin !== originUrl.origin) {
1664
1996
  throw new Error(`the request ${input} is not on the transport's own origin ${originUrl.origin}`);
1665
1997
  }
1998
+ const requestDeadlineMs = requestDeadlineOf(url.pathname, init.method, deadlineMs);
1666
1999
  return new Promise((resolve, reject) => {
2000
+ let responseBody = null;
1667
2001
  let written = false;
1668
2002
  let settled = false;
1669
2003
  let deadline = null;
@@ -1691,11 +2025,29 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
1691
2025
  headers: init.headers,
1692
2026
  ca: options.ca
1693
2027
  }, (incoming) => {
2028
+ responseBody = incoming;
2029
+ const binary = BINARY_RESPONSE_ROUTE_NAMES.some((name) => ROUTES[name].path === url.pathname && ROUTES[name].method === init.method);
1694
2030
  const chunks = [];
1695
- incoming.on("data", (chunk) => {
1696
- chunks.push(chunk);
1697
- });
2031
+ if (binary) {
2032
+ if (incoming.statusCode === void 0) {
2033
+ settle2(() => reject(new Error("the host's response carried no status")));
2034
+ incoming.destroy();
2035
+ return;
2036
+ }
2037
+ resolve(responseOf(incoming.statusCode, incoming, incoming.statusMessage, incoming.headers));
2038
+ } else {
2039
+ incoming.on("data", (chunk) => {
2040
+ chunks.push(chunk);
2041
+ });
2042
+ }
1698
2043
  incoming.on("error", lost);
2044
+ incoming.on("close", () => {
2045
+ if (!incoming.complete)
2046
+ lost(new Error("the connection closed before the whole response arrived"));
2047
+ else
2048
+ settle2(() => {
2049
+ });
2050
+ });
1699
2051
  incoming.on("end", () => {
1700
2052
  const status = incoming.statusCode;
1701
2053
  const reason = incoming.statusMessage;
@@ -1704,16 +2056,17 @@ function createHttpsTransport(origin, options = {}, deadlineMs = REQUEST_DEADLIN
1704
2056
  reject(new Error("the host's response carried no status"));
1705
2057
  return;
1706
2058
  }
1707
- resolve(responseOf(status, Buffer.concat(chunks).toString("utf8"), reason));
2059
+ if (!binary)
2060
+ resolve(responseOf(status, Buffer.concat(chunks), reason, incoming.headers));
1708
2061
  });
1709
2062
  });
1710
2063
  });
1711
2064
  deadline = setTimeout(() => {
1712
- settle2(() => {
1713
- reject(new HostOutcomeUnknown(path, "deadline", `the host did not answer ${path} within the deadline of ${String(deadlineMs)} ms`));
1714
- });
2065
+ const error = new HostOutcomeUnknown(path, "deadline", `the host did not answer ${path} within the deadline of ${String(requestDeadlineMs)} ms`);
2066
+ settle2(() => reject(error));
2067
+ responseBody?.destroy(error);
1715
2068
  outgoing.destroy();
1716
- }, deadlineMs);
2069
+ }, requestDeadlineMs);
1717
2070
  outgoing.on("finish", () => {
1718
2071
  written = true;
1719
2072
  });
@@ -1760,6 +2113,9 @@ var ADMIN_ROUTE_NAMES = Object.freeze([
1760
2113
  "grantMembership",
1761
2114
  "revokeMembership",
1762
2115
  "setModelConfiguration",
2116
+ "setModelId",
2117
+ "readModelConfigurationStatus",
2118
+ "readAccount",
1763
2119
  "readDisplayNames",
1764
2120
  "listMembers",
1765
2121
  "changeMembershipRole",
@@ -1923,6 +2279,9 @@ function exploreViewAddress(address, state) {
1923
2279
  }
1924
2280
  return query2.size === 0 ? path : `${path}?${query2.toString()}`;
1925
2281
  }
2282
+ function exploreOpenObjectAddress(address, objectId) {
2283
+ return withViewState(typePageAddress(address), { object: objectId });
2284
+ }
1926
2285
  function projectAddress(organisationId, projectId, ref) {
1927
2286
  return withSubject(projectBase(organisationId, projectId), { ref, q: null });
1928
2287
  }
@@ -1945,6 +2304,19 @@ function settingsAddress(organisationId, page) {
1945
2304
  function proposalAddress(organisationId, projectId, proposalId, ref) {
1946
2305
  return withSubject(`${projectBase(organisationId, projectId)}/reviews/${encodeURIComponent(proposalId)}`, { ref, q: null });
1947
2306
  }
2307
+ function withViewState(address, state) {
2308
+ const split = address.indexOf("?");
2309
+ const path = split === -1 ? address : address.slice(0, split);
2310
+ const query2 = new URLSearchParams(split === -1 ? "" : address.slice(split + 1));
2311
+ for (const [name, value] of Object.entries(state)) {
2312
+ if (value === null || value === "") {
2313
+ query2.delete(name);
2314
+ } else {
2315
+ query2.set(name, value);
2316
+ }
2317
+ }
2318
+ return query2.size === 0 ? path : `${path}?${query2.toString()}`;
2319
+ }
1948
2320
  function branchDiffAddress(organisationId, projectId, ref) {
1949
2321
  return withSubject(`${projectBase(organisationId, projectId)}/branches/diff`, { ref, q: null });
1950
2322
  }
@@ -2049,6 +2421,8 @@ function linkPath(organisationId, projectId, subject, ref) {
2049
2421
  // packages/objects-sdk/dist/transport-client.js
2050
2422
  var OBJECTS_ROUTE_ENTRIES = routeEntriesOf("objects-sdk");
2051
2423
  var OBJECTS_ROUTE_NAMES = [
2424
+ "stageAttachment",
2425
+ "readAttachment",
2052
2426
  "createObjectSet",
2053
2427
  "listObjectSets",
2054
2428
  "readObjectSet",
@@ -2056,6 +2430,7 @@ var OBJECTS_ROUTE_NAMES = [
2056
2430
  "deleteObjectSet",
2057
2431
  "readObject",
2058
2432
  "queryObjects",
2433
+ "queryRows",
2059
2434
  "aggregateObjects",
2060
2435
  "discoverVerbs",
2061
2436
  "readHistory",
@@ -2081,19 +2456,432 @@ var OBJECTS_ROUTE_NAMES = [
2081
2456
  "listApps",
2082
2457
  "setObjectLock"
2083
2458
  ];
2459
+ var JSON_OBJECTS_ROUTE_NAMES = OBJECTS_ROUTE_NAMES.filter((name) => !isBinaryRequestRoute(name) && !BINARY_RESPONSE_ROUTE_NAMES.some((route2) => route2 === name));
2084
2460
  function entries4() {
2085
- return OBJECTS_ROUTE_NAMES.map((name) => ROUTES[name]);
2461
+ return JSON_OBJECTS_ROUTE_NAMES.map((name) => ROUTES[name]);
2086
2462
  }
2087
2463
  function createObjectsTransportClient(transport, origin, token) {
2088
- return createTypedClient(OBJECTS_ROUTE_NAMES, entries4(), transport, origin, token);
2464
+ return Object.freeze({
2465
+ ...createTypedClient(JSON_OBJECTS_ROUTE_NAMES, entries4(), transport, origin, token),
2466
+ readAttachment: (selector, input) => callAttachment(transport, origin, selector, input, token),
2467
+ stageAttachment: (selector, file) => call(transport, origin, "stageAttachment", {
2468
+ selector,
2469
+ input: { name: file.name, body: (async function* () {
2470
+ yield file.bytes;
2471
+ })() }
2472
+ }, token, null)
2473
+ });
2089
2474
  }
2090
2475
 
2091
2476
  // packages/schema-language/dist/version.js
2092
2477
  var SCHEMA_LANGUAGE_VERSION = "1";
2093
2478
 
2479
+ // packages/schema-language/dist/attachment-classes.js
2480
+ var ATTACHMENT_CLASSES = {
2481
+ image: [
2482
+ { mediaType: "image/png", extensions: [".png"] },
2483
+ { mediaType: "image/jpeg", extensions: [".jpg", ".jpeg"] },
2484
+ { mediaType: "image/webp", extensions: [".webp"] },
2485
+ { mediaType: "image/gif", extensions: [".gif"] }
2486
+ ],
2487
+ pdf: [{ mediaType: "application/pdf", extensions: [".pdf"] }],
2488
+ step: [{ mediaType: "model/step", extensions: [".step", ".stp"] }],
2489
+ mesh: [{ mediaType: "model/stl", extensions: [".stl"] }],
2490
+ text: [{
2491
+ mediaType: "text/plain; charset=utf-8",
2492
+ extensions: [
2493
+ ".txt",
2494
+ ".md",
2495
+ ".csv",
2496
+ ".json",
2497
+ ".yaml",
2498
+ ".yml",
2499
+ ".toml",
2500
+ ".ini",
2501
+ ".log",
2502
+ ".xml",
2503
+ ".ts",
2504
+ ".tsx",
2505
+ ".js",
2506
+ ".py",
2507
+ ".c",
2508
+ ".h",
2509
+ ".cpp",
2510
+ ".hpp",
2511
+ ".rs",
2512
+ ".go",
2513
+ ".java",
2514
+ ".m",
2515
+ ".sql",
2516
+ ".sh"
2517
+ ]
2518
+ }]
2519
+ };
2520
+
2521
+ // packages/schema-language/dist/datetime.js
2522
+ var DATETIME_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?(?:(Z)|([+-])(\d{2}):(\d{2}))$/;
2523
+ var MILLISECONDS_PER_MINUTE = 6e4;
2524
+ function normaliseDatetime(text) {
2525
+ const match = DATETIME_PATTERN.exec(text);
2526
+ if (match === null) {
2527
+ return void 0;
2528
+ }
2529
+ const year = Number(match[1]);
2530
+ const month = Number(match[2]);
2531
+ const day = Number(match[3]);
2532
+ const hour = Number(match[4]);
2533
+ const minute = Number(match[5]);
2534
+ const second = Number(match[6]);
2535
+ const millisecond = match[7] === void 0 ? 0 : Number(match[7].padEnd(3, "0"));
2536
+ if (minute > 59 || second > 59) {
2537
+ return void 0;
2538
+ }
2539
+ const local = /* @__PURE__ */ new Date(0);
2540
+ local.setUTCFullYear(year, month - 1, day);
2541
+ local.setUTCHours(hour, minute, second, millisecond);
2542
+ if (local.getUTCMonth() !== month - 1 || local.getUTCDate() !== day) {
2543
+ return void 0;
2544
+ }
2545
+ let offsetMinutes = 0;
2546
+ if (match[8] === void 0) {
2547
+ const offsetHour = Number(match[10]);
2548
+ const offsetMinute = Number(match[11]);
2549
+ if (offsetHour > 23 || offsetMinute > 59) {
2550
+ return void 0;
2551
+ }
2552
+ offsetMinutes = (match[9] === "-" ? -1 : 1) * (offsetHour * 60 + offsetMinute);
2553
+ }
2554
+ const instant = new Date(local.getTime() - offsetMinutes * MILLISECONDS_PER_MINUTE);
2555
+ if (instant.getUTCFullYear() < 0 || instant.getUTCFullYear() > 9999) {
2556
+ return void 0;
2557
+ }
2558
+ return instant.toISOString();
2559
+ }
2560
+
2561
+ // packages/schema-language/dist/validate-value.js
2562
+ var RULE_TYPE_MISMATCH = "type-mismatch";
2563
+ var RULE_UNDECLARED_PROPERTY = "undeclared-property";
2564
+ var RULE_MISSING_REQUIRED_PROPERTY = "missing-required-property";
2565
+ var RULE_ENUM_VIOLATION = "enum-violation";
2566
+ var RULE_ARRAY_BOUND_EXCEEDED = "array-bound-exceeded";
2567
+ var RULE_INVALID_DATETIME = "invalid-datetime";
2568
+ function validateValue(schema, value) {
2569
+ const violations = [];
2570
+ walk(schema, value, [], violations);
2571
+ return violations.length === 0 ? { ok: true } : { ok: false, violations };
2572
+ }
2573
+ function walk(schema, value, path, violations) {
2574
+ switch (schema.kind) {
2575
+ case "attachment": {
2576
+ if (!isAttachmentDescriptor(value))
2577
+ violations.push({ path, rule: "invalid-attachment" });
2578
+ return;
2579
+ }
2580
+ case "null": {
2581
+ if (value !== null) {
2582
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2583
+ }
2584
+ return;
2585
+ }
2586
+ case "boolean": {
2587
+ if (typeof value !== "boolean") {
2588
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2589
+ }
2590
+ return;
2591
+ }
2592
+ case "string":
2593
+ case "person": {
2594
+ if (typeof value !== "string") {
2595
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2596
+ }
2597
+ return;
2598
+ }
2599
+ case "datetime": {
2600
+ if (typeof value !== "string") {
2601
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2602
+ } else if (normaliseDatetime(value) === void 0) {
2603
+ violations.push({ path, rule: RULE_INVALID_DATETIME });
2604
+ }
2605
+ return;
2606
+ }
2607
+ case "number": {
2608
+ if (typeof value !== "number" || !Number.isFinite(value)) {
2609
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2610
+ }
2611
+ return;
2612
+ }
2613
+ case "integer": {
2614
+ if (typeof value !== "number" || !Number.isInteger(value)) {
2615
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2616
+ }
2617
+ return;
2618
+ }
2619
+ case "enum": {
2620
+ if (!schema.members.includes(value)) {
2621
+ violations.push({ path, rule: RULE_ENUM_VIOLATION });
2622
+ }
2623
+ return;
2624
+ }
2625
+ case "array": {
2626
+ if (!Array.isArray(value)) {
2627
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2628
+ return;
2629
+ }
2630
+ if (value.length > schema.maxItems) {
2631
+ violations.push({ path, rule: RULE_ARRAY_BOUND_EXCEEDED });
2632
+ }
2633
+ value.forEach((item, index) => {
2634
+ walk(schema.items, item, [...path, String(index)], violations);
2635
+ });
2636
+ return;
2637
+ }
2638
+ case "object": {
2639
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
2640
+ violations.push({ path, rule: RULE_TYPE_MISMATCH });
2641
+ return;
2642
+ }
2643
+ const record = value;
2644
+ for (const key of schema.required) {
2645
+ if (!Object.prototype.hasOwnProperty.call(record, key)) {
2646
+ violations.push({ path: [...path, key], rule: RULE_MISSING_REQUIRED_PROPERTY });
2647
+ }
2648
+ }
2649
+ for (const key of Object.keys(record)) {
2650
+ if (!Object.prototype.hasOwnProperty.call(schema.properties, key)) {
2651
+ violations.push({ path: [...path, key], rule: RULE_UNDECLARED_PROPERTY });
2652
+ continue;
2653
+ }
2654
+ walk(schema.properties[key], record[key], [...path, key], violations);
2655
+ }
2656
+ return;
2657
+ }
2658
+ }
2659
+ }
2660
+ function isAttachmentDescriptor(value) {
2661
+ if (typeof value !== "object" || value === null || Array.isArray(value) || !("sha256" in value) || !("name" in value) || !("mediaType" in value) || !("bytes" in value))
2662
+ return false;
2663
+ if (Object.keys(value).length !== 4 || !["sha256", "name", "mediaType", "bytes"].every((key) => Object.hasOwn(value, key)) || typeof value.sha256 !== "string" || value.sha256.length !== 64 || !/^[a-f0-9]{64}$/.test(value.sha256) || typeof value.name !== "string" || value.name.length < 1 || value.name.length > 255 || value.name.startsWith(".") || hasForbiddenNameCharacter(value.name) || typeof value.mediaType !== "string" || typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes <= 0 || value.bytes > 26214400)
2664
+ return false;
2665
+ const name = value.name.toLowerCase();
2666
+ return Object.values(ATTACHMENT_CLASSES).some((formats) => formats.some((format) => format.mediaType === value.mediaType && format.extensions.some((extension) => name.endsWith(extension))));
2667
+ }
2668
+ function hasForbiddenNameCharacter(name) {
2669
+ for (let index = 0; index < name.length; index++) {
2670
+ const code = name.charCodeAt(index);
2671
+ if (name[index] === "/" || name[index] === "\\" || code < 32 || code >= 127 && code <= 159)
2672
+ return true;
2673
+ }
2674
+ return false;
2675
+ }
2676
+
2677
+ // packages/schema-language/dist/language-version.js
2678
+ var KINDS_VERSION_1 = Object.freeze(["null", "boolean", "string", "number", "integer", "person", "enum", "array", "object"]);
2679
+ var KINDS_VERSION_2 = Object.freeze([...KINDS_VERSION_1, "datetime"]);
2680
+ var KINDS_VERSION_3 = Object.freeze([...KINDS_VERSION_2, "attachment"]);
2681
+ var KINDS_BY_LANGUAGE_VERSION = /* @__PURE__ */ new Map([
2682
+ ["1", KINDS_VERSION_1],
2683
+ ["2", KINDS_VERSION_2],
2684
+ ["3", KINDS_VERSION_3]
2685
+ ]);
2686
+ function schemaKindsFor(languageVersion) {
2687
+ return KINDS_BY_LANGUAGE_VERSION.get(languageVersion);
2688
+ }
2689
+
2690
+ // packages/schema-language/dist/canonical-json.js
2691
+ function canonicalJson(value) {
2692
+ return JSON.stringify(sortKeys(value, /* @__PURE__ */ new Set()));
2693
+ }
2694
+ function utf8ByteLength(text) {
2695
+ return new TextEncoder().encode(text).length;
2696
+ }
2697
+ function sortKeys(value, ancestors) {
2698
+ if (Array.isArray(value)) {
2699
+ if (ancestors.has(value)) {
2700
+ return null;
2701
+ }
2702
+ ancestors.add(value);
2703
+ const sorted = value.map((item) => sortKeys(item, ancestors));
2704
+ ancestors.delete(value);
2705
+ return sorted;
2706
+ }
2707
+ if (value !== null && typeof value === "object") {
2708
+ if (ancestors.has(value)) {
2709
+ return null;
2710
+ }
2711
+ ancestors.add(value);
2712
+ const sorted = {};
2713
+ for (const key of Object.keys(value).sort()) {
2714
+ sorted[key] = sortKeys(value[key], ancestors);
2715
+ }
2716
+ ancestors.delete(value);
2717
+ return sorted;
2718
+ }
2719
+ return value;
2720
+ }
2721
+
2722
+ // packages/schema-language/dist/identifiers.js
2723
+ function normaliseIdentifier(value) {
2724
+ return value.normalize("NFC").toLowerCase();
2725
+ }
2726
+ var PROTOTYPE_AFFECTING_KEYS = ["__proto__", "constructor", "prototype"];
2727
+
2728
+ // packages/schema-language/dist/limits.js
2729
+ var LIMITS_VERSION_1 = {
2730
+ maxDocumentBytes: 65536,
2731
+ maxDepth: 8,
2732
+ maxPropertiesPerObject: 256,
2733
+ maxArrayItems: 1024,
2734
+ maxIdentifierLength: 64
2735
+ };
2736
+ var LIMITS_BY_LANGUAGE_VERSION = /* @__PURE__ */ new Map([
2737
+ ["1", LIMITS_VERSION_1],
2738
+ ["2", LIMITS_VERSION_1],
2739
+ ["3", LIMITS_VERSION_1]
2740
+ ]);
2741
+ function limitsForLanguageVersion(languageVersion) {
2742
+ return LIMITS_BY_LANGUAGE_VERSION.get(languageVersion);
2743
+ }
2744
+
2094
2745
  // packages/schema-language/dist/validate-schema.js
2095
- var SCHEMA_KINDS = Object.freeze(["null", "boolean", "string", "number", "integer", "person", "enum", "array", "object"]);
2096
- var VALID_KINDS = new Set(SCHEMA_KINDS);
2746
+ var RULE_UNKNOWN_LANGUAGE_VERSION = "unknown-language-version";
2747
+ var RULE_SIZE = "size-limit";
2748
+ var RULE_DEPTH = "depth-limit";
2749
+ var RULE_FIELD_COUNT = "field-count-limit";
2750
+ var RULE_ARRAY_BOUND = "array-bound-limit";
2751
+ var RULE_IDENTIFIER_LENGTH = "identifier-length-limit";
2752
+ var RULE_PROTOTYPE_KEY = "prototype-key";
2753
+ var RULE_COLLISION = "identifier-collision";
2754
+ var RULE_RECURSIVE = "recursive-reference";
2755
+ var RULE_UNKNOWN_KIND = "unknown-kind";
2756
+ var RULE_MALFORMED_SCHEMA = "malformed-schema";
2757
+ var RULE_UNDECLARED_REQUIRED_KEY = "undeclared-required-key";
2758
+ function validateSchema(schema, languageVersion, category) {
2759
+ const limits = limitsForLanguageVersion(languageVersion);
2760
+ const kinds = schemaKindsFor(languageVersion);
2761
+ if (limits === void 0 || kinds === void 0) {
2762
+ return { ok: false, violations: [{ path: [], rule: RULE_UNKNOWN_LANGUAGE_VERSION }] };
2763
+ }
2764
+ if (typeof schema !== "object" || schema === null || Array.isArray(schema)) {
2765
+ return { ok: false, violations: [{ path: [], rule: RULE_MALFORMED_SCHEMA }] };
2766
+ }
2767
+ const sizeBytes = utf8ByteLength(canonicalJson(schema));
2768
+ if (sizeBytes > limits.maxDocumentBytes) {
2769
+ return { ok: false, violations: [{ path: [], rule: RULE_SIZE }] };
2770
+ }
2771
+ const violations = [];
2772
+ walk2(schema, [], 1, /* @__PURE__ */ new Set(), limits, kinds, category, violations);
2773
+ return violations.length === 0 ? { ok: true, schema } : { ok: false, violations };
2774
+ }
2775
+ function walk2(node, path, depth, ancestors, limits, kinds, category, violations) {
2776
+ if (ancestors.has(node)) {
2777
+ violations.push({ path, rule: RULE_RECURSIVE });
2778
+ return;
2779
+ }
2780
+ if (depth > limits.maxDepth) {
2781
+ violations.push({ path, rule: RULE_DEPTH });
2782
+ return;
2783
+ }
2784
+ if (typeof node !== "object" || node === null || Array.isArray(node)) {
2785
+ violations.push({ path, rule: RULE_MALFORMED_SCHEMA });
2786
+ return;
2787
+ }
2788
+ const record = node;
2789
+ const kind = record.kind;
2790
+ if (typeof kind !== "string" || !kinds.includes(kind)) {
2791
+ violations.push({ path, rule: RULE_UNKNOWN_KIND, allowed: kinds });
2792
+ return;
2793
+ }
2794
+ ancestors.add(node);
2795
+ try {
2796
+ if (kind === "attachment") {
2797
+ if (category !== "object" || path.length !== 2 || path[0] !== "properties") {
2798
+ violations.push({ path, rule: "attachment-position" });
2799
+ }
2800
+ if (!Array.isArray(record.accept) || record.accept.length === 0 || record.accept.some((entry2) => typeof entry2 !== "string" || !Object.hasOwn(ATTACHMENT_CLASSES, entry2))) {
2801
+ violations.push({ path, rule: RULE_MALFORMED_SCHEMA });
2802
+ }
2803
+ return;
2804
+ }
2805
+ if (kind === "object") {
2806
+ const properties = record.properties;
2807
+ if (typeof properties !== "object" || properties === null || Array.isArray(properties)) {
2808
+ violations.push({ path, rule: RULE_MALFORMED_SCHEMA });
2809
+ return;
2810
+ }
2811
+ if (!Array.isArray(record.required) || !record.required.every((key) => typeof key === "string")) {
2812
+ violations.push({ path, rule: RULE_MALFORMED_SCHEMA });
2813
+ return;
2814
+ }
2815
+ const propertyRecord = properties;
2816
+ const keys = Object.keys(propertyRecord);
2817
+ if (keys.length > limits.maxPropertiesPerObject) {
2818
+ violations.push({ path, rule: RULE_FIELD_COUNT });
2819
+ }
2820
+ checkIdentifiers(keys, path, limits, violations);
2821
+ for (const requiredKey of record.required) {
2822
+ if (!keys.includes(requiredKey)) {
2823
+ violations.push({ path: [...path, requiredKey], rule: RULE_UNDECLARED_REQUIRED_KEY });
2824
+ }
2825
+ }
2826
+ for (const key of keys) {
2827
+ walk2(propertyRecord[key], [...path, "properties", key], depth + 1, ancestors, limits, kinds, category, violations);
2828
+ }
2829
+ return;
2830
+ }
2831
+ if (kind === "array") {
2832
+ if (typeof record.maxItems !== "number" || !Number.isFinite(record.maxItems)) {
2833
+ violations.push({ path, rule: RULE_MALFORMED_SCHEMA });
2834
+ return;
2835
+ }
2836
+ if (record.maxItems > limits.maxArrayItems) {
2837
+ violations.push({ path, rule: RULE_ARRAY_BOUND });
2838
+ }
2839
+ walk2(record.items, [...path, "items"], depth + 1, ancestors, limits, kinds, category, violations);
2840
+ return;
2841
+ }
2842
+ if (kind === "enum") {
2843
+ if (!Array.isArray(record.members) || !record.members.every((member) => typeof member === "string" || typeof member === "number" && Number.isFinite(member))) {
2844
+ violations.push({ path, rule: RULE_MALFORMED_SCHEMA });
2845
+ return;
2846
+ }
2847
+ const stringMembers = record.members.filter((member) => typeof member === "string");
2848
+ checkIdentifiers(stringMembers, [...path, "members"], limits, violations);
2849
+ return;
2850
+ }
2851
+ } finally {
2852
+ ancestors.delete(node);
2853
+ }
2854
+ }
2855
+ function checkIdentifiers(names, path, limits, violations) {
2856
+ const byNormalised = /* @__PURE__ */ new Map();
2857
+ for (const name of names) {
2858
+ if (name.length > limits.maxIdentifierLength) {
2859
+ violations.push({ path: [...path, name], rule: RULE_IDENTIFIER_LENGTH });
2860
+ }
2861
+ if (PROTOTYPE_AFFECTING_KEYS.includes(name)) {
2862
+ violations.push({ path: [...path, name], rule: RULE_PROTOTYPE_KEY });
2863
+ }
2864
+ const normalised = normaliseIdentifier(name);
2865
+ const group = byNormalised.get(normalised);
2866
+ if (group) {
2867
+ group.push(name);
2868
+ } else {
2869
+ byNormalised.set(normalised, [name]);
2870
+ }
2871
+ }
2872
+ for (const group of byNormalised.values()) {
2873
+ if (group.length > 1) {
2874
+ for (const name of group) {
2875
+ violations.push({ path: [...path, name], rule: RULE_COLLISION });
2876
+ }
2877
+ }
2878
+ }
2879
+ }
2880
+
2881
+ // packages/schema-language/dist/object-schema.js
2882
+ function objectSchemaOf(propertyDefinitions, requiredPropertyKeys) {
2883
+ return { kind: "object", properties: propertyDefinitions, required: requiredPropertyKeys };
2884
+ }
2097
2885
 
2098
2886
  // packages/schema-language/dist/view-catalogue.js
2099
2887
  var MAX_ELEMENT_CHILDREN = 100;
@@ -2185,10 +2973,42 @@ var VIEW_CATALOGUE = deepFreeze2({
2185
2973
  views: ["object"],
2186
2974
  role: "leaf",
2187
2975
  props: {
2188
- property: { kind: "string", required: true, minLength: 1, maxLength: 64, propertyKey: true, error: "Unknown geometry property" },
2976
+ property: {
2977
+ kind: "string",
2978
+ required: true,
2979
+ minLength: 1,
2980
+ maxLength: 64,
2981
+ propertyKey: true,
2982
+ attachmentClass: "mesh",
2983
+ error: "Unknown geometry property"
2984
+ },
2189
2985
  label: { kind: "string", minLength: 1, maxLength: 160, error: "Invalid geometry label" }
2190
2986
  }
2191
2987
  },
2988
+ ImageViewer: {
2989
+ views: ["object"],
2990
+ role: "leaf",
2991
+ props: {
2992
+ property: { kind: "string", required: true, minLength: 1, maxLength: 64, propertyKey: true, attachmentClass: "image", error: "Unknown image property" },
2993
+ alt: { kind: "string", required: true, minLength: 1, maxLength: 500, error: "Invalid alternative text" }
2994
+ }
2995
+ },
2996
+ PdfViewer: {
2997
+ views: ["object"],
2998
+ role: "leaf",
2999
+ props: {
3000
+ property: {
3001
+ kind: "string",
3002
+ required: true,
3003
+ minLength: 1,
3004
+ maxLength: 64,
3005
+ propertyKey: true,
3006
+ attachmentClass: "pdf",
3007
+ error: "Unknown PDF property"
3008
+ },
3009
+ label: { kind: "string", minLength: 1, maxLength: 160, error: "Invalid PDF label" }
3010
+ }
3011
+ },
2192
3012
  AppBody: {
2193
3013
  views: ["app", "page"],
2194
3014
  role: "container",
@@ -2284,11 +3104,22 @@ var VIEW_CATALOGUE = deepFreeze2({
2284
3104
  Stat: {
2285
3105
  views: ["object", "app", "page"],
2286
3106
  role: "leaf",
3107
+ exactlyOneOf: { props: ["value", "aggregate"], error: "Invalid stat source" },
2287
3108
  props: {
2288
3109
  label: { kind: "string", required: true, minLength: 1, maxLength: 160, error: "Invalid stat label" },
2289
- value: { kind: "scalar", required: true, maxLength: 160, bindable: "read", error: "Invalid stat value" },
3110
+ value: { kind: "scalar", maxLength: 160, bindable: "read", error: "Invalid stat value" },
2290
3111
  unit: { kind: "string", minLength: 1, maxLength: 32, error: "Invalid unit" },
2291
- query: { kind: "string", minLength: 1, maxLength: 64, part: true, error: "Unknown query part" }
3112
+ query: { kind: "string", minLength: 1, maxLength: 64, part: true, error: "Unknown query part" },
3113
+ aggregate: { kind: "string", views: ["object", "app"], minLength: 1, maxLength: 64, aggregatePart: true, error: "Unknown aggregate part" }
3114
+ }
3115
+ },
3116
+ Aggregate: {
3117
+ views: ["object", "app"],
3118
+ role: "leaf",
3119
+ props: {
3120
+ reach: { kind: "json", required: true, error: "Invalid aggregate reach" },
3121
+ measure: { kind: "json", required: true, error: "Invalid aggregate measure" },
3122
+ ends: { kind: "choice", required: true, values: ["visible", "all"], error: "Invalid aggregate ends" }
2292
3123
  }
2293
3124
  },
2294
3125
  Link: {
@@ -2481,6 +3312,26 @@ var VERB_TEMPLATE = deepFreeze3({
2481
3312
  }
2482
3313
  });
2483
3314
 
3315
+ // packages/objects-sdk/dist/validation.js
3316
+ function validateLocally(schema, languageVersion, value, category) {
3317
+ const checked = validateSchema(schema, languageVersion, category);
3318
+ return checked.ok ? validateValue(checked.schema, value) : { ok: false, violations: checked.violations };
3319
+ }
3320
+ function checkSampleAgainstChanges(changes, typeKey, sample) {
3321
+ const entries6 = entryChangesOf(changes);
3322
+ const document = Object.hasOwn(entries6, typeKey) ? entries6[typeKey] : void 0;
3323
+ if (document === void 0) {
3324
+ return { kind: "no-such-type" };
3325
+ }
3326
+ if (document.typeCategory === "verb") {
3327
+ return { kind: "no-properties" };
3328
+ }
3329
+ return {
3330
+ kind: "checked",
3331
+ result: validateLocally(objectSchemaOf(document.propertyDefinitions, document.requiredPropertyKeys), document.schemaLanguageVersion, sample, document.typeCategory)
3332
+ };
3333
+ }
3334
+
2484
3335
  // packages/ontology-sdk/dist/type-delta.js
2485
3336
  var NOT_COMPARED = /* @__PURE__ */ new Set(["typeCategory", "typeKey", "version"]);
2486
3337
  function isRecord(value) {
@@ -2708,6 +3559,7 @@ var exitCodeOfRefusal = (refusal2) => {
2708
3559
 
2709
3560
  // packages/cli/src/generated/help.ts
2710
3561
  function schemasOf(entry2) {
3562
+ if (isBinaryRequestRoute(entry2.name)) throw new Error("this route takes a binary request body and has no JSON input schema");
2711
3563
  return { input: ROUTE_INPUT_SCHEMAS[entry2.name], selector: entry2.selector === "none" ? null : SELECTOR_SCHEMAS[entry2.selector] };
2712
3564
  }
2713
3565
  var DEFS_PREFIX = "#/$defs/";
@@ -2783,9 +3635,9 @@ function resolveField(field, schemas, sent) {
2783
3635
  if (schema === null) {
2784
3636
  return null;
2785
3637
  }
2786
- let node = deref(schema, rootSchema);
2787
- if (node.oneOf !== void 0) {
2788
- const members2 = kindMembers(node, rootSchema);
3638
+ let node2 = deref(schema, rootSchema);
3639
+ if (node2.oneOf !== void 0) {
3640
+ const members2 = kindMembers(node2, rootSchema);
2789
3641
  const discriminator2 = members2?.[0]?.discriminator;
2790
3642
  if (discriminator2 !== void 0 && key === discriminator2) {
2791
3643
  return { allowedKinds: members2?.map((candidate) => candidate.kind) ?? [], discriminator: discriminator2 };
@@ -2795,24 +3647,24 @@ function resolveField(field, schemas, sent) {
2795
3647
  if (chosen === void 0) {
2796
3648
  return null;
2797
3649
  }
2798
- node = chosen.member;
3650
+ node2 = chosen.member;
2799
3651
  }
2800
- if (node.type === "array") {
2801
- if (node.items === void 0 || !Array.isArray(value) || !/^(0|[1-9]\d*)$/.test(key) || Number(key) >= value.length) {
3652
+ if (node2.type === "array") {
3653
+ if (node2.items === void 0 || !Array.isArray(value) || !/^(0|[1-9]\d*)$/.test(key) || Number(key) >= value.length) {
2802
3654
  return null;
2803
3655
  }
2804
- schema = node.items;
3656
+ schema = node2.items;
2805
3657
  value = value[Number(key)];
2806
3658
  continue;
2807
3659
  }
2808
- const property = node.properties?.[key];
3660
+ const property = node2.properties?.[key];
2809
3661
  if (property !== void 0) {
2810
3662
  schema = property;
2811
- } else if (typeof node.additionalProperties === "object") {
3663
+ } else if (typeof node2.additionalProperties === "object") {
2812
3664
  if (isRecord2(value) && Object.keys(value).some((name) => name.includes("."))) {
2813
3665
  return null;
2814
3666
  }
2815
- schema = node.additionalProperties;
3667
+ schema = node2.additionalProperties;
2816
3668
  } else {
2817
3669
  return null;
2818
3670
  }
@@ -2823,7 +3675,13 @@ function resolveField(field, schemas, sent) {
2823
3675
  }
2824
3676
  const members = kindMembers(schema, rootSchema);
2825
3677
  const discriminator = members?.[0]?.discriminator;
2826
- return { allowedKinds: members?.map((candidate) => candidate.kind) ?? [], ...discriminator === void 0 ? {} : { discriminator } };
3678
+ const node = deref(schema, rootSchema);
3679
+ const allowedValues = node.enum ?? (node.const === void 0 ? [] : [node.const]);
3680
+ return {
3681
+ allowedKinds: members?.map((candidate) => candidate.kind) ?? [],
3682
+ ...allowedValues.length === 0 ? {} : { allowedValues },
3683
+ ...discriminator === void 0 ? {} : { discriminator }
3684
+ };
2827
3685
  }
2828
3686
  var CORRELATION_FIELD = "correlation";
2829
3687
  var DEPTH_LIMIT = 3;
@@ -2942,6 +3800,14 @@ function withoutCorrelation(example) {
2942
3800
  return isRecord2(example) ? Object.fromEntries(Object.entries(example).filter(([name]) => name !== CORRELATION_FIELD)) : example;
2943
3801
  }
2944
3802
  function schemaHelpLines(entry2) {
3803
+ if (isBinaryRequestRoute(entry2.name)) {
3804
+ const binary = BINARY_REQUEST_INPUTS[entry2.name];
3805
+ return [
3806
+ `content-type: ${binary.contentType}`,
3807
+ `${binary.selectorHeader}: selector as JSON text`,
3808
+ `${binary.nameHeader}: attachment name as an RFC 8187 ext-value`
3809
+ ];
3810
+ }
2945
3811
  const schemas = schemasOf(entry2);
2946
3812
  const input = fieldLines(schemas.input, schemas.input, " ");
2947
3813
  const lines = ["input fields:", ...input.length === 0 ? [" none"] : input];
@@ -3011,12 +3877,75 @@ function explanationLines(heading, explanation) {
3011
3877
  }
3012
3878
  return lines;
3013
3879
  }
3880
+ function displayExplanationOf(rule, explanation, merge = false) {
3881
+ if (rule === "merge-not-permitted" || merge && (rule === "not-permitted" || rule === "capability-missing")) {
3882
+ return {
3883
+ explains: explanation.explains,
3884
+ explanation: {
3885
+ meaning: `${explanation.explanation.meaning} The merge requires the \`branches.merge\` capability in the target scope.`,
3886
+ next: explanation.explanation.next
3887
+ }
3888
+ };
3889
+ }
3890
+ if (rule === "merge-conflict") {
3891
+ return {
3892
+ explains: explanation.explains,
3893
+ explanation: {
3894
+ meaning: "The merge found changes both branches made from their common base.",
3895
+ next: [{ option: "Read the conflict fields with readMergeConflicts, setting input.name to the source branch's name." }]
3896
+ }
3897
+ };
3898
+ }
3899
+ return rule === "not-a-ref-head" ? {
3900
+ explains: "rule",
3901
+ explanation: {
3902
+ meaning: "This branch has new commits since this review began.",
3903
+ next: [{ option: "Reload the proposal to review its latest commit." }]
3904
+ }
3905
+ } : explanation;
3906
+ }
3907
+ function branchNameRule(request3) {
3908
+ const input = request3.sent.input;
3909
+ const name = typeof input === "object" && input !== null && !Array.isArray(input) ? input.name : void 0;
3910
+ if (typeof name !== "string") {
3911
+ return "The branch name must be a string containing one ref segment.";
3912
+ }
3913
+ if (name.includes("/")) {
3914
+ return "The branch name must be one ref segment and cannot contain a slash.";
3915
+ }
3916
+ if (!/^[A-Za-z0-9._-]+$/.test(name)) {
3917
+ return "A ref segment uses only ASCII letters, digits, dot, underscore and hyphen.";
3918
+ }
3919
+ if (name.startsWith(".")) {
3920
+ return "A ref segment cannot start with a dot.";
3921
+ }
3922
+ if (name.endsWith(".")) {
3923
+ return "A ref segment cannot end with a dot.";
3924
+ }
3925
+ if (name.endsWith(".lock")) {
3926
+ return "A ref segment cannot end in .lock.";
3927
+ }
3928
+ if (name.includes("..")) {
3929
+ return "A ref segment cannot contain two consecutive dots.";
3930
+ }
3931
+ return "The branch name must fit the database's UTF-8 byte binding limit.";
3932
+ }
3014
3933
  function refusalLines(refusal2, settle2, request3, host, reference) {
3015
- const lines = explanationLines(refusalHeading(refusal2), refusal2);
3934
+ const lines = explanationLines(refusalHeading(refusal2), displayExplanationOf(refusal2.kind === "refused" ? refusal2.rule : void 0, refusal2, request3?.command === "openeng branches-sdk merge"));
3935
+ if (refusal2.kind === "refused" && refusal2.rule === "owned-type-not-presentation" && refusal2.detail !== void 0) {
3936
+ lines.push(`type: ${refusal2.detail.typeKey}; field: ${refusal2.detail.field}`);
3937
+ }
3016
3938
  const allowed = allowedFieldOf(refusal2, request3);
3939
+ const allowedValues = allowed?.allowedValues ?? [];
3017
3940
  if (request3 !== void 0 && allowed !== null && allowed.allowedKinds.length > 0 && allowed.discriminator !== void 0) {
3018
3941
  lines.push(`allowed ${allowed.discriminator}: ${allowed.allowedKinds.join(", ")}`, `${request3.command} --help shows each shape`);
3019
3942
  }
3943
+ if (request3 !== void 0 && allowedValues.length > 0) {
3944
+ lines.push(`allowed values: ${allowedValues.map((value) => JSON.stringify(value)).join(", ")}`);
3945
+ }
3946
+ if (request3?.command === "openeng branches-sdk createBranch" && refusal2.kind === "invalid-request" && refusal2.field === "input.name") {
3947
+ lines.push(`Branch name rule: ${branchNameRule(request3)}`);
3948
+ }
3020
3949
  if (refusal2.kind === "unknown-outcome") {
3021
3950
  lines.push(`The operation may or may not have taken effect, and openeng will not repeat it. Settle it with: ${settle2}`);
3022
3951
  }
@@ -3029,6 +3958,9 @@ function refusalLines(refusal2, settle2, request3, host, reference) {
3029
3958
  lines.push(`${versions}; the host did not read this CLI's protocol version (read: ${read})`);
3030
3959
  }
3031
3960
  }
3961
+ if (refusal2.kind === "protocol-mismatch") {
3962
+ lines.push("Update with: npm install -g @openengio/cli@latest");
3963
+ }
3032
3964
  if (reference !== void 0) {
3033
3965
  lines.push(`reference: ${reference}`);
3034
3966
  }
@@ -3037,11 +3969,20 @@ function refusalLines(refusal2, settle2, request3, host, reference) {
3037
3969
  function refusalValue(refusal2, settle2, request3, host, reference) {
3038
3970
  const referenced = reference === void 0 ? {} : { reference };
3039
3971
  if (refusal2.kind === "protocol-mismatch") {
3040
- return { ...refusal2, clientVersion: PROTOCOL_VERSION, ...host === void 0 ? {} : { host }, ...referenced };
3972
+ return { ...refusal2, clientVersion: PROTOCOL_VERSION, update: "npm install -g @openengio/cli@latest", ...host === void 0 ? {} : { host }, ...referenced };
3041
3973
  }
3042
3974
  const allowed = allowedFieldOf(refusal2, request3);
3043
3975
  const settled = refusal2.kind === "unknown-outcome" ? { ...refusal2, settle: settle2 } : refusal2;
3044
- return allowed === null || allowed.allowedKinds.length === 0 ? { ...settled, ...referenced } : { ...settled, allowedKinds: allowed.allowedKinds, ...referenced };
3976
+ const explained = refusal2.kind === "refused" ? { ...settled, ...displayExplanationOf(refusal2.rule, refusal2, request3?.command === "openeng branches-sdk merge") } : settled;
3977
+ if (allowed === null) {
3978
+ return { ...explained, ...referenced };
3979
+ }
3980
+ return {
3981
+ ...explained,
3982
+ ...allowed.allowedKinds.length === 0 ? {} : { allowedKinds: allowed.allowedKinds },
3983
+ ...(allowed.allowedValues?.length ?? 0) === 0 ? {} : { allowedValues: allowed.allowedValues },
3984
+ ...referenced
3985
+ };
3045
3986
  }
3046
3987
  function jsonLine(value) {
3047
3988
  return `${JSON.stringify(value)}
@@ -3106,10 +4047,11 @@ var render = (outcome, json, scope, host) => {
3106
4047
  const result = outcome.result;
3107
4048
  const resultReference = typeof result.correlationId === "string" ? result.correlationId : void 0;
3108
4049
  if (json) {
3109
- const referenced = resultReference === void 0 ? result : { ...result, reference: resultReference };
4050
+ const explained = { ...result, ...displayExplanationOf(result.rule, result, result.rule === "merge-not-permitted") };
4051
+ const referenced = resultReference === void 0 ? explained : { ...explained, reference: resultReference };
3110
4052
  return { exitCode, stdout: jsonLine(scopedValue(referenced, scope)), stderr: echo };
3111
4053
  }
3112
- const lines = explanationLines(`refused: ${typeof result.rule === "string" ? result.rule : "no rule named"}`, result);
4054
+ const lines = explanationLines(`refused: ${typeof result.rule === "string" ? result.rule : "no rule named"}`, displayExplanationOf(result.rule, result, result.rule === "merge-not-permitted"));
3113
4055
  for (const conflict of result.conflicts ?? []) {
3114
4056
  lines.push(`conflict: ${conflict.property}; current: ${conflict.current === null ? "absent" : JSON.stringify(conflict.current)}`);
3115
4057
  }
@@ -3375,27 +4317,61 @@ function quotedForSecurity(text) {
3375
4317
  function failureOf(store, operation, command, result) {
3376
4318
  return new SessionStoreError(store, operation, `${command} exited ${String(result.exitCode)} and wrote ${String(result.stderr.length)} characters to its standard error`);
3377
4319
  }
4320
+ var KEYCHAIN_ENCODING = "openeng-session:v1:";
4321
+ function keychainTextOf(text) {
4322
+ let bytes;
4323
+ if (text.startsWith(KEYCHAIN_ENCODING)) {
4324
+ const encoded = text.slice(KEYCHAIN_ENCODING.length);
4325
+ bytes = Buffer.from(encoded, "base64");
4326
+ if (bytes.toString("base64") !== encoded) {
4327
+ throw new SessionStoreError("macos-keychain", "read", "the stored entry is not canonical base64");
4328
+ }
4329
+ } else if (/^(?:[0-9a-fA-F]{2})+$/.test(text)) {
4330
+ bytes = Buffer.from(text, "hex");
4331
+ } else {
4332
+ return text;
4333
+ }
4334
+ const decoded = bytes.toString("utf8");
4335
+ if (!Buffer.from(decoded, "utf8").equals(bytes)) {
4336
+ throw new SessionStoreError("macos-keychain", "read", "the stored entry is not UTF-8");
4337
+ }
4338
+ return decoded;
4339
+ }
4340
+ function keychainOutputOf(result) {
4341
+ return result.stdout.endsWith("\n") ? result.stdout.slice(0, -1) : result.stdout;
4342
+ }
4343
+ function keychainReadRequest(hostKey) {
4344
+ return { command: SECURITY, args: ["find-generic-password", "-a", hostKey, "-s", SERVICE, "-w"], stdin: "" };
4345
+ }
3378
4346
  function macosStore(spawn2) {
3379
4347
  const kind = "macos-keychain";
3380
4348
  return {
3381
4349
  kind,
3382
4350
  async read(hostKey) {
3383
- const result = await spawn2({ command: SECURITY, args: ["find-generic-password", "-a", hostKey, "-s", SERVICE, "-w"], stdin: "" });
4351
+ const result = await spawn2(keychainReadRequest(hostKey));
3384
4352
  if (result.exitCode === SECURITY_NOT_FOUND) {
3385
4353
  return null;
3386
4354
  }
3387
4355
  if (result.exitCode !== 0) {
3388
4356
  throw failureOf(kind, "read", "security", result);
3389
4357
  }
3390
- return entryOf(kind, hostKey, result.stdout.endsWith("\n") ? result.stdout.slice(0, -1) : result.stdout);
4358
+ return entryOf(kind, hostKey, keychainTextOf(keychainOutputOf(result)));
3391
4359
  },
3392
4360
  async write(hostKey, session, organisation) {
3393
- const command = ["add-generic-password", "-U", "-a", quotedForSecurity(hostKey), "-s", SERVICE, "-w", quotedForSecurity(secretOf(hostKey, session, organisation))].join(" ");
4361
+ const secret = KEYCHAIN_ENCODING + Buffer.from(secretOf(hostKey, session, organisation), "utf8").toString("base64");
4362
+ const command = ["add-generic-password", "-U", "-a", quotedForSecurity(hostKey), "-s", SERVICE, "-w", quotedForSecurity(secret)].join(" ");
3394
4363
  const result = await spawn2({ command: SECURITY, args: ["-i"], stdin: `${command}
3395
4364
  ` });
3396
4365
  if (result.exitCode !== 0 || result.stderr !== "") {
3397
4366
  throw failureOf(kind, "write", "security -i", result);
3398
4367
  }
4368
+ const stored = await spawn2(keychainReadRequest(hostKey));
4369
+ if (stored.exitCode !== 0 || stored.stderr !== "") {
4370
+ throw failureOf(kind, "write", "security read-back", stored);
4371
+ }
4372
+ if (keychainOutputOf(stored) !== secret) {
4373
+ throw new SessionStoreError(kind, "write", "the keychain did not retain the written entry");
4374
+ }
3399
4375
  },
3400
4376
  async delete(hostKey) {
3401
4377
  const result = await spawn2({ command: SECURITY, args: ["delete-generic-password", "-a", hostKey, "-s", SERVICE], stdin: "" });
@@ -3464,11 +4440,11 @@ var createFileStore = (configDirectory) => {
3464
4440
  try {
3465
4441
  mkdirSync(directory, { recursive: true, mode: 448 });
3466
4442
  chmodSync(directory, 448);
3467
- const descriptor = openSync(temporary, "wx", 384);
4443
+ const descriptor2 = openSync(temporary, "wx", 384);
3468
4444
  try {
3469
- writeSync(descriptor, secretOf(hostKey, session, organisation));
4445
+ writeSync(descriptor2, secretOf(hostKey, session, organisation));
3470
4446
  } finally {
3471
- closeSync(descriptor);
4447
+ closeSync(descriptor2);
3472
4448
  }
3473
4449
  renameSync(temporary, final);
3474
4450
  } catch (error) {
@@ -3843,11 +4819,11 @@ async function takeLock(path, deps) {
3843
4819
  let unreadableSince = null;
3844
4820
  for (; ; ) {
3845
4821
  try {
3846
- const descriptor = openSync2(path, "wx", 384);
4822
+ const descriptor2 = openSync2(path, "wx", 384);
3847
4823
  try {
3848
- writeSync2(descriptor, text);
4824
+ writeSync2(descriptor2, text);
3849
4825
  } finally {
3850
- closeSync2(descriptor);
4826
+ closeSync2(descriptor2);
3851
4827
  }
3852
4828
  return () => {
3853
4829
  if (readLockText(path) === text) {
@@ -8573,6 +9549,8 @@ function choice(members) {
8573
9549
  }
8574
9550
  var REQUIREMENT_STATUSES = ["Draft", "In review", "Approved", "Baselined"];
8575
9551
  var REQUIREMENT_PRIORITIES = ["Must", "Should", "Could"];
9552
+ var REQUIREMENT_VERIFICATION_METHODS = ["Test", "Analysis", "Inspection", "Demonstration"];
9553
+ var REQUIREMENT_CATEGORIES = ["Performance", "Interface", "Safety", "Environmental", "Regulatory"];
8576
9554
  var SPECIFICATION_STATUSES = ["Draft", "In review", "Approved"];
8577
9555
  var VERIFICATION_STATUSES = ["Planned", "In progress", "Passed", "Failed"];
8578
9556
  var VERIFICATION_METHODS = ["Test", "Inspection", "Test and analysis", "Demonstration"];
@@ -8588,7 +9566,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8588
9566
  displayName: "System",
8589
9567
  propertyDefinitions: { identifier: STRING, name: STRING, owner: PERSON },
8590
9568
  requiredPropertyKeys: ["identifier", "name"],
8591
- presentationBindings: { title: "name", typeIcon: "account_tree" },
9569
+ presentationBindings: { title: "name", typeIcon: "account_tree", propertyOrder: ["identifier", "name", "owner"] },
8592
9570
  // A system's parent is the system it is contained by: contains' source is the parent, its
8593
9571
  // target the child, so a system resolves its own parent through the same edge type.
8594
9572
  structureDeclaration: { relationships: ["contains"] }
@@ -8596,9 +9574,20 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8596
9574
  {
8597
9575
  typeKey: "requirement",
8598
9576
  displayName: "Requirement",
8599
- propertyDefinitions: { identifier: STRING, statement: STRING, status: choice(REQUIREMENT_STATUSES), priority: choice(REQUIREMENT_PRIORITIES), owner: PERSON },
8600
- requiredPropertyKeys: ["identifier", "statement", "status", "priority"],
8601
- presentationBindings: { title: "statement", typeIcon: "assignment" },
9577
+ propertyDefinitions: {
9578
+ identifier: STRING,
9579
+ statement: STRING,
9580
+ status: choice(REQUIREMENT_STATUSES),
9581
+ priority: choice(REQUIREMENT_PRIORITIES),
9582
+ owner: PERSON,
9583
+ rationale: STRING,
9584
+ verificationMethod: choice(REQUIREMENT_VERIFICATION_METHODS),
9585
+ acceptanceCriteria: STRING,
9586
+ source: STRING,
9587
+ category: choice(REQUIREMENT_CATEGORIES)
9588
+ },
9589
+ requiredPropertyKeys: ["identifier", "statement", "status", "priority", "verificationMethod", "category"],
9590
+ presentationBindings: { title: "statement", typeIcon: "assignment", propertyOrder: ["identifier", "statement", "category", "status", "priority", "verificationMethod", "acceptanceCriteria", "rationale", "source", "owner"] },
8602
9591
  structureDeclaration: { relationships: ["has-requirement"] }
8603
9592
  },
8604
9593
  {
@@ -8606,7 +9595,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8606
9595
  displayName: "Specification",
8607
9596
  propertyDefinitions: { identifier: STRING, statement: STRING, status: choice(SPECIFICATION_STATUSES), owner: PERSON },
8608
9597
  requiredPropertyKeys: ["identifier", "statement", "status"],
8609
- presentationBindings: { title: "statement", typeIcon: "description" },
9598
+ presentationBindings: { title: "statement", typeIcon: "description", propertyOrder: ["identifier", "statement", "status", "owner"] },
8610
9599
  structureDeclaration: { relationships: ["has-specification"] }
8611
9600
  },
8612
9601
  {
@@ -8614,7 +9603,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8614
9603
  displayName: "Verification",
8615
9604
  propertyDefinitions: { identifier: STRING, statement: STRING, method: choice(VERIFICATION_METHODS), status: choice(VERIFICATION_STATUSES), owner: PERSON },
8616
9605
  requiredPropertyKeys: ["identifier", "statement", "method", "status"],
8617
- presentationBindings: { title: "statement", typeIcon: "fact_check" },
9606
+ presentationBindings: { title: "statement", typeIcon: "fact_check", propertyOrder: ["identifier", "statement", "method", "status", "owner"] },
8618
9607
  structureDeclaration: { relationships: ["has-verification"] }
8619
9608
  },
8620
9609
  {
@@ -8622,7 +9611,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8622
9611
  displayName: "Risk",
8623
9612
  propertyDefinitions: { identifier: STRING, statement: STRING, severity: choice(RISK_SEVERITIES), likelihood: choice(RISK_LIKELIHOODS), owner: PERSON },
8624
9613
  requiredPropertyKeys: ["identifier", "statement", "severity", "likelihood"],
8625
- presentationBindings: { title: "statement", typeIcon: "warning" },
9614
+ presentationBindings: { title: "statement", typeIcon: "warning", propertyOrder: ["identifier", "statement", "severity", "likelihood", "owner"] },
8626
9615
  structureDeclaration: { relationships: ["has-risk"] }
8627
9616
  },
8628
9617
  {
@@ -8639,7 +9628,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8639
9628
  cadReference: STRING
8640
9629
  },
8641
9630
  requiredPropertyKeys: ["identifier", "name", "makeOrBuy", "lifecycleState"],
8642
- presentationBindings: { title: "name", typeIcon: "precision_manufacturing" },
9631
+ presentationBindings: { title: "name", typeIcon: "precision_manufacturing", propertyOrder: ["identifier", "name", "makeOrBuy", "lifecycleState", "material", "mass", "cadReference", "owner"] },
8643
9632
  structureDeclaration: {
8644
9633
  relationships: ["has-part"],
8645
9634
  views: [
@@ -8653,7 +9642,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8653
9642
  displayName: "BOM line",
8654
9643
  propertyDefinitions: { reference: STRING, quantity: NUMBER, findNumber: NUMBER },
8655
9644
  requiredPropertyKeys: ["reference", "quantity", "findNumber"],
8656
- presentationBindings: { title: "reference", typeIcon: "format_list_numbered" },
9645
+ presentationBindings: { title: "reference", typeIcon: "format_list_numbered", propertyOrder: ["reference", "findNumber", "quantity"] },
8657
9646
  // A BOM line's parent is the part that itemises it: itemises' source is the assembly part
8658
9647
  // (parentEnd "source"), its target the BOM line, so a BOM line resolves its own parent
8659
9648
  // through the same edge type `system` resolves its own parent through, above.
@@ -8664,7 +9653,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8664
9653
  displayName: "Revision",
8665
9654
  propertyDefinitions: { name: STRING, code: STRING, state: choice(REVISION_STATES), changeNote: STRING },
8666
9655
  requiredPropertyKeys: ["name", "code", "state", "changeNote"],
8667
- presentationBindings: { title: "name", typeIcon: "history" },
9656
+ presentationBindings: { title: "name", typeIcon: "history", propertyOrder: ["name", "code", "state", "changeNote"] },
8668
9657
  structureDeclaration: { relationships: ["has-revision"] }
8669
9658
  },
8670
9659
  {
@@ -8672,7 +9661,7 @@ var DEMO_OBJECT_TYPES = Object.freeze([
8672
9661
  displayName: "Release",
8673
9662
  propertyDefinitions: { identifier: STRING, name: STRING, status: choice(RELEASE_STATUSES), effectiveFrom: STRING },
8674
9663
  requiredPropertyKeys: ["identifier", "name", "status"],
8675
- presentationBindings: { title: "name", typeIcon: "verified" },
9664
+ presentationBindings: { title: "name", typeIcon: "verified", propertyOrder: ["identifier", "name", "status", "effectiveFrom"] },
8676
9665
  structureDeclaration: { relationships: [] }
8677
9666
  }
8678
9667
  ]);
@@ -8765,7 +9754,12 @@ function fullWorld(size, owner, data) {
8765
9754
  statement: row.statement,
8766
9755
  status: rotate(REQUIREMENT_STATUSES, index),
8767
9756
  priority: rotate(REQUIREMENT_PRIORITIES, index),
8768
- owner
9757
+ owner,
9758
+ rationale: row.rationale,
9759
+ verificationMethod: row.verificationMethod,
9760
+ acceptanceCriteria: row.acceptanceCriteria,
9761
+ source: row.source,
9762
+ category: row.category
8769
9763
  }
8770
9764
  })),
8771
9765
  ...data.specifications.map((row, index) => ({
@@ -8914,31 +9908,31 @@ var SYSTEM_TREE = [
8914
9908
  { identifier: "BOP-WW", name: "Water Wash System", parent: "BOP" }
8915
9909
  ];
8916
9910
  var REQUIREMENTS = [
8917
- { identifier: "OCGT-REQ-001", statement: "The plant shall deliver a net electrical output of not less than 50 MW at ISO ambient conditions (15 \xB0C, 101.3 kPa, 60% relative humidity), measured at the high-voltage terminals of the step-up transformer.", derivesFrom: null, allocatedTo: "OCGT" },
8918
- { identifier: "OCGT-REQ-002", statement: "The net heat rate on natural gas, lower heating value basis, shall not exceed 10,800 kJ/kWh at ISO conditions and base load.", derivesFrom: null, allocatedTo: "OCGT" },
8919
- { identifier: "OCGT-REQ-003", statement: "The unit shall reach full load within 10 minutes of a start command from standstill.", derivesFrom: null, allocatedTo: "OCGT" },
8920
- { identifier: "OCGT-REQ-004", statement: "The unit shall sustain a load ramp rate of not less than 8 MW per minute between 40% and 100% load.", derivesFrom: null, allocatedTo: "OCGT" },
8921
- { identifier: "OCGT-REQ-005", statement: "Stack NOx shall not exceed 25 ppmvd corrected to 15% oxygen between 50% and 100% load on natural gas.", derivesFrom: null, allocatedTo: "OCGT" },
8922
- { identifier: "OCGT-REQ-006", statement: "Stack CO shall not exceed 25 ppmvd corrected to 15% oxygen between 50% and 100% load on natural gas.", derivesFrom: null, allocatedTo: "OCGT" },
8923
- { identifier: "OCGT-REQ-007", statement: "Sound pressure level shall not exceed 85 dB(A) at 1 m from any enclosure and 55 dB(A) at the site boundary.", derivesFrom: null, allocatedTo: "OCGT" },
8924
- { identifier: "OCGT-REQ-008", statement: "Plant availability shall be not less than 95% over a rolling 12-month period, excluding scheduled outages.", derivesFrom: null, allocatedTo: "OCGT" },
8925
- { identifier: "OCGT-REQ-009", statement: "The unit shall be designed for not fewer than 250 starts per year over a 25-year design life.", derivesFrom: null, allocatedTo: "OCGT" },
8926
- { identifier: "OCGT-REQ-010", statement: "No single failure shall cause an uncontrolled release of fuel gas or an unprotected overspeed event.", derivesFrom: null, allocatedTo: "OCGT" },
8927
- { identifier: "OCGT-REQ-101", statement: "The fuel gas system shall accept a supply pressure of 22 to 30 bar(g) and deliver conditioned gas to the combustor within \xB11% of the demanded flow.", derivesFrom: "OCGT-REQ-001", allocatedTo: "FGS" },
8928
- { identifier: "OCGT-REQ-102", statement: "Inlet air filtration shall limit clean pressure loss to not more than 1.0 kPa and remove particles above 0.3 \xB5m with not less than 99.5% efficiency.", derivesFrom: "OCGT-REQ-001", allocatedTo: "AIR-FH" },
8929
- { identifier: "OCGT-REQ-103", statement: "The compressor shall deliver a pressure ratio of not less than 16:1 at ISO base load.", derivesFrom: "OCGT-REQ-002", allocatedTo: "GT-CMP" },
8930
- { identifier: "OCGT-REQ-105", statement: "The burners shall hold stable lean premixed combustion between 50% and 100% load with dynamic pressure amplitude below 25 mbar rms.", derivesFrom: "OCGT-REQ-005", allocatedTo: "GT-CMB" },
8931
- { identifier: "OCGT-REQ-106", statement: "The fuel metering skid shall control fuel flow to within \xB10.5% of full scale over the load range.", derivesFrom: "OCGT-REQ-004", allocatedTo: "FGS-MS" },
8932
- { identifier: "OCGT-REQ-107", statement: "The starting system shall accelerate the rotor from turning gear to ignition speed in not more than 120 s.", derivesFrom: "OCGT-REQ-003", allocatedTo: "GEN" },
8933
- { identifier: "OCGT-REQ-108", statement: "Overspeed protection shall trip the fuel valves at 110% of rated speed through two independent channels.", derivesFrom: "OCGT-REQ-010", allocatedTo: "CPS-OS" },
8934
- { identifier: "OCGT-REQ-109", statement: "The emergency shutoff valves shall close within 1 s of a trip signal with seat leakage not worse than Class V.", derivesFrom: "OCGT-REQ-010", allocatedTo: "FGS-ESV" },
8935
- { identifier: "OCGT-REQ-110", statement: "Fire and gas detection shall alarm at 20% of the lower explosive limit and trip the unit at 40% in the enclosure.", derivesFrom: "OCGT-REQ-010", allocatedTo: "CPS-FG" },
8936
- { identifier: "OCGT-REQ-111", statement: "The exhaust silencer shall attenuate exhaust noise to not more than 70 dB(A) at 100 m.", derivesFrom: "OCGT-REQ-007", allocatedTo: "EXH-SL" },
8937
- { identifier: "OCGT-REQ-112", statement: "Enclosure ventilation shall keep enclosure air below 55 \xB0C and provide not fewer than 12 air changes per hour.", derivesFrom: "OCGT-REQ-010", allocatedTo: "ENC" },
8938
- { identifier: "OCGT-REQ-113", statement: "The lube oil system shall supply oil at 45 to 55 \xB0C and not less than 1.5 bar at the bearing headers, and shall carry the rotor through coast-down on loss of AC power.", derivesFrom: "OCGT-REQ-008", allocatedTo: "LOS" },
8939
- { identifier: "OCGT-REQ-114", statement: "The generator shall be rated at not less than 62.5 MVA at 0.8 power factor and 11 kV.", derivesFrom: "OCGT-REQ-001", allocatedTo: "GEN" },
8940
- { identifier: "OCGT-REQ-115", statement: "The step-up transformer shall transform 11 kV to 132 kV with load losses not exceeding 0.4% at rated load.", derivesFrom: "OCGT-REQ-001", allocatedTo: "ELE-TX" },
8941
- { identifier: "OCGT-REQ-116", statement: "The unit control system shall run the start sequence automatically with no operator action beyond the start command.", derivesFrom: "OCGT-REQ-003", allocatedTo: "CPS-UC" }
9911
+ { identifier: "OCGT-REQ-001", statement: "The plant shall deliver a net electrical output of not less than 50 MW at ISO ambient conditions (15 \xB0C, 101.3 kPa, 60% relative humidity), measured at the high-voltage terminals of the step-up transformer.", derivesFrom: null, allocatedTo: "OCGT", rationale: "The 50 MW peaking contract sets the plant's revenue; ISO conditions give a common basis for comparing bids and measured performance.", verificationMethod: "Test", acceptanceCriteria: "Corrected net output at the transformer high-voltage terminals is at least 50.0 MW in the acceptance performance test.", source: "Grid peaking capacity agreement, schedule 2", category: "Performance" },
9912
+ { identifier: "OCGT-REQ-002", statement: "The net heat rate on natural gas, lower heating value basis, shall not exceed 10,800 kJ/kWh at ISO conditions and base load.", derivesFrom: null, allocatedTo: "OCGT", rationale: "Fuel is the dominant operating cost of a peaking plant, and the heat rate sets the dispatch price against the market.", verificationMethod: "Test", acceptanceCriteria: "Corrected net heat rate on natural gas (LHV) is at most 10,800 kJ/kWh at base load.", source: "Grid peaking capacity agreement, schedule 2", category: "Performance" },
9913
+ { identifier: "OCGT-REQ-003", statement: "The unit shall reach full load within 10 minutes of a start command from standstill.", derivesFrom: null, allocatedTo: "OCGT", rationale: "A peaker earns most when it answers a short-notice call; a slow start loses dispatch hours.", verificationMethod: "Demonstration", acceptanceCriteria: "Ten consecutive cold starts reach full load in no more than 10 minutes each.", source: "Grid operator ancillary service rules, fast start class", category: "Performance" },
9914
+ { identifier: "OCGT-REQ-004", statement: "The unit shall sustain a load ramp rate of not less than 8 MW per minute between 40% and 100% load.", derivesFrom: null, allocatedTo: "OCGT", rationale: "The ramp rate lets the plant follow the grid operator's set-point changes without penalty.", verificationMethod: "Test", acceptanceCriteria: "Recorded ramp between 40% and 100% load averages at least 8 MW per minute.", source: "Grid operator ancillary service rules, ramp clause", category: "Performance" },
9915
+ { identifier: "OCGT-REQ-005", statement: "Stack NOx shall not exceed 25 ppmvd corrected to 15% oxygen between 50% and 100% load on natural gas.", derivesFrom: null, allocatedTo: "OCGT", rationale: "The air permit caps NOx; the limit has to hold across the load range the plant will run in.", verificationMethod: "Test", acceptanceCriteria: "Extractive analyser readings at 50%, 75% and 100% load are all at or below 25 ppmvd at 15% O2.", source: "Site air permit, condition 4", category: "Environmental" },
9916
+ { identifier: "OCGT-REQ-006", statement: "Stack CO shall not exceed 25 ppmvd corrected to 15% oxygen between 50% and 100% load on natural gas.", derivesFrom: null, allocatedTo: "OCGT", rationale: "The air permit caps CO; low-load combustion can raise CO, so the limit applies down to 50% load.", verificationMethod: "Test", acceptanceCriteria: "Extractive analyser readings at 50%, 75% and 100% load are all at or below 25 ppmvd at 15% O2.", source: "Site air permit, condition 5", category: "Environmental" },
9917
+ { identifier: "OCGT-REQ-007", statement: "Sound pressure level shall not exceed 85 dB(A) at 1 m from any enclosure and 55 dB(A) at the site boundary.", derivesFrom: null, allocatedTo: "OCGT", rationale: "Neighbours and the planning consent limit noise at the boundary; the enclosure limit protects operators.", verificationMethod: "Test", acceptanceCriteria: "Survey results are at most 85 dB(A) at 1 m from every enclosure and 55 dB(A) at the site boundary.", source: "Planning consent, noise condition 12", category: "Environmental" },
9918
+ { identifier: "OCGT-REQ-008", statement: "Plant availability shall be not less than 95% over a rolling 12-month period, excluding scheduled outages.", derivesFrom: null, allocatedTo: "OCGT", rationale: "The capacity agreement pays on availability, and a lower figure triggers a penalty.", verificationMethod: "Inspection", acceptanceCriteria: "Outage records over the 12-month reliability run show availability of at least 95%, scheduled outages excluded.", source: "Grid peaking capacity agreement, schedule 4", category: "Performance" },
9919
+ { identifier: "OCGT-REQ-009", statement: "The unit shall be designed for not fewer than 250 starts per year over a 25-year design life.", derivesFrom: null, allocatedTo: "OCGT", rationale: "A peaker starts often; the hot gas path life is consumed by starts as much as by running hours.", verificationMethod: "Analysis", acceptanceCriteria: "Low-cycle fatigue assessment shows no hot gas path part reaches its life limit within 250 starts per year over 25 years.", source: "Owner's technical specification, section 3.4", category: "Performance" },
9920
+ { identifier: "OCGT-REQ-010", statement: "No single failure shall cause an uncontrolled release of fuel gas or an unprotected overspeed event.", derivesFrom: null, allocatedTo: "OCGT", rationale: "A single fault must never release fuel gas or let the rotor overspeed; both events are potentially fatal.", verificationMethod: "Analysis", acceptanceCriteria: "The hazard and operability review and the trip matrix functional test find no single failure that releases fuel gas or defeats overspeed protection.", source: "Functional safety standard IEC 61511, owner's safety case", category: "Safety" },
9921
+ { identifier: "OCGT-REQ-101", statement: "The fuel gas system shall accept a supply pressure of 22 to 30 bar(g) and deliver conditioned gas to the combustor within \xB11% of the demanded flow.", derivesFrom: "OCGT-REQ-001", allocatedTo: "FGS", rationale: "The gas supply pressure varies with the pipeline; the skid has to absorb it and still meter accurately.", verificationMethod: "Test", acceptanceCriteria: "At supply pressures from 22 to 30 bar(g) the delivered flow stays within 1% of demand.", source: "Gas transporter connection agreement", category: "Interface" },
9922
+ { identifier: "OCGT-REQ-102", statement: "Inlet air filtration shall limit clean pressure loss to not more than 1.0 kPa and remove particles above 0.3 \xB5m with not less than 99.5% efficiency.", derivesFrom: "OCGT-REQ-001", allocatedTo: "AIR-FH", rationale: "Dirty air fouls the compressor and cuts output; a high pressure loss at the filters does the same.", verificationMethod: "Test", acceptanceCriteria: "Clean pressure loss is at most 1.0 kPa and particle removal above 0.3 um is at least 99.5% on the filter test rig.", source: "Filter standard EN ISO 16890, class F9", category: "Performance" },
9923
+ { identifier: "OCGT-REQ-103", statement: "The compressor shall deliver a pressure ratio of not less than 16:1 at ISO base load.", derivesFrom: "OCGT-REQ-002", allocatedTo: "GT-CMP", rationale: "The pressure ratio sets the cycle efficiency and so the heat rate target.", verificationMethod: "Test", acceptanceCriteria: "Measured compressor pressure ratio at ISO base load is at least 16:1.", source: "Gas turbine supplier performance guarantee", category: "Performance" },
9924
+ { identifier: "OCGT-REQ-105", statement: "The burners shall hold stable lean premixed combustion between 50% and 100% load with dynamic pressure amplitude below 25 mbar rms.", derivesFrom: "OCGT-REQ-005", allocatedTo: "GT-CMB", rationale: "Combustion dynamics damage burners and limit the load range in which the NOx limit holds.", verificationMethod: "Test", acceptanceCriteria: "Dynamic pressure amplitude stays below 25 mbar rms from 50% to 100% load.", source: "Gas turbine supplier operating limits", category: "Performance" },
9925
+ { identifier: "OCGT-REQ-106", statement: "The fuel metering skid shall control fuel flow to within \xB10.5% of full scale over the load range.", derivesFrom: "OCGT-REQ-004", allocatedTo: "FGS-MS", rationale: "Flow accuracy decides how closely the unit holds load and emissions.", verificationMethod: "Test", acceptanceCriteria: "Metered flow error is within 0.5% of full scale at five points across the load range.", source: "Gas turbine supplier fuel interface specification", category: "Interface" },
9926
+ { identifier: "OCGT-REQ-107", statement: "The starting system shall accelerate the rotor from turning gear to ignition speed in not more than 120 s.", derivesFrom: "OCGT-REQ-003", allocatedTo: "GEN", rationale: "The start time budget leaves 120 s for acceleration; a slower starter breaks the 10 minute start.", verificationMethod: "Test", acceptanceCriteria: "Acceleration from turning gear to ignition speed takes at most 120 s in the commissioning start.", source: "Owner's technical specification, section 5.1", category: "Performance" },
9927
+ { identifier: "OCGT-REQ-108", statement: "Overspeed protection shall trip the fuel valves at 110% of rated speed through two independent channels.", derivesFrom: "OCGT-REQ-010", allocatedTo: "CPS-OS", rationale: "Overspeed can burst the rotor; two independent channels guard against a single channel fault.", verificationMethod: "Test", acceptanceCriteria: "Each channel trips the fuel valves at 110% speed in a simulation, and a physical trip confirms it.", source: "Machinery safety standard ISO 21789", category: "Safety" },
9928
+ { identifier: "OCGT-REQ-109", statement: "The emergency shutoff valves shall close within 1 s of a trip signal with seat leakage not worse than Class V.", derivesFrom: "OCGT-REQ-010", allocatedTo: "FGS-ESV", rationale: "A fast, tight shutoff limits the gas that can reach a burning or faulty machine.", verificationMethod: "Test", acceptanceCriteria: "Each installed valve closes in at most 1 s with seat leakage within Class V.", source: "Fuel gas code NFPA 85, shutoff valve clause", category: "Safety" },
9929
+ { identifier: "OCGT-REQ-110", statement: "Fire and gas detection shall alarm at 20% of the lower explosive limit and trip the unit at 40% in the enclosure.", derivesFrom: "OCGT-REQ-010", allocatedTo: "CPS-FG", rationale: "Gas accumulating in the enclosure is an explosion hazard; staged alarms give operators time to act.", verificationMethod: "Test", acceptanceCriteria: "Test gas at each detector gives an alarm at 20% of the lower explosive limit and a trip at 40%.", source: "Fuel gas code NFPA 85, enclosure clause", category: "Safety" },
9930
+ { identifier: "OCGT-REQ-111", statement: "The exhaust silencer shall attenuate exhaust noise to not more than 70 dB(A) at 100 m.", derivesFrom: "OCGT-REQ-007", allocatedTo: "EXH-SL", rationale: "Exhaust noise is the dominant far-field source, so the silencer carries most of the boundary noise budget.", verificationMethod: "Analysis", acceptanceCriteria: "The measured level at 100 m is at most 70 dB(A) and agrees with the silencer model.", source: "Planning consent, noise condition 12", category: "Environmental" },
9931
+ { identifier: "OCGT-REQ-112", statement: "Enclosure ventilation shall keep enclosure air below 55 \xB0C and provide not fewer than 12 air changes per hour.", derivesFrom: "OCGT-REQ-010", allocatedTo: "ENC", rationale: "A hot enclosure shortens electronics life and trips the unit; air changes also dilute any leaked gas.", verificationMethod: "Inspection", acceptanceCriteria: "Commissioning records show enclosure air below 55 C at full load and at least 12 air changes per hour.", source: "Fuel gas code NFPA 85, ventilation clause", category: "Safety" },
9932
+ { identifier: "OCGT-REQ-113", statement: "The lube oil system shall supply oil at 45 to 55 \xB0C and not less than 1.5 bar at the bearing headers, and shall carry the rotor through coast-down on loss of AC power.", derivesFrom: "OCGT-REQ-008", allocatedTo: "LOS", rationale: "Bearings need oil at the right temperature and pressure, and a power loss must not run them dry during coast-down.", verificationMethod: "Demonstration", acceptanceCriteria: "A simulated loss of AC power keeps header pressure at or above 1.5 bar through coast-down.", source: "Gas turbine supplier lube oil specification", category: "Interface" },
9933
+ { identifier: "OCGT-REQ-114", statement: "The generator shall be rated at not less than 62.5 MVA at 0.8 power factor and 11 kV.", derivesFrom: "OCGT-REQ-001", allocatedTo: "GEN", rationale: "The generator rating has to cover the turbine output with margin at the lagging power factor the grid asks for.", verificationMethod: "Inspection", acceptanceCriteria: "The generator nameplate and factory test report show at least 62.5 MVA at 0.8 power factor and 11 kV.", source: "Grid code, reactive power requirement", category: "Interface" },
9934
+ { identifier: "OCGT-REQ-115", statement: "The step-up transformer shall transform 11 kV to 132 kV with load losses not exceeding 0.4% at rated load.", derivesFrom: "OCGT-REQ-001", allocatedTo: "ELE-TX", rationale: "The transformer connects the plant to the 132 kV grid; its losses subtract from net output.", verificationMethod: "Test", acceptanceCriteria: "The factory test shows 11 kV to 132 kV transformation and load losses of at most 0.4% at rated load.", source: "Grid connection agreement", category: "Interface" },
9935
+ { identifier: "OCGT-REQ-116", statement: "The unit control system shall run the start sequence automatically with no operator action beyond the start command.", derivesFrom: "OCGT-REQ-003", allocatedTo: "CPS-UC", rationale: "An automatic sequence removes operator error and makes every start repeatable.", verificationMethod: "Demonstration", acceptanceCriteria: "Ten starts complete with no operator action after the start command.", source: "Owner's operating philosophy, section 2", category: "Performance" }
8942
9936
  ];
8943
9937
  var SPECIFICATIONS = [
8944
9938
  { identifier: "OCGT-SPEC-001", statement: "Single-shaft industrial gas turbine with a 16-stage axial compressor and a 3-stage axial turbine, ISO base rating 52 MW at the generator terminals.", satisfies: ["OCGT-REQ-001", "OCGT-REQ-103"] },
@@ -9733,14 +10727,14 @@ var IDENTIFIER_FIELD = Object.freeze({
9733
10727
  app: "appKey",
9734
10728
  "app-draft": "appKey"
9735
10729
  });
9736
- var PROJECT_REF_USAGE = "openeng link <explore|branch-diff|project> --project <id> --ref <ref>";
9737
- var SET_USAGE = "openeng link explore --project <id> --ref <ref> --object-set <id>";
10730
+ var PROJECT_REF_USAGE = "openeng link <branch-diff|project> --project <id> --ref <ref>";
10731
+ var EXPLORE_USAGE = "openeng link explore --project <id> --ref <ref> (--object <id> | --object-set <id>)";
9738
10732
  var REF_USAGE = "openeng link <ontology|change-set> --ref <ref>";
9739
10733
  var DRAFT_USAGE = "openeng link app-draft <appKey> --ref <ref>";
9740
10734
  var IDENTIFIED_USAGE = "openeng link <object|type|proposal|app> <identifier> --project <id> --ref <ref>";
9741
10735
  var APP_PAGE_USAGE = "openeng link app-page <appKey> <pageKey> --project <id> --ref <ref>";
9742
10736
  var PAGE_USAGE = "openeng link organisation-page <page>";
9743
- var LINK_HELP = [PROJECT_REF_USAGE, SET_USAGE, REF_USAGE, DRAFT_USAGE, IDENTIFIED_USAGE, APP_PAGE_USAGE, PAGE_USAGE];
10737
+ var LINK_HELP = [PROJECT_REF_USAGE, EXPLORE_USAGE, REF_USAGE, DRAFT_USAGE, IDENTIFIED_USAGE, APP_PAGE_USAGE, PAGE_USAGE];
9744
10738
  var refusal = (message) => ({ kind: "client-refusal", message });
9745
10739
  var SCOPE_OF_KIND = Object.freeze({
9746
10740
  object: "project-and-ref",
@@ -9799,12 +10793,6 @@ function subjectReads(clients, subject, scope) {
9799
10793
  ));
9800
10794
  }
9801
10795
  switch (subject.kind) {
9802
- case "object":
9803
- reads.push(checkedRead(
9804
- clients.objects.readObject({ selector: { projectId: scope.project, ref: scope.ref }, input: { objectId: subject.objectId } }),
9805
- `no object ${subject.objectId} in project ${scope.project} on ref ${scope.ref}`
9806
- ));
9807
- break;
9808
10796
  case "type":
9809
10797
  reads.push(checkedRead(
9810
10798
  clients.objects.readCatalogue({ selector: { projectId: scope.project }, input: {} }),
@@ -9871,30 +10859,62 @@ async function link(context) {
9871
10859
  if (typeof scope === "string") {
9872
10860
  return refusal(`openeng link ${subject.kind} ${scope}`);
9873
10861
  }
9874
- if (options.objectSet !== void 0 && (subject.kind !== "explore" || options.objectSet.length === 0)) {
9875
- return refusal("--object-set needs a saved set identifier and the explore page");
10862
+ if (subject.kind === "explore") {
10863
+ if (options.object === void 0 === (options.objectSet === void 0) || options.object === "" || options.objectSet === "") {
10864
+ return refusal("openeng link explore needs exactly one of --object <id> or --object-set <id>");
10865
+ }
10866
+ } else if (options.object !== void 0 || options.objectSet !== void 0) {
10867
+ return refusal("--object and --object-set are only for openeng link explore");
9876
10868
  }
9877
10869
  const objectSet = options.objectSet;
9878
- const path = options.objectSet === void 0 ? linkPath(organisation.id, scope.project, subject, scope.ref) : exploreViewAddress({ organisationId: organisation.id, projectId: scope.project, ref: scope.ref, q: null }, { typeKey: null, objectId: null, setId: options.objectSet });
10870
+ const objectId = subject.kind === "object" ? subject.objectId : options.object;
9879
10871
  const run2 = await runAuthenticated(host, deps, async (clients) => {
9880
- const [origin, checks, saved] = await Promise.all([
10872
+ const [origin, checks, saved, object] = await Promise.all([
9881
10873
  clients.admin.readWebOrigin({ input: {} }),
9882
10874
  Promise.all(subjectReads(clients, subject, scope)),
9883
10875
  objectSet === void 0 ? Promise.resolve(null) : clients.objects.readObjectSet({
9884
10876
  selector: { projectId: scope.project, ref: scope.ref },
9885
10877
  input: { setId: objectSet }
10878
+ }),
10879
+ objectId === void 0 ? Promise.resolve(null) : clients.objects.readObject({
10880
+ selector: { projectId: scope.project, ref: scope.ref },
10881
+ input: { objectId }
9886
10882
  })
9887
10883
  ]);
9888
10884
  if (saved !== null && ("refusal" in saved || saved.replayed === true)) return saved;
9889
10885
  const blocked = checks.find((check) => check.missing === null && ("refusal" in check.answer || check.answer.replayed === true));
9890
10886
  if (blocked !== void 0) return blocked.answer;
10887
+ if (object !== null) {
10888
+ if ("refusal" in object) {
10889
+ return object.refusal.kind === "not-found" ? refusal(`no object ${objectId} in project ${scope.project} on ref ${scope.ref}`) : object;
10890
+ }
10891
+ if (object.replayed === true) return object;
10892
+ }
9891
10893
  if ("refusal" in origin) {
9892
10894
  return origin.refusal.kind === "not-found" ? refusal("the host's web application was not found") : origin;
9893
10895
  }
9894
10896
  if (origin.replayed === true) return origin;
9895
10897
  const missing = checks.find((check) => check.missing !== null);
9896
10898
  if (missing !== void 0 && missing.missing !== null) return refusal(missing.missing);
9897
- return { kind: "link-ready", webOrigin: origin.result.webOrigin };
10899
+ let path;
10900
+ if (subject.kind === "object") {
10901
+ if (object === null) throw new Error("an object link needs its object read");
10902
+ path = exploreOpenObjectAddress({
10903
+ organisationId: organisation.id,
10904
+ projectId: scope.project,
10905
+ ref: scope.ref,
10906
+ typeKey: object.result.typeKey
10907
+ }, subject.objectId);
10908
+ } else if (subject.kind === "explore") {
10909
+ path = exploreViewAddress({ organisationId: organisation.id, projectId: scope.project, ref: scope.ref, q: null }, {
10910
+ typeKey: null,
10911
+ objectId: options.object ?? null,
10912
+ setId: objectSet ?? null
10913
+ });
10914
+ } else {
10915
+ path = linkPath(organisation.id, scope.project, subject, scope.ref);
10916
+ }
10917
+ return { kind: "link-ready", webOrigin: origin.result.webOrigin, path };
9898
10918
  });
9899
10919
  if (!run2.ok) {
9900
10920
  return outcomeOfSessionFailure(run2.failure, SETTLE2);
@@ -9902,7 +10922,7 @@ async function link(context) {
9902
10922
  const { answer } = run2;
9903
10923
  if ("kind" in answer) {
9904
10924
  if (answer.kind === "client-refusal") return answer;
9905
- const { webOrigin } = answer;
10925
+ const { webOrigin, path } = answer;
9906
10926
  if (webOrigin === null) {
9907
10927
  return refusal("this host has no web application configured, so it has no page to link to");
9908
10928
  }
@@ -9919,10 +10939,22 @@ var spec = (argumentCount, usage) => ({
9919
10939
  usage,
9920
10940
  help: [
9921
10941
  ...LINK_HELP,
10942
+ "object: the object's type page with the object open; its type comes from the object read",
10943
+ "type: the type's page",
10944
+ "explore: Explore with exactly one --object or --object-set seed",
10945
+ "branch-diff: the branch comparison page",
10946
+ "project: the project page",
10947
+ "proposal: the proposal review page",
10948
+ "ontology: the organisation's Types workspace",
10949
+ "change-set: the organisation's Change set workspace",
10950
+ "app: the published app's first page",
10951
+ "app-page: the named page of a published app",
10952
+ "app-draft: the app's draft screen in the Types workspace",
10953
+ "organisation-page: the named organisation administration page or settings",
9922
10954
  "does: reads the page's subject before printing its web address for the attached organisation",
9923
10955
  "ref: --ref takes main or <projectId>/<branch>, the ref the platform returns; match --project when given",
9924
10956
  "refusal: a subject not found by the page's own read prints no address",
9925
- "example: openeng link explore --project proj_abc123 --ref main",
10957
+ "example: openeng link explore --project proj_abc123 --ref main --object obj_abc123",
9926
10958
  "output: the address on one line; under --json an object with link"
9927
10959
  ],
9928
10960
  run: link
@@ -10400,7 +11432,9 @@ var FLAG_NAME = {
10400
11432
  project: "--project",
10401
11433
  changeSet: "--change-set",
10402
11434
  revision: "--revision",
10403
- from: "--from"
11435
+ from: "--from",
11436
+ type: "--type",
11437
+ sample: "--sample"
10404
11438
  };
10405
11439
  function required(usage, context, keys) {
10406
11440
  const values = {};
@@ -10657,7 +11691,7 @@ var typesDraftState = {
10657
11691
  return run2.ok ? outcomeOfEnvelope(run2.answer, settle2, (state) => `change set ${changeSetId} is ${state.state} at revision ${state.revision}`) : outcomeOfSessionFailure(run2.failure, settle2);
10658
11692
  }
10659
11693
  };
10660
- function changesOfFile(path) {
11694
+ function objectOfFile(path, shape) {
10661
11695
  let text;
10662
11696
  try {
10663
11697
  text = readFileSync5(path, "utf8");
@@ -10677,9 +11711,13 @@ function changesOfFile(path) {
10677
11711
  throw error;
10678
11712
  }
10679
11713
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
10680
- return { ok: false, outcome: { kind: "client-refusal", message: `the file ${JSON.stringify(path)} is not a JSON object keyed by type key` } };
11714
+ return { ok: false, outcome: { kind: "client-refusal", message: `the file ${JSON.stringify(path)} is not ${shape}` } };
10681
11715
  }
10682
- return { ok: true, changes: parsed };
11716
+ return { ok: true, object: parsed };
11717
+ }
11718
+ function changesOfFile(path) {
11719
+ const file = objectOfFile(path, "a JSON object keyed by type key");
11720
+ return file.ok ? { ok: true, changes: file.object } : file;
10683
11721
  }
10684
11722
  function railGroupsOfFlag(text) {
10685
11723
  if (text === void 0) {
@@ -10766,6 +11804,81 @@ var typesDraftValidate = {
10766
11804
  return outcome.kind === "success" && violated ? { kind: "findings", value: outcome.value, text: outcome.text } : outcome;
10767
11805
  }
10768
11806
  };
11807
+ var typesDraftTry = {
11808
+ organisation: "required",
11809
+ words: ["types", "draft", "try"],
11810
+ usage: "openeng types draft try --type <key> --sample <file> [--change-set <id>]",
11811
+ help: [
11812
+ "openeng types draft try --type <key> --sample <file> [--change-set <id>]",
11813
+ "does: checks one sample instance against the open change set's version of a type, with the check a write runs; writes nothing",
11814
+ "example: openeng types draft try --type part --sample sample.json",
11815
+ "output: a line saying the sample fits, or a count and one line per violation (exit 4); under --json an object with valid and violations, each with path and rule"
11816
+ ],
11817
+ run: async (context) => {
11818
+ const flags = required("openeng types draft try", context, ["type", "sample"]);
11819
+ if (!flags.ok) {
11820
+ return flags.outcome;
11821
+ }
11822
+ const { type: typeKey, sample: samplePath } = flags.values;
11823
+ const file = objectOfFile(samplePath, "a JSON object of property values");
11824
+ if (!file.ok) {
11825
+ return file.outcome;
11826
+ }
11827
+ const sample = file.object;
11828
+ const named = context.options.changeSet;
11829
+ const settle2 = "repeat openeng types draft try, which only reads";
11830
+ const run2 = await runAuthenticated(context.host, context.deps, async (clients) => {
11831
+ let changeSetId = named;
11832
+ if (changeSetId === void 0) {
11833
+ const current = await clients.ontology.readCurrentChangeSet({ input: {} });
11834
+ if ("refusal" in current) {
11835
+ return { refusal: current.refusal, correlationId: current.correlationId };
11836
+ }
11837
+ if (current.replayed === true) {
11838
+ throw new Error("the host answered a replay to a read that carried no idempotency key");
11839
+ }
11840
+ if (current.result === null) {
11841
+ return { noChangeSet: true };
11842
+ }
11843
+ changeSetId = current.result.changeSetId;
11844
+ }
11845
+ const read = await clients.ontology.readChangeSet({ input: { changeSetId } });
11846
+ if ("refusal" in read) {
11847
+ return { refusal: read.refusal, correlationId: read.correlationId };
11848
+ }
11849
+ if (read.replayed === true) {
11850
+ throw new Error("the host answered a replay to a read that carried no idempotency key");
11851
+ }
11852
+ return { check: checkSampleAgainstChanges(read.result.changes, typeKey, sample) };
11853
+ });
11854
+ if (!run2.ok) {
11855
+ return outcomeOfSessionFailure(run2.failure, settle2);
11856
+ }
11857
+ const answer = run2.answer;
11858
+ if ("refusal" in answer) {
11859
+ return outcomeOfRouteRefusal(answer.refusal, settle2, answer.correlationId);
11860
+ }
11861
+ if ("noChangeSet" in answer) {
11862
+ return { kind: "client-refusal", message: "no change set is open; open one with openeng types draft open" };
11863
+ }
11864
+ const check = answer.check;
11865
+ if (check.kind === "no-such-type") {
11866
+ return { kind: "client-refusal", message: `the change set holds no type by the key ${JSON.stringify(typeKey)}` };
11867
+ }
11868
+ if (check.kind === "no-properties") {
11869
+ return { kind: "client-refusal", message: `${JSON.stringify(typeKey)} is a verb type, which has no properties an instance could carry` };
11870
+ }
11871
+ if (check.result.ok) {
11872
+ return { kind: "success", value: { valid: true, violations: [] }, text: "the sample fits" };
11873
+ }
11874
+ const violations = check.result.violations.map((violation) => ({ path: violation.path, rule: violation.rule }));
11875
+ return {
11876
+ kind: "findings",
11877
+ value: { valid: false, violations },
11878
+ text: [`${String(violations.length)} ${violations.length === 1 ? "violation" : "violations"}`, ...violations.map((violation) => ` ${JSON.stringify(violation)}`)].join("\n")
11879
+ };
11880
+ }
11881
+ };
10769
11882
  var typesDraftDiscard = {
10770
11883
  organisation: "required",
10771
11884
  words: ["types", "draft", "discard"],
@@ -10810,6 +11923,197 @@ var typesDraftAccept = {
10810
11923
  }
10811
11924
  };
10812
11925
 
11926
+ // packages/cli/src/commands/attachment.ts
11927
+ import { createHash as createHash3, randomUUID as randomUUID5 } from "node:crypto";
11928
+ import { readFileSync as readFileSync6, writeFileSync } from "node:fs";
11929
+ import { basename } from "node:path";
11930
+ var usageAdd = "openeng attachment add <object> <property> <file> --project <id> --ref <ref>";
11931
+ var usageGet = "openeng attachment get <object> <property> [--out <path>] --project <id> --ref <ref>";
11932
+ var usageList = "openeng attachment list <object> --project <id> --ref <ref>";
11933
+ var invalid = (message) => ({ kind: "client-refusal", message });
11934
+ var malformed2 = (field) => ({ kind: "internal-failure", message: `the host answered with malformed ${field}` });
11935
+ function selectorOf2(context) {
11936
+ const { project, ref } = context.options;
11937
+ if (project === void 0 || ref === void 0) return invalid("attachment commands need --project <id> and --ref <ref>");
11938
+ return { projectId: project, ref };
11939
+ }
11940
+ function positional(context, count, usage) {
11941
+ if (context.args.length !== count || context.args.some((argument) => argument.length === 0)) return invalid(`usage: ${usage}`);
11942
+ return context.args;
11943
+ }
11944
+ function isOutcome(value) {
11945
+ return !Array.isArray(value) && typeof value === "object" && value !== null && "kind" in value;
11946
+ }
11947
+ function isSelector(value) {
11948
+ return "projectId" in value;
11949
+ }
11950
+ function isRecord3(value) {
11951
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11952
+ }
11953
+ function descriptor(value) {
11954
+ return isRecord3(value) && typeof value.sha256 === "string" && typeof value.name === "string" && typeof value.mediaType === "string" && typeof value.bytes === "number";
11955
+ }
11956
+ async function saveDescriptor(context, selector, objectId, property, file) {
11957
+ const bytes = new Uint8Array(readFileSync6(file));
11958
+ const name = basename(file);
11959
+ const settle2 = `openeng attachment get ${objectId} ${property} --project ${selector.projectId} --ref ${selector.ref}`;
11960
+ const run2 = await runAuthenticated(context.host, context.deps, async (clients) => {
11961
+ const staged = await clients.objects.stageAttachment(selector, { name, bytes });
11962
+ if ("refusal" in staged) return { outcome: outcomeOfEnvelope(staged, settle2, (value2) => JSON.stringify(value2)) };
11963
+ if (staged.replayed === true) return { outcome: outcomeOfEnvelope(staged, settle2, (value2) => JSON.stringify(value2)) };
11964
+ const object = await clients.objects.readObject({ selector, input: { objectId } });
11965
+ if ("refusal" in object) return { outcome: outcomeOfEnvelope(object, settle2, (value2) => JSON.stringify(value2)) };
11966
+ if (object.replayed === true) return { outcome: outcomeOfEnvelope(object, settle2, (value2) => JSON.stringify(value2)) };
11967
+ const catalogue = await clients.objects.readCatalogue({ selector: { projectId: selector.projectId }, input: {} });
11968
+ if ("refusal" in catalogue) return { outcome: outcomeOfEnvelope(catalogue, settle2, (value2) => JSON.stringify(value2)) };
11969
+ if (catalogue.replayed === true) return { outcome: outcomeOfEnvelope(catalogue, settle2, (value2) => JSON.stringify(value2)) };
11970
+ const type = catalogue.result.objects.find((candidate) => candidate.typeKey === object.result.typeKey);
11971
+ if (type === void 0) return { outcome: invalid(`could not find the published type version for object ${objectId}`) };
11972
+ if (!isRecord3(type.propertyDefinitions)) return { outcome: malformed2("propertyDefinitions") };
11973
+ const definitions = type.propertyDefinitions;
11974
+ if (definitions[property] === void 0) return { outcome: invalid(`property ${property} is not declared on ${type.typeKey}`) };
11975
+ if (!isRecord3(object.result.properties)) return { outcome: malformed2("object properties") };
11976
+ const props = object.result.properties;
11977
+ const current = props[property];
11978
+ const previous = isRecord3(current) && "value" in current ? { value: current.value } : { absent: true };
11979
+ const saved = await clients.objects.mutate({ selector, input: {
11980
+ correlation: { kind: "mint" },
11981
+ operation: { kind: "update-object", objectId, typeVersion: type.version, changes: { [property]: { from: previous, to: { value: staged.result } } } }
11982
+ } }, randomUUID5());
11983
+ if ("refusal" in saved) return { outcome: outcomeOfEnvelope(saved, settle2, (value2) => JSON.stringify(value2)) };
11984
+ if (saved.replayed === true) return { outcome: outcomeOfEnvelope(saved, settle2, (value2) => JSON.stringify(value2)) };
11985
+ if (saved.result.kind === "unknown") {
11986
+ const outcome2 = {
11987
+ kind: "unknown-outcome-no-answer",
11988
+ message: `the mutation outcome is unknown (correlation ${saved.result.correlationId}; trailer ${saved.result.trailer})`,
11989
+ settle: `recover this mutation on ref ${selector.ref} with correlation ${saved.result.correlationId}; recovery searches the trailer ${saved.result.trailer}`
11990
+ };
11991
+ return {
11992
+ outcome: outcome2
11993
+ };
11994
+ }
11995
+ if (saved.result.kind === "refused") return { outcome: outcomeOfEnvelope(saved, settle2, (value2) => JSON.stringify(value2)) };
11996
+ const outcome = { kind: "success", value: staged.result, text: JSON.stringify(staged.result) };
11997
+ return {
11998
+ outcome,
11999
+ descriptor: staged.result
12000
+ };
12001
+ });
12002
+ if (!run2.ok) return outcomeOfSessionFailure(run2.failure, settle2);
12003
+ if (run2.answer.outcome.kind !== "success") return run2.answer.outcome;
12004
+ const value = run2.answer.descriptor;
12005
+ return { kind: "success", value, text: JSON.stringify(value) };
12006
+ }
12007
+ var attachmentAdd = {
12008
+ words: ["attachment", "add"],
12009
+ arguments: 3,
12010
+ organisation: "required",
12011
+ usage: usageAdd,
12012
+ help: [
12013
+ usageAdd,
12014
+ "does: stages a file and saves its descriptor on the object's attachment property",
12015
+ "example: openeng attachment add obj_abc drawing ./drawing.pdf --project proj_abc --ref main",
12016
+ "output: the attachment descriptor as JSON"
12017
+ ],
12018
+ run: async (context) => {
12019
+ const args = positional(context, 3, usageAdd);
12020
+ const selector = selectorOf2(context);
12021
+ if (isOutcome(args)) return args;
12022
+ if (!isSelector(selector)) return selector;
12023
+ const [objectId, property, file] = args;
12024
+ if (objectId === void 0 || property === void 0 || file === void 0) return invalid(`usage: ${usageAdd}`);
12025
+ return saveDescriptor(context, selector, objectId, property, file);
12026
+ }
12027
+ };
12028
+ var attachmentGet = {
12029
+ words: ["attachment", "get"],
12030
+ arguments: 2,
12031
+ organisation: "required",
12032
+ usage: usageGet,
12033
+ help: [
12034
+ usageGet,
12035
+ "does: downloads an object's attachment property to --out or the descriptor's name",
12036
+ "example: openeng attachment get obj_abc drawing --out ./drawing.pdf --project proj_abc --ref main",
12037
+ "output: the path written"
12038
+ ],
12039
+ run: async (context) => {
12040
+ const args = positional(context, 2, usageGet);
12041
+ const selector = selectorOf2(context);
12042
+ if (isOutcome(args)) return args;
12043
+ if (!isSelector(selector)) return selector;
12044
+ const [objectId, property] = args;
12045
+ if (objectId === void 0 || property === void 0) return invalid(`usage: ${usageGet}`);
12046
+ const settle2 = `repeat openeng attachment get ${objectId} ${property} --project ${selector.projectId} --ref ${selector.ref}`;
12047
+ const run2 = await runAuthenticated(context.host, context.deps, async (clients) => {
12048
+ const answer = await clients.objects.readAttachment(selector, { objectId, property });
12049
+ if ("refusal" in answer) return { outcome: outcomeOfEnvelope(answer, settle2, (value) => JSON.stringify(value)) };
12050
+ if (answer.replayed === true) return { outcome: outcomeOfEnvelope(answer, settle2, (value) => JSON.stringify(value)) };
12051
+ const chunks = [];
12052
+ for await (const chunk of answer.result.body) chunks.push(chunk);
12053
+ const bytes = Buffer.concat(chunks);
12054
+ const digest = createHash3("sha256").update(bytes).digest("hex");
12055
+ if (digest !== answer.result.descriptor.sha256) {
12056
+ const outcome2 = { kind: "internal-failure", message: "the downloaded attachment did not match its descriptor's SHA-256" };
12057
+ return { outcome: outcome2 };
12058
+ }
12059
+ const path = context.options.out ?? answer.result.descriptor.name;
12060
+ writeFileSync(path, bytes);
12061
+ const outcome = { kind: "success", value: { path }, text: path };
12062
+ return { outcome };
12063
+ });
12064
+ return run2.ok ? run2.answer.outcome : outcomeOfSessionFailure(run2.failure, settle2);
12065
+ }
12066
+ };
12067
+ function attachmentProperties(object, propertyDefinitions) {
12068
+ if (!isRecord3(propertyDefinitions)) return { ok: false, outcome: malformed2("propertyDefinitions") };
12069
+ if (!isRecord3(object.properties)) return { ok: false, outcome: malformed2("object properties") };
12070
+ const properties = object.properties;
12071
+ const entries6 = Object.entries(propertyDefinitions).flatMap(([property, definition]) => {
12072
+ if (!isRecord3(definition) || definition.kind !== "attachment") return [];
12073
+ const stored = properties[property];
12074
+ if (!isRecord3(stored) || !descriptor(stored.value)) return [];
12075
+ return [{ property, descriptor: stored.value }];
12076
+ });
12077
+ return { ok: true, entries: entries6 };
12078
+ }
12079
+ var attachmentList = {
12080
+ words: ["attachment", "list"],
12081
+ arguments: 1,
12082
+ organisation: "required",
12083
+ usage: usageList,
12084
+ help: [
12085
+ usageList,
12086
+ "does: lists the object's attachment-kind properties",
12087
+ "example: openeng attachment list obj_abc --project proj_abc --ref main",
12088
+ "output: one JSON object per attachment property with its descriptor"
12089
+ ],
12090
+ run: async (context) => {
12091
+ const args = positional(context, 1, usageList);
12092
+ const selector = selectorOf2(context);
12093
+ if (isOutcome(args)) return args;
12094
+ if (!isSelector(selector)) return selector;
12095
+ const objectId = args[0];
12096
+ if (objectId === void 0) return invalid(`usage: ${usageList}`);
12097
+ const settle2 = `openeng attachment list ${objectId} --project ${selector.projectId} --ref ${selector.ref}`;
12098
+ const run2 = await runAuthenticated(context.host, context.deps, async (clients) => {
12099
+ const object = await clients.objects.readObject({ selector, input: { objectId } });
12100
+ if ("refusal" in object) return { outcome: outcomeOfEnvelope(object, settle2, (value) => JSON.stringify(value)) };
12101
+ if (object.replayed === true) return { outcome: outcomeOfEnvelope(object, settle2, (value) => JSON.stringify(value)) };
12102
+ const catalogue = await clients.objects.readCatalogue({ selector: { projectId: selector.projectId }, input: {} });
12103
+ if ("refusal" in catalogue) return { outcome: outcomeOfEnvelope(catalogue, settle2, (value) => JSON.stringify(value)) };
12104
+ if (catalogue.replayed === true) return { outcome: outcomeOfEnvelope(catalogue, settle2, (value) => JSON.stringify(value)) };
12105
+ const type = catalogue.result.objects.find((candidate) => candidate.typeKey === object.result.typeKey);
12106
+ if (type === void 0) return { outcome: invalid(`could not find the published type version for object ${objectId}`) };
12107
+ const listed = attachmentProperties(object.result, type.propertyDefinitions);
12108
+ if (!listed.ok) return { outcome: listed.outcome };
12109
+ const entries6 = listed.entries;
12110
+ const outcome = { kind: "success", value: entries6, text: entries6.map((entry2) => JSON.stringify(entry2)).join("\n") || "no attachments" };
12111
+ return { outcome };
12112
+ });
12113
+ return run2.ok ? run2.answer.outcome : outcomeOfSessionFailure(run2.failure, settle2);
12114
+ }
12115
+ };
12116
+
10813
12117
  // packages/cli/src/commands/public.ts
10814
12118
  var loginCommand = {
10815
12119
  words: ["login"],
@@ -10884,6 +12188,9 @@ var PUBLIC_HAND_WRITTEN_COMMANDS = [
10884
12188
  ceilingSet,
10885
12189
  schemaUpdateRequest,
10886
12190
  schemaUpdateShow,
12191
+ attachmentAdd,
12192
+ attachmentGet,
12193
+ attachmentList,
10887
12194
  typesList,
10888
12195
  typesExport,
10889
12196
  typesDraftOpen,
@@ -10891,6 +12198,7 @@ var PUBLIC_HAND_WRITTEN_COMMANDS = [
10891
12198
  typesDraftShow,
10892
12199
  typesDraftState,
10893
12200
  typesDraftRevise,
12201
+ typesDraftTry,
10894
12202
  typesDraftValidate,
10895
12203
  typesDraftDiscard,
10896
12204
  typesDraftAccept,
@@ -10913,7 +12221,7 @@ var PUBLIC_COMMANDS = [
10913
12221
 
10914
12222
  // packages/cli/src/main.ts
10915
12223
  import { spawn } from "node:child_process";
10916
- import { readFileSync as readFileSync6 } from "node:fs";
12224
+ import { readFileSync as readFileSync8 } from "node:fs";
10917
12225
  import { homedir } from "node:os";
10918
12226
  import { parseArgs } from "node:util";
10919
12227
 
@@ -10939,6 +12247,8 @@ var CLI_OPTIONS = {
10939
12247
  revision: { type: "string" },
10940
12248
  from: { type: "string" },
10941
12249
  "rail-groups": { type: "string" },
12250
+ type: { type: "string" },
12251
+ sample: { type: "string" },
10942
12252
  size: { type: "string" },
10943
12253
  world: { type: "string" },
10944
12254
  selector: { type: "string" },
@@ -10951,12 +12261,13 @@ var CLI_OPTIONS = {
10951
12261
  team: { type: "string" },
10952
12262
  owner: { type: "string" },
10953
12263
  label: { type: "string" },
12264
+ out: { type: "string" },
10954
12265
  help: { type: "boolean", short: "h" },
10955
12266
  version: { type: "boolean" }
10956
12267
  };
10957
12268
 
10958
12269
  // packages/cli/src/cli-version.ts
10959
- var PATCH_VERSION = 1;
12270
+ var PATCH_VERSION = 0;
10960
12271
  var CLI_VERSION = `0.${PROTOCOL_VERSION}.${PATCH_VERSION}`;
10961
12272
 
10962
12273
  // packages/cli/src/environment.ts
@@ -10964,12 +12275,99 @@ var readEnvironment = () => Object.freeze({
10964
12275
  OPENENG_HOST: process.env.OPENENG_HOST,
10965
12276
  OPENENG_SIGN_IN_ORIGIN: process.env.OPENENG_SIGN_IN_ORIGIN,
10966
12277
  OPENENG_SESSION_STORE: process.env.OPENENG_SESSION_STORE,
10967
- XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME
12278
+ XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
12279
+ OPENENG_NO_UPDATE_CHECK: process.env.OPENENG_NO_UPDATE_CHECK,
12280
+ CI: process.env.CI
10968
12281
  });
10969
12282
 
10970
12283
  // packages/cli/src/transport.ts
10971
12284
  var createTransport = (host) => host.kind === "unix" ? createHostFetch(host.socketPath) : createHttpsTransport(host.origin);
10972
12285
 
12286
+ // packages/cli/src/update-check.ts
12287
+ import { randomUUID as randomUUID6 } from "node:crypto";
12288
+ import { existsSync, mkdirSync as mkdirSync3, readFileSync as readFileSync7, renameSync as renameSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
12289
+ import { join as join4 } from "node:path";
12290
+ function versionParts(value) {
12291
+ if (typeof value !== "string" || !/^\d+\.\d+\.\d+$/.test(value)) {
12292
+ return null;
12293
+ }
12294
+ const parts = value.split(".").map(Number);
12295
+ return parts.every(Number.isSafeInteger) ? parts : null;
12296
+ }
12297
+ function readCache(file) {
12298
+ if (!existsSync(file)) {
12299
+ return null;
12300
+ }
12301
+ const value = JSON.parse(readFileSync7(file, "utf8"));
12302
+ if (typeof value !== "object" || value === null || !("latest" in value) || !("checkedAt" in value)) {
12303
+ return null;
12304
+ }
12305
+ return typeof value.latest === "string" && versionParts(value.latest) !== null && typeof value.checkedAt === "number" && Number.isFinite(value.checkedAt) ? { latest: value.latest, checkedAt: value.checkedAt } : null;
12306
+ }
12307
+ async function publishedVersion(signal) {
12308
+ const response = await fetch("https://registry.npmjs.org/@openengio%2fcli/latest", { signal, redirect: "error" });
12309
+ if (!response.ok) {
12310
+ return null;
12311
+ }
12312
+ const value = await response.json();
12313
+ return typeof value === "object" && value !== null && "version" in value && typeof value.version === "string" && versionParts(value.version) !== null ? value.version : null;
12314
+ }
12315
+ async function fetchLatest() {
12316
+ const controller = new AbortController();
12317
+ let timer;
12318
+ const deadline = new Promise((resolve) => {
12319
+ timer = setTimeout(() => {
12320
+ controller.abort();
12321
+ resolve(null);
12322
+ }, 1500);
12323
+ });
12324
+ try {
12325
+ return await Promise.race([publishedVersion(controller.signal), deadline]);
12326
+ } finally {
12327
+ clearTimeout(timer);
12328
+ }
12329
+ }
12330
+ function writeCache(directory, file, cache) {
12331
+ mkdirSync3(directory, { recursive: true, mode: 448 });
12332
+ const temporary = `${file}.${randomUUID6()}.tmp`;
12333
+ try {
12334
+ writeFileSync2(temporary, JSON.stringify(cache), { flag: "wx", mode: 384 });
12335
+ renameSync2(temporary, file);
12336
+ } finally {
12337
+ if (existsSync(temporary)) {
12338
+ unlinkSync3(temporary);
12339
+ }
12340
+ }
12341
+ }
12342
+ async function checkForUpdate(configDirectory) {
12343
+ try {
12344
+ const directory = join4(configDirectory, "openeng");
12345
+ const file = join4(directory, "update-check.json");
12346
+ const now = Date.now();
12347
+ let cache = readCache(file);
12348
+ if (cache === null || now < cache.checkedAt || now - cache.checkedAt >= 864e5) {
12349
+ const latest2 = await fetchLatest();
12350
+ if (latest2 === null) {
12351
+ return;
12352
+ }
12353
+ cache = { latest: latest2, checkedAt: now };
12354
+ writeCache(directory, file, cache);
12355
+ }
12356
+ const latest = versionParts(cache.latest);
12357
+ const current = versionParts(CLI_VERSION);
12358
+ if (latest === null || current === null) {
12359
+ return;
12360
+ }
12361
+ const difference = latest.findIndex((part, index) => part !== current[index]);
12362
+ if (difference !== -1 && latest[difference] > current[difference]) {
12363
+ process.stderr.write(`openeng ${cache.latest} is available (you have ${CLI_VERSION}): npm install -g @openengio/cli@latest
12364
+ `);
12365
+ }
12366
+ } catch {
12367
+ return;
12368
+ }
12369
+ }
12370
+
10973
12371
  // packages/cli/src/main.ts
10974
12372
  var clock = {
10975
12373
  now: () => Date.now(),
@@ -11085,6 +12483,8 @@ function parseInvocation(argv) {
11085
12483
  revision: values.revision,
11086
12484
  from: values.from,
11087
12485
  railGroups: values["rail-groups"],
12486
+ type: values.type,
12487
+ sample: values.sample,
11088
12488
  size: values.size,
11089
12489
  world: values.world,
11090
12490
  selector: values.selector,
@@ -11096,7 +12496,8 @@ function parseInvocation(argv) {
11096
12496
  company: values.company,
11097
12497
  team: values.team,
11098
12498
  owner: values.owner,
11099
- label: values.label
12499
+ label: values.label,
12500
+ out: values.out
11100
12501
  }
11101
12502
  };
11102
12503
  } catch (error) {
@@ -11117,11 +12518,11 @@ async function run(commands, argv) {
11117
12518
  }
11118
12519
  const { options } = invocation;
11119
12520
  if (invocation.version) {
11120
- return { outcome: { kind: "success", value: { version: CLI_VERSION }, text: CLI_VERSION }, json: options.json, scope: null };
12521
+ return { outcome: { kind: "success", value: { version: CLI_VERSION }, text: CLI_VERSION }, json: options.json, scope: null, skipUpdateCheck: true };
11121
12522
  }
11122
12523
  const helped = outcomeOfHelp(commands, invocation.words, invocation.help);
11123
12524
  if (helped !== void 0) {
11124
- return { outcome: helped, json: options.json, scope: null };
12525
+ return { outcome: helped, json: options.json, scope: null, skipUpdateCheck: true };
11125
12526
  }
11126
12527
  const command = findCommand(commands, invocation.words);
11127
12528
  if (command === void 0) {
@@ -11169,7 +12570,7 @@ ${usageLines(commands).join("\n")}` : unknownCommandMessage(commands, invocation
11169
12570
  deps,
11170
12571
  options,
11171
12572
  args: invocation.words.slice(command.words.length),
11172
- readStandardInput: () => readFileSync6(0, "utf8"),
12573
+ readStandardInput: () => readFileSync8(0, "utf8"),
11173
12574
  promptSecret,
11174
12575
  writeLine: (line) => process.stdout.write(`${line}
11175
12576
  `),
@@ -11224,6 +12625,10 @@ async function main(commands) {
11224
12625
  `);
11225
12626
  }
11226
12627
  process.exitCode = rendered.exitCode;
12628
+ const environment = readEnvironment();
12629
+ if (result.skipUpdateCheck !== true && environment.OPENENG_NO_UPDATE_CHECK !== "1" && environment.CI === void 0) {
12630
+ await checkForUpdate(configurationDirectory(environment.XDG_CONFIG_HOME, homedir()));
12631
+ }
11227
12632
  }
11228
12633
 
11229
12634
  // packages/cli/src/bin-public.ts