@mdbase-dev/connect-protocol 0.1.0-beta.123 → 0.1.0-beta.125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/connect-problems.generated.d.ts +11 -0
- package/dist/connect-problems.generated.js +1 -0
- package/dist/files.d.ts +17 -0
- package/dist/index.d.ts +4 -55
- package/dist/index.js +1 -0
- package/dist/manifest.d.ts +7 -0
- package/dist/manifest.js +88 -35
- package/dist/operations.d.ts +1 -1
- package/dist/operations.js +2 -0
- package/dist/records.d.ts +108 -0
- package/dist/records.js +3 -0
- package/dist/type-packs.d.ts +22 -6
- package/package.json +3 -2
- package/schemas/connect-problem.v1.schema.json +40 -0
- package/schemas/connect-problems.v1.catalog.json +1 -0
- package/schemas/connect-protocol.v1.schema.json +100 -0
- package/schemas/files.v1.schema.json +26 -1
- package/schemas/mdbase-app.schema.json +14 -7
- package/schemas/mdbase-query.v0.3.schema.json +5 -0
- package/schemas/operation-catalog.v1.json +1 -0
- package/schemas/operation-mutation-classification.v1.json +17 -0
|
@@ -168,6 +168,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
|
|
|
168
168
|
readonly category: "availability";
|
|
169
169
|
readonly recovery: "retry";
|
|
170
170
|
};
|
|
171
|
+
readonly file_list_changed: {
|
|
172
|
+
readonly category: "conflict";
|
|
173
|
+
readonly recovery: "refresh";
|
|
174
|
+
};
|
|
171
175
|
readonly file_move_failed: {
|
|
172
176
|
readonly category: "internal";
|
|
173
177
|
readonly recovery: "contact_support";
|
|
@@ -564,6 +568,7 @@ export interface ConnectProblemDetailsByCode {
|
|
|
564
568
|
"file_changed_during_move": undefined;
|
|
565
569
|
"file_changed_during_read": undefined;
|
|
566
570
|
"file_index_warming": undefined;
|
|
571
|
+
"file_list_changed": undefined;
|
|
567
572
|
"file_move_failed": undefined;
|
|
568
573
|
"file_mutation_conflict": undefined;
|
|
569
574
|
"file_not_found": undefined;
|
|
@@ -919,6 +924,12 @@ export interface ConnectProblemByCode {
|
|
|
919
924
|
recovery: "retry";
|
|
920
925
|
details?: never;
|
|
921
926
|
};
|
|
927
|
+
"file_list_changed": ConnectProblemBase & {
|
|
928
|
+
code: "file_list_changed";
|
|
929
|
+
category: "conflict";
|
|
930
|
+
recovery: "refresh";
|
|
931
|
+
details?: never;
|
|
932
|
+
};
|
|
922
933
|
"file_move_failed": ConnectProblemBase & {
|
|
923
934
|
code: "file_move_failed";
|
|
924
935
|
category: "internal";
|
|
@@ -43,6 +43,7 @@ export const CONNECT_PROBLEM_CATALOG = {
|
|
|
43
43
|
"file_changed_during_move": { category: "conflict", recovery: "refresh" },
|
|
44
44
|
"file_changed_during_read": { category: "conflict", recovery: "refresh" },
|
|
45
45
|
"file_index_warming": { category: "availability", recovery: "retry" },
|
|
46
|
+
"file_list_changed": { category: "conflict", recovery: "refresh" },
|
|
46
47
|
"file_move_failed": { category: "internal", recovery: "contact_support" },
|
|
47
48
|
"file_mutation_conflict": { category: "conflict", recovery: "resolve_conflict" },
|
|
48
49
|
"file_not_found": { category: "conflict", recovery: "refresh" },
|
package/dist/files.d.ts
CHANGED
|
@@ -84,7 +84,24 @@ export interface ListFilesRequest {
|
|
|
84
84
|
after?: string;
|
|
85
85
|
limit?: number;
|
|
86
86
|
}
|
|
87
|
+
export type StatFileRequest = {
|
|
88
|
+
protocol_version: 1;
|
|
89
|
+
type: "stat_file";
|
|
90
|
+
} & ({
|
|
91
|
+
path: string;
|
|
92
|
+
file_id?: never;
|
|
93
|
+
} | {
|
|
94
|
+
path?: never;
|
|
95
|
+
file_id: string;
|
|
96
|
+
});
|
|
97
|
+
export interface FileStat {
|
|
98
|
+
protocol_version: 1;
|
|
99
|
+
type: "file_stat";
|
|
100
|
+
file: CollectionFileDescriptor | null;
|
|
101
|
+
}
|
|
87
102
|
export interface ListFilesPage {
|
|
103
|
+
/** Authority-local file implementation features, not granted actions. */
|
|
104
|
+
authority_capabilities?: string[];
|
|
88
105
|
protocol_version: 1;
|
|
89
106
|
type: "files_page";
|
|
90
107
|
files: CollectionFileDescriptor[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ConnectProblem } from "./connect-problems.generated.js";
|
|
2
|
+
import type { JsonObject, QueryRecord } from "./records.js";
|
|
3
|
+
export * from "./records.js";
|
|
2
4
|
import type { ApplicationFileRequirement, LegacyApplicationFileRequirement, CollectionFileDescriptor, FileCapability } from "./files.js";
|
|
3
5
|
import type { CollectionOperation } from "./operations.js";
|
|
4
6
|
import type { ApplicationCapabilityRequirements, LegacyApplicationCapabilityRequirements } from "./capabilities.js";
|
|
@@ -632,7 +634,6 @@ export interface ConnectorCollection {
|
|
|
632
634
|
enabled: boolean;
|
|
633
635
|
contracts: CollectionContractDescriptor[];
|
|
634
636
|
}
|
|
635
|
-
export type JsonObject = Record<string, unknown>;
|
|
636
637
|
export interface MdbaseDiagnostic {
|
|
637
638
|
[key: string]: unknown;
|
|
638
639
|
severity: "error" | "warning" | "info";
|
|
@@ -755,60 +756,6 @@ export interface SavedViewExecution<Frontmatter extends JsonObject = JsonObject>
|
|
|
755
756
|
}>;
|
|
756
757
|
};
|
|
757
758
|
}
|
|
758
|
-
export interface CollectionFileMetadata extends JsonObject {
|
|
759
|
-
name: string;
|
|
760
|
-
folder: string;
|
|
761
|
-
size: number;
|
|
762
|
-
mtime: string;
|
|
763
|
-
tags?: string[];
|
|
764
|
-
links?: unknown[];
|
|
765
|
-
embeds?: unknown[];
|
|
766
|
-
}
|
|
767
|
-
export interface DataContractViewIdentity {
|
|
768
|
-
id: string;
|
|
769
|
-
version: string;
|
|
770
|
-
digest: string;
|
|
771
|
-
type: string;
|
|
772
|
-
implementation_digest: string;
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* A projected query row. Frontmatter members are optional because
|
|
776
|
-
* `frontmatter_mode` selects which fixed-semantics representation is returned.
|
|
777
|
-
*/
|
|
778
|
-
export interface QueryRecord<Frontmatter extends JsonObject = JsonObject> {
|
|
779
|
-
path: string;
|
|
780
|
-
frontmatter?: Frontmatter;
|
|
781
|
-
effective_frontmatter?: Frontmatter;
|
|
782
|
-
body?: string;
|
|
783
|
-
types: string[];
|
|
784
|
-
file: Partial<CollectionFileMetadata> & {
|
|
785
|
-
path?: string;
|
|
786
|
-
};
|
|
787
|
-
values?: JsonObject;
|
|
788
|
-
/** Present when the authority returned a normalized contract projection. */
|
|
789
|
-
contract?: DataContractViewIdentity;
|
|
790
|
-
}
|
|
791
|
-
/** An authoritative record or a field-limited data-contract projection. */
|
|
792
|
-
export interface RecordDocument<Frontmatter extends JsonObject = JsonObject> {
|
|
793
|
-
path: string;
|
|
794
|
-
revision: string;
|
|
795
|
-
types: string[];
|
|
796
|
-
frontmatter: Frontmatter;
|
|
797
|
-
effective_frontmatter: Frontmatter;
|
|
798
|
-
/** Omitted from contract-scoped results. */
|
|
799
|
-
body?: string;
|
|
800
|
-
/**
|
|
801
|
-
* The exact UTF-8 Markdown source, including frontmatter delimiters,
|
|
802
|
-
* comments, quoting, whitespace, line endings, and trailing newline.
|
|
803
|
-
* Returned only when the operation requests it.
|
|
804
|
-
*/
|
|
805
|
-
document?: string;
|
|
806
|
-
file: Partial<CollectionFileMetadata> & {
|
|
807
|
-
path?: string;
|
|
808
|
-
};
|
|
809
|
-
/** Present when the authority returned a normalized contract projection. */
|
|
810
|
-
contract?: DataContractViewIdentity;
|
|
811
|
-
}
|
|
812
759
|
export interface CollectionTypeDescriptor {
|
|
813
760
|
name: string;
|
|
814
761
|
version?: number;
|
|
@@ -854,6 +801,8 @@ export interface CollectionContractImplementationDescriptor {
|
|
|
854
801
|
binding?: JsonObject;
|
|
855
802
|
}
|
|
856
803
|
export interface CollectionDescription {
|
|
804
|
+
/** Authority-local implementation features, not permissions. Absence means legacy. */
|
|
805
|
+
authority_capabilities?: string[];
|
|
857
806
|
protocol_version: 1;
|
|
858
807
|
collection_id: string;
|
|
859
808
|
display_name: string;
|
package/dist/index.js
CHANGED
package/dist/manifest.d.ts
CHANGED
|
@@ -60,3 +60,10 @@ export declare function parseAppManifest(value: unknown, options?: ManifestValid
|
|
|
60
60
|
/** Validate and clone without changing capability IDs, file aliases, or version. */
|
|
61
61
|
export declare function parseVersionedAppManifest(value: unknown, options?: ManifestValidationOptions): VersionedAppManifest;
|
|
62
62
|
export declare function formatManifestValidationIssues(issues: readonly ManifestValidationIssue[]): string;
|
|
63
|
+
/**
|
|
64
|
+
* Validate one schema-valid type-pack provision beyond its JSON Schema: the
|
|
65
|
+
* embedded resources are exactly the manifest's, each digest pins its bytes,
|
|
66
|
+
* and every seed `upgrade_from` baseline satisfies mdbase 05A. Issue paths are
|
|
67
|
+
* prefixed with `path`, the provision's location in its enclosing document.
|
|
68
|
+
*/
|
|
69
|
+
export declare function validateTypePackProvision(value: unknown, path?: string): ManifestValidationIssue[];
|
package/dist/manifest.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
3
3
|
import addFormatsModule from "ajv-formats";
|
|
4
|
+
import { isMap, parseDocument } from "yaml";
|
|
4
5
|
import appManifestSchema from "../schemas/mdbase-app.schema.json" with { type: "json" };
|
|
5
6
|
import legacyAppManifestSchema from "../schemas/mdbase-app.legacy-v1.schema.json" with { type: "json" };
|
|
6
7
|
import { RECORD_EXTENSIONS_CONFIGURATION_PATH } from "./collection-setup.js";
|
|
@@ -266,47 +267,99 @@ function validateProvisionRequirements(value) {
|
|
|
266
267
|
issues.push(issue(`/provisions/type_packs/${packIndex}/provides`, "contractRequirement", "may only contain contracts required by the application"));
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
270
|
+
issues.push(...validateTypePackProvision(provision, `/provisions/type_packs/${packIndex}`));
|
|
271
|
+
}
|
|
272
|
+
return issues;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Validate one schema-valid type-pack provision beyond its JSON Schema: the
|
|
276
|
+
* embedded resources are exactly the manifest's, each digest pins its bytes,
|
|
277
|
+
* and every seed `upgrade_from` baseline satisfies mdbase 05A. Issue paths are
|
|
278
|
+
* prefixed with `path`, the provision's location in its enclosing document.
|
|
279
|
+
*/
|
|
280
|
+
export function validateTypePackProvision(value, path = "") {
|
|
281
|
+
const provision = asObject(value);
|
|
282
|
+
const manifest = asObject(provision.manifest);
|
|
283
|
+
const declaredResources = Array.isArray(manifest.resources)
|
|
284
|
+
? manifest.resources.map(asObject)
|
|
285
|
+
: [];
|
|
286
|
+
const embeddedResources = Array.isArray(provision.resources)
|
|
287
|
+
? provision.resources.map(asObject)
|
|
288
|
+
: [];
|
|
289
|
+
const embedded = new Map(embeddedResources.map((resource) => [String(resource.source), resource.document]));
|
|
290
|
+
if (embedded.size !== embeddedResources.length
|
|
291
|
+
|| new Set(declaredResources.map((resource) => String(resource.source))).size
|
|
292
|
+
!== declaredResources.length
|
|
293
|
+
|| declaredResources.length !== embeddedResources.length) {
|
|
294
|
+
return [issue(`${path}/resources`, "resourceSet", "must match manifest source paths exactly")];
|
|
295
|
+
}
|
|
296
|
+
const issues = [];
|
|
297
|
+
for (const [resourceIndex, resource] of declaredResources.entries()) {
|
|
298
|
+
const resourcePath = `${path}/manifest/resources/${resourceIndex}`;
|
|
299
|
+
const source = String(resource.source);
|
|
300
|
+
const document = embedded.get(source);
|
|
301
|
+
if (typeof document !== "string") {
|
|
302
|
+
issues.push(issue(`${path}/resources`, "resourceSet", `is missing manifest source ${source}`));
|
|
282
303
|
continue;
|
|
283
304
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
305
|
+
if (sha256(document) !== resource.digest) {
|
|
306
|
+
issues.push(issue(`${resourcePath}/digest`, "digest", "does not match the embedded document"));
|
|
307
|
+
}
|
|
308
|
+
if (resource.upgrade_from !== undefined) {
|
|
309
|
+
issues.push(...validateSeedUpgrade(resource, document, `${resourcePath}/upgrade_from`));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return issues;
|
|
313
|
+
}
|
|
314
|
+
/** 05A seed-upgrade baselines: exact, distinct, earlier starters of the same type. */
|
|
315
|
+
function validateSeedUpgrade(resource, document, path) {
|
|
316
|
+
if (resource.kind !== "type" || resource.mode !== "seed") {
|
|
317
|
+
return [issue(path, "seedUpgrade", "is only allowed for seed types")];
|
|
318
|
+
}
|
|
319
|
+
const desired = typeFrontmatter(document);
|
|
320
|
+
const listed = Array.isArray(resource.upgrade_from);
|
|
321
|
+
const baselines = (listed ? resource.upgrade_from : [resource.upgrade_from]).map(asObject);
|
|
322
|
+
const seen = new Set();
|
|
323
|
+
const issues = [];
|
|
324
|
+
for (const [index, baseline] of baselines.entries()) {
|
|
325
|
+
const baselinePath = listed ? `${path}/${index}` : path;
|
|
326
|
+
const baselineDocument = String(baseline.document);
|
|
327
|
+
if (baseline.digest !== sha256(baselineDocument)) {
|
|
328
|
+
issues.push(issue(`${baselinePath}/digest`, "digest", "does not match the baseline document"));
|
|
329
|
+
}
|
|
330
|
+
else if (seen.has(baseline.digest)) {
|
|
331
|
+
issues.push(issue(`${baselinePath}/digest`, "uniqueBaseline", "duplicates another upgrade baseline"));
|
|
332
|
+
}
|
|
333
|
+
else if (baseline.digest === resource.digest) {
|
|
334
|
+
issues.push(issue(`${baselinePath}/digest`, "seedUpgrade", "must not be the resource's own document"));
|
|
335
|
+
}
|
|
336
|
+
seen.add(baseline.digest);
|
|
337
|
+
const previous = typeFrontmatter(baselineDocument);
|
|
338
|
+
if (!desired || !previous || previous.kind !== desired.kind || previous.name !== desired.name) {
|
|
339
|
+
issues.push(issue(`${baselinePath}/document`, "seedUpgrade", "must be a type document with the same kind and name as the resource"));
|
|
340
|
+
}
|
|
341
|
+
else if (baseline.version !== undefined && previous.version !== baseline.version) {
|
|
342
|
+
issues.push(issue(`${baselinePath}/version`, "seedUpgrade", "must equal the version the baseline document declares"));
|
|
306
343
|
}
|
|
307
344
|
}
|
|
308
345
|
return issues;
|
|
309
346
|
}
|
|
347
|
+
/** Top-level frontmatter of a type document, or undefined when it has none. */
|
|
348
|
+
// The identity a type document declares. Only these top-level keys are read, so
|
|
349
|
+
// anchors and aliases elsewhere in a starter are harmless and alias expansion
|
|
350
|
+
// stays disabled.
|
|
351
|
+
function typeFrontmatter(document) {
|
|
352
|
+
const source = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(document)?.[1];
|
|
353
|
+
if (source === undefined)
|
|
354
|
+
return undefined;
|
|
355
|
+
const parsed = parseDocument(source, { uniqueKeys: true });
|
|
356
|
+
if (parsed.errors.length > 0 || !isMap(parsed.contents))
|
|
357
|
+
return undefined;
|
|
358
|
+
return { kind: parsed.get("kind"), name: parsed.get("name"), version: parsed.get("version") };
|
|
359
|
+
}
|
|
360
|
+
function sha256(document) {
|
|
361
|
+
return `sha256:${createHash("sha256").update(document).digest("hex")}`;
|
|
362
|
+
}
|
|
310
363
|
function validateConfigurationSetup(value) {
|
|
311
364
|
const manifest = asObject(value);
|
|
312
365
|
const requirements = asObject(manifest.requirements);
|
package/dist/operations.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const OPERATION_CATALOG_VERSION: 1;
|
|
2
2
|
export declare const COLLECTION_OPERATIONS: readonly ["describe", "changes", "read", "query", "list_views", "execute_view", "read_view_source", "create_view_source", "update_view_source", "delete_view_source", "validate", "create", "update", "delete", "rename", "read_type", "create_type", "update_type", "assess_type_pack", "apply_type_pack", "assess_collection_setup", "apply_collection_setup", "list_timers", "put_timer", "cancel_timer", "reconcile_timers", "sync"];
|
|
3
3
|
export type CollectionOperation = typeof COLLECTION_OPERATIONS[number];
|
|
4
|
-
export declare const FILE_CONTROL_MESSAGE_TYPES: readonly ["list_files", "open_file_upload", "open_file_download", "move_file", "delete_file", "get_file_transfer_status", "commit_file_upload", "abort_file_transfer"];
|
|
4
|
+
export declare const FILE_CONTROL_MESSAGE_TYPES: readonly ["list_files", "stat_file", "open_file_upload", "open_file_download", "move_file", "delete_file", "get_file_transfer_status", "commit_file_upload", "abort_file_transfer"];
|
|
5
5
|
export type FileControlMessageType = typeof FILE_CONTROL_MESSAGE_TYPES[number];
|
|
6
6
|
export type EncryptedOperation = CollectionOperation | "file_control";
|
|
7
7
|
export declare const MUTATING_OPERATION_IDENTIFIERS: readonly ["create_view_source", "update_view_source", "delete_view_source", "create", "update", "delete", "rename", "create_type", "update_type", "apply_type_pack", "apply_collection_setup", "put_timer", "cancel_timer", "reconcile_timers", "sync:mutate", "file_control:open_file_upload", "file_control:move_file", "file_control:delete_file", "file_control:commit_file_upload", "file_control:abort_file_transfer"];
|
package/dist/operations.js
CHANGED
|
@@ -31,6 +31,7 @@ export const COLLECTION_OPERATIONS = [
|
|
|
31
31
|
];
|
|
32
32
|
export const FILE_CONTROL_MESSAGE_TYPES = [
|
|
33
33
|
"list_files",
|
|
34
|
+
"stat_file",
|
|
34
35
|
"open_file_upload",
|
|
35
36
|
"open_file_download",
|
|
36
37
|
"move_file",
|
|
@@ -99,6 +100,7 @@ const COLLECTION_INPUT_SCHEMA_VERSIONS = {
|
|
|
99
100
|
};
|
|
100
101
|
const FILE_CONTROL_INPUT_SCHEMA_VERSIONS = {
|
|
101
102
|
"list_files": 1,
|
|
103
|
+
"stat_file": 1,
|
|
102
104
|
"open_file_upload": 1,
|
|
103
105
|
"open_file_download": 1,
|
|
104
106
|
"move_file": 1,
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export type JsonObject = Record<string, unknown>;
|
|
2
|
+
export interface CollectionFileMetadata extends JsonObject {
|
|
3
|
+
name: string;
|
|
4
|
+
folder: string;
|
|
5
|
+
size: number;
|
|
6
|
+
mtime: string;
|
|
7
|
+
tags?: string[];
|
|
8
|
+
links?: unknown[];
|
|
9
|
+
embeds?: unknown[];
|
|
10
|
+
}
|
|
11
|
+
export interface DataContractViewIdentity {
|
|
12
|
+
id: string;
|
|
13
|
+
version: string;
|
|
14
|
+
digest: string;
|
|
15
|
+
type: string;
|
|
16
|
+
implementation_digest: string;
|
|
17
|
+
}
|
|
18
|
+
/** Frontmatter members depend on the selected frontmatter_mode. */
|
|
19
|
+
export interface QueryRecord<Frontmatter extends JsonObject = JsonObject> {
|
|
20
|
+
path: string;
|
|
21
|
+
/** Exact-source token; absent on authorities predating query-record-revisions-v1. */
|
|
22
|
+
revision?: string;
|
|
23
|
+
frontmatter?: Frontmatter;
|
|
24
|
+
effective_frontmatter?: Frontmatter;
|
|
25
|
+
body?: string;
|
|
26
|
+
types: string[];
|
|
27
|
+
file: Partial<CollectionFileMetadata> & {
|
|
28
|
+
path?: string;
|
|
29
|
+
};
|
|
30
|
+
values?: JsonObject;
|
|
31
|
+
/** Present when the authority returned a normalized contract projection. */
|
|
32
|
+
contract?: DataContractViewIdentity;
|
|
33
|
+
}
|
|
34
|
+
export declare const MAX_READ_MANY_PATHS = 100;
|
|
35
|
+
/** Ceiling for the serialized batch operation envelope; callers must split on overflow. */
|
|
36
|
+
export declare const MAX_READ_MANY_RESPONSE_BYTES: number;
|
|
37
|
+
export interface DataContractSelector {
|
|
38
|
+
id: string;
|
|
39
|
+
version: string;
|
|
40
|
+
type?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Existing read operation: exactly one target form; batch defaults differ from point reads. */
|
|
43
|
+
export type ReadInput = ({
|
|
44
|
+
path: string;
|
|
45
|
+
paths?: never;
|
|
46
|
+
} | {
|
|
47
|
+
path?: never;
|
|
48
|
+
paths: string[];
|
|
49
|
+
}) & {
|
|
50
|
+
contract?: DataContractSelector;
|
|
51
|
+
/** Batch default: true. Single-path defaults remain unchanged. */
|
|
52
|
+
include_body?: boolean;
|
|
53
|
+
/** Batch default: false. Contract projections cannot request exact source. */
|
|
54
|
+
include_document?: boolean;
|
|
55
|
+
};
|
|
56
|
+
export type ReadManyDocumentItem<Frontmatter extends JsonObject = JsonObject> = {
|
|
57
|
+
path: string;
|
|
58
|
+
status: "found";
|
|
59
|
+
record: RecordDocument<Frontmatter>;
|
|
60
|
+
} | {
|
|
61
|
+
path: string;
|
|
62
|
+
status: "missing";
|
|
63
|
+
} | {
|
|
64
|
+
path: string;
|
|
65
|
+
status: "error";
|
|
66
|
+
error: {
|
|
67
|
+
code: string;
|
|
68
|
+
message: string;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
export interface ReadManyDocumentsResult<Frontmatter extends JsonObject = JsonObject> {
|
|
72
|
+
/** One ordered item per input occurrence, including duplicates. */
|
|
73
|
+
items: Array<ReadManyDocumentItem<Frontmatter>>;
|
|
74
|
+
}
|
|
75
|
+
/** Negotiated narrow row; omitted document fields are not empty fields. */
|
|
76
|
+
export interface QueryMetadataRecord {
|
|
77
|
+
path: string;
|
|
78
|
+
types: string[];
|
|
79
|
+
revision: string;
|
|
80
|
+
values: JsonObject;
|
|
81
|
+
contract?: DataContractViewIdentity;
|
|
82
|
+
}
|
|
83
|
+
export interface QueryMetadataResult {
|
|
84
|
+
output: "metadata";
|
|
85
|
+
results: QueryMetadataRecord[];
|
|
86
|
+
meta?: JsonObject;
|
|
87
|
+
}
|
|
88
|
+
/** An authoritative record or a field-limited data-contract projection. */
|
|
89
|
+
export interface RecordDocument<Frontmatter extends JsonObject = JsonObject> {
|
|
90
|
+
path: string;
|
|
91
|
+
revision: string;
|
|
92
|
+
types: string[];
|
|
93
|
+
frontmatter: Frontmatter;
|
|
94
|
+
effective_frontmatter: Frontmatter;
|
|
95
|
+
/** Omitted from contract-scoped results. */
|
|
96
|
+
body?: string;
|
|
97
|
+
/**
|
|
98
|
+
* The exact UTF-8 Markdown source, including frontmatter delimiters,
|
|
99
|
+
* comments, quoting, whitespace, line endings, and trailing newline.
|
|
100
|
+
* Returned only when the operation requests it.
|
|
101
|
+
*/
|
|
102
|
+
document?: string;
|
|
103
|
+
file: Partial<CollectionFileMetadata> & {
|
|
104
|
+
path?: string;
|
|
105
|
+
};
|
|
106
|
+
/** Present when the authority returned a normalized contract projection. */
|
|
107
|
+
contract?: DataContractViewIdentity;
|
|
108
|
+
}
|
package/dist/records.js
ADDED
package/dist/type-packs.d.ts
CHANGED
|
@@ -35,12 +35,19 @@ export declare const MDBASE_TIMER_FIRED_CONTRACT: {
|
|
|
35
35
|
readonly version: "1.0.0";
|
|
36
36
|
readonly digest: "sha256:41105be7a7abf33b31ced47e1e1965242236e40ccaea286b959b0a8c591f5642";
|
|
37
37
|
};
|
|
38
|
+
/** Exact bytes of a starter the publisher previously shipped for a seed type. */
|
|
39
|
+
type TypePackUpgradeBaseline = {
|
|
40
|
+
digest: string;
|
|
41
|
+
document: string;
|
|
42
|
+
/** The `version` the baseline document declares, for presentation only. */
|
|
43
|
+
version?: number;
|
|
44
|
+
};
|
|
38
45
|
export interface TypePackManifestResource {
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Previously shipped starters this seed type may be upgraded from; only valid
|
|
48
|
+
* for seed type resources. A single baseline is equivalent to a one-item list.
|
|
49
|
+
*/
|
|
50
|
+
upgrade_from?: TypePackUpgradeBaseline | TypePackUpgradeBaseline[];
|
|
44
51
|
kind: "contract" | "type" | "schema";
|
|
45
52
|
mode: "managed" | "seed";
|
|
46
53
|
source: string;
|
|
@@ -78,6 +85,11 @@ export interface TypePackResourceDiff {
|
|
|
78
85
|
current_digest?: string;
|
|
79
86
|
installed_digest?: string;
|
|
80
87
|
adopted_from_digest?: string;
|
|
88
|
+
/** The declared baseline an engine upgraded this seed from (seed `update` only). */
|
|
89
|
+
upgrade_baseline?: {
|
|
90
|
+
digest: string;
|
|
91
|
+
version?: number;
|
|
92
|
+
};
|
|
81
93
|
reason?: string;
|
|
82
94
|
}
|
|
83
95
|
export interface TypePackReceipt {
|
|
@@ -85,7 +97,10 @@ export interface TypePackReceipt {
|
|
|
85
97
|
version: string;
|
|
86
98
|
digest: string;
|
|
87
99
|
installed_by: string;
|
|
88
|
-
resources: Omit<TypePackResourceDiff, "action" | "current_digest" | "installed_digest" | "reason">
|
|
100
|
+
resources: Array<Omit<TypePackResourceDiff, "action" | "current_digest" | "installed_digest" | "upgrade_baseline" | "reason"> & {
|
|
101
|
+
/** Seed only: the publisher document the target descends from, when known. */
|
|
102
|
+
origin_digest?: string;
|
|
103
|
+
}>;
|
|
89
104
|
}
|
|
90
105
|
export interface TypePackAssessment {
|
|
91
106
|
status: "current" | "install" | "upgrade" | "downgrade" | "reconfigure" | "conflict";
|
|
@@ -136,3 +151,4 @@ export type ContractSetupChoice = {
|
|
|
136
151
|
fields: Record<string, string>;
|
|
137
152
|
binding?: Record<string, unknown>;
|
|
138
153
|
};
|
|
154
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mdbase-dev/connect-protocol",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.125",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"ajv": "^8.20.0",
|
|
31
|
-
"ajv-formats": "^3.0.1"
|
|
31
|
+
"ajv-formats": "^3.0.1",
|
|
32
|
+
"yaml": "^2.9.1"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@types/node": "^24.0.0",
|
|
@@ -1928,6 +1928,46 @@
|
|
|
1928
1928
|
}
|
|
1929
1929
|
}
|
|
1930
1930
|
},
|
|
1931
|
+
{
|
|
1932
|
+
"type": "object",
|
|
1933
|
+
"additionalProperties": false,
|
|
1934
|
+
"required": [
|
|
1935
|
+
"problem_version",
|
|
1936
|
+
"code",
|
|
1937
|
+
"category",
|
|
1938
|
+
"recovery",
|
|
1939
|
+
"message"
|
|
1940
|
+
],
|
|
1941
|
+
"properties": {
|
|
1942
|
+
"problem_version": {
|
|
1943
|
+
"const": 1
|
|
1944
|
+
},
|
|
1945
|
+
"code": {
|
|
1946
|
+
"const": "file_list_changed"
|
|
1947
|
+
},
|
|
1948
|
+
"category": {
|
|
1949
|
+
"const": "conflict"
|
|
1950
|
+
},
|
|
1951
|
+
"recovery": {
|
|
1952
|
+
"const": "refresh"
|
|
1953
|
+
},
|
|
1954
|
+
"message": {
|
|
1955
|
+
"type": "string",
|
|
1956
|
+
"minLength": 1
|
|
1957
|
+
},
|
|
1958
|
+
"operation_outcome": {
|
|
1959
|
+
"enum": [
|
|
1960
|
+
"not_sent",
|
|
1961
|
+
"rejected",
|
|
1962
|
+
"unknown"
|
|
1963
|
+
]
|
|
1964
|
+
},
|
|
1965
|
+
"trace_id": {
|
|
1966
|
+
"type": "string",
|
|
1967
|
+
"minLength": 1
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
},
|
|
1931
1971
|
{
|
|
1932
1972
|
"type": "object",
|
|
1933
1973
|
"additionalProperties": false,
|
|
@@ -194,6 +194,7 @@
|
|
|
194
194
|
"file_changed_during_move": { "category": "conflict", "recovery": "refresh" },
|
|
195
195
|
"file_changed_during_read": { "category": "conflict", "recovery": "refresh" },
|
|
196
196
|
"file_index_warming": { "category": "availability", "recovery": "retry" },
|
|
197
|
+
"file_list_changed": { "category": "conflict", "recovery": "refresh" },
|
|
197
198
|
"file_move_failed": { "category": "internal", "recovery": "contact_support" },
|
|
198
199
|
"file_mutation_conflict": { "category": "conflict", "recovery": "resolve_conflict" },
|
|
199
200
|
"file_not_found": { "category": "conflict", "recovery": "refresh" },
|
|
@@ -410,11 +410,27 @@
|
|
|
410
410
|
"properties": {
|
|
411
411
|
"kind": { "enum": ["contract", "type", "schema"] },
|
|
412
412
|
"mode": { "enum": ["managed", "seed"] },
|
|
413
|
+
"upgrade_from": {
|
|
414
|
+
"oneOf": [
|
|
415
|
+
{ "$ref": "#/$defs/typePackUpgradeBaseline" },
|
|
416
|
+
{ "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/typePackUpgradeBaseline" } }
|
|
417
|
+
]
|
|
418
|
+
},
|
|
413
419
|
"source": { "type": "string", "minLength": 1, "maxLength": 500 },
|
|
414
420
|
"target": { "type": "string", "minLength": 1, "maxLength": 500 },
|
|
415
421
|
"digest": { "$ref": "#/$defs/digest" }
|
|
416
422
|
}
|
|
417
423
|
},
|
|
424
|
+
"typePackUpgradeBaseline": {
|
|
425
|
+
"type": "object",
|
|
426
|
+
"additionalProperties": false,
|
|
427
|
+
"required": ["digest", "document"],
|
|
428
|
+
"properties": {
|
|
429
|
+
"digest": { "$ref": "#/$defs/digest" },
|
|
430
|
+
"document": { "type": "string", "maxLength": 262144 },
|
|
431
|
+
"version": { "type": "integer", "minimum": 1 }
|
|
432
|
+
}
|
|
433
|
+
},
|
|
418
434
|
"typePackSourceResource": {
|
|
419
435
|
"type": "object",
|
|
420
436
|
"additionalProperties": false,
|
|
@@ -674,12 +690,96 @@
|
|
|
674
690
|
"display_name": { "type": "string", "minLength": 1 },
|
|
675
691
|
"spec_version": { "type": "string", "minLength": 1 },
|
|
676
692
|
"operations": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/operation" } },
|
|
693
|
+
"authority_capabilities": { "type": "array", "items": { "type": "string" } },
|
|
677
694
|
"change_cursor": { "type": "integer", "minimum": 0 },
|
|
678
695
|
"types": { "type": "array", "items": { "$ref": "#/$defs/collectionType" } },
|
|
679
696
|
"contracts": { "type": "array", "items": { "$ref": "#/$defs/collectionContract" } },
|
|
680
697
|
"configuration": { "type": "object", "description": "Canonical portable collection settings. Extension and implementation-specific values are omitted." }
|
|
681
698
|
}
|
|
682
699
|
},
|
|
700
|
+
"dataContractSelector": {
|
|
701
|
+
"type": "object", "additionalProperties": false,
|
|
702
|
+
"required": ["id", "version"],
|
|
703
|
+
"properties": {
|
|
704
|
+
"id": { "type": "string" }, "version": { "type": "string" }, "type": { "type": "string" }
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
"readInput": {
|
|
708
|
+
"type": "object", "additionalProperties": false,
|
|
709
|
+
"properties": {
|
|
710
|
+
"path": { "type": "string", "minLength": 1 },
|
|
711
|
+
"paths": { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "minLength": 1 } },
|
|
712
|
+
"include_body": { "type": "boolean", "description": "Batch default true; point-read defaults unchanged." },
|
|
713
|
+
"include_document": { "type": "boolean", "default": false },
|
|
714
|
+
"contract": { "$ref": "#/$defs/dataContractSelector" }
|
|
715
|
+
},
|
|
716
|
+
"oneOf": [{ "required": ["path"] }, { "required": ["paths"] }],
|
|
717
|
+
"allOf": [{ "if": { "required": ["contract"] }, "then": { "properties": { "include_document": { "const": false } } } }]
|
|
718
|
+
},
|
|
719
|
+
"recordDocument": {
|
|
720
|
+
"type": "object", "additionalProperties": false,
|
|
721
|
+
"required": ["path", "revision", "types", "frontmatter", "effective_frontmatter", "file"],
|
|
722
|
+
"properties": {
|
|
723
|
+
"path": { "type": "string" }, "revision": { "type": "string" },
|
|
724
|
+
"types": { "type": "array", "items": { "type": "string" } },
|
|
725
|
+
"frontmatter": { "type": "object" }, "effective_frontmatter": { "type": "object" },
|
|
726
|
+
"body": { "type": "string" }, "document": { "type": "string" },
|
|
727
|
+
"file": { "type": "object" }, "contract": { "type": "object" }
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
"readManyDocumentItem": {
|
|
731
|
+
"oneOf": [
|
|
732
|
+
{
|
|
733
|
+
"type": "object", "additionalProperties": false, "required": ["path", "status", "record"],
|
|
734
|
+
"properties": { "path": { "type": "string" }, "status": { "const": "found" }, "record": { "$ref": "#/$defs/recordDocument" } }
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
"type": "object", "additionalProperties": false, "required": ["path", "status"],
|
|
738
|
+
"properties": { "path": { "type": "string" }, "status": { "const": "missing" } }
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
"type": "object", "additionalProperties": false, "required": ["path", "status", "error"],
|
|
742
|
+
"properties": {
|
|
743
|
+
"path": { "type": "string" }, "status": { "const": "error" },
|
|
744
|
+
"error": {
|
|
745
|
+
"type": "object", "additionalProperties": false, "required": ["code", "message"],
|
|
746
|
+
"properties": { "code": { "type": "string" }, "message": { "type": "string" } }
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
]
|
|
751
|
+
},
|
|
752
|
+
"readManyDocumentsResult": {
|
|
753
|
+
"description": "Ordered items including duplicates. Serialized operation envelope maximum 8 MiB; overflow fails explicitly and asks callers to split, never truncates.",
|
|
754
|
+
"type": "object", "additionalProperties": false, "required": ["items"],
|
|
755
|
+
"properties": { "items": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/readManyDocumentItem" } } }
|
|
756
|
+
},
|
|
757
|
+
"queryRecord": {
|
|
758
|
+
"type": "object", "additionalProperties": false, "required": ["path", "types", "file"],
|
|
759
|
+
"properties": {
|
|
760
|
+
"path": { "type": "string" }, "revision": { "type": "string" },
|
|
761
|
+
"types": { "type": "array", "items": { "type": "string" } },
|
|
762
|
+
"frontmatter": { "type": "object" }, "effective_frontmatter": { "type": "object" },
|
|
763
|
+
"body": { "type": "string" }, "values": { "type": "object" },
|
|
764
|
+
"file": { "type": "object" }, "contract": { "type": "object" }
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
"queryMetadataRecord": {
|
|
768
|
+
"type": "object", "additionalProperties": false, "required": ["path", "types", "revision", "values"],
|
|
769
|
+
"properties": {
|
|
770
|
+
"path": { "type": "string" }, "revision": { "type": "string" },
|
|
771
|
+
"types": { "type": "array", "items": { "type": "string" } },
|
|
772
|
+
"values": { "type": "object" }, "contract": { "type": "object" }
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
"queryMetadataResult": {
|
|
776
|
+
"type": "object", "additionalProperties": false, "required": ["output", "results"],
|
|
777
|
+
"properties": {
|
|
778
|
+
"output": { "const": "metadata" },
|
|
779
|
+
"results": { "type": "array", "items": { "$ref": "#/$defs/queryMetadataRecord" } },
|
|
780
|
+
"meta": { "type": "object" }
|
|
781
|
+
}
|
|
782
|
+
},
|
|
683
783
|
"collectionType": {
|
|
684
784
|
"type": "object",
|
|
685
785
|
"additionalProperties": false,
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
{ "$ref": "#/$defs/fileDescriptor" },
|
|
10
10
|
{ "$ref": "#/$defs/listFilesRequest" },
|
|
11
11
|
{ "$ref": "#/$defs/listFilesPage" },
|
|
12
|
+
{ "$ref": "#/$defs/statFileRequest" },
|
|
13
|
+
{ "$ref": "#/$defs/fileStat" },
|
|
12
14
|
{ "$ref": "#/$defs/openUploadRequest" },
|
|
13
15
|
{ "$ref": "#/$defs/openDownloadRequest" },
|
|
14
16
|
{ "$ref": "#/$defs/moveFileRequest" },
|
|
@@ -161,7 +163,30 @@
|
|
|
161
163
|
"protocol_version": { "const": 1 },
|
|
162
164
|
"type": { "const": "files_page" },
|
|
163
165
|
"files": { "type": "array", "items": { "$ref": "#/$defs/fileDescriptor" } },
|
|
164
|
-
"next": { "type": "string", "minLength": 1 }
|
|
166
|
+
"next": { "type": "string", "minLength": 1 },
|
|
167
|
+
"authority_capabilities": { "type": "array", "items": { "type": "string" } }
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"statFileRequest": {
|
|
171
|
+
"type": "object",
|
|
172
|
+
"additionalProperties": false,
|
|
173
|
+
"required": ["protocol_version", "type"],
|
|
174
|
+
"properties": {
|
|
175
|
+
"protocol_version": { "const": 1 },
|
|
176
|
+
"type": { "const": "stat_file" },
|
|
177
|
+
"path": { "$ref": "#/$defs/path" },
|
|
178
|
+
"file_id": { "$ref": "#/$defs/uuid" }
|
|
179
|
+
},
|
|
180
|
+
"oneOf": [{ "required": ["path"] }, { "required": ["file_id"] }]
|
|
181
|
+
},
|
|
182
|
+
"fileStat": {
|
|
183
|
+
"type": "object",
|
|
184
|
+
"additionalProperties": false,
|
|
185
|
+
"required": ["protocol_version", "type", "file"],
|
|
186
|
+
"properties": {
|
|
187
|
+
"protocol_version": { "const": 1 },
|
|
188
|
+
"type": { "const": "file_stat" },
|
|
189
|
+
"file": { "oneOf": [{ "$ref": "#/$defs/fileDescriptor" }, { "type": "null" }] }
|
|
165
190
|
}
|
|
166
191
|
},
|
|
167
192
|
"openUploadRequest": {
|
|
@@ -319,19 +319,26 @@
|
|
|
319
319
|
"kind": { "enum": ["contract", "type", "schema"] },
|
|
320
320
|
"mode": { "enum": ["managed", "seed"] },
|
|
321
321
|
"upgrade_from": {
|
|
322
|
-
"
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
"digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
|
|
327
|
-
"document": { "type": "string", "maxLength": 262144 }
|
|
328
|
-
}
|
|
322
|
+
"oneOf": [
|
|
323
|
+
{ "$ref": "#/$defs/typePackUpgradeBaseline" },
|
|
324
|
+
{ "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/typePackUpgradeBaseline" } }
|
|
325
|
+
]
|
|
329
326
|
},
|
|
330
327
|
"source": { "type": "string", "minLength": 1, "maxLength": 240 },
|
|
331
328
|
"target": { "type": "string", "minLength": 1, "maxLength": 240 },
|
|
332
329
|
"digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
|
|
333
330
|
}
|
|
334
331
|
},
|
|
332
|
+
"typePackUpgradeBaseline": {
|
|
333
|
+
"type": "object",
|
|
334
|
+
"additionalProperties": false,
|
|
335
|
+
"required": ["digest", "document"],
|
|
336
|
+
"properties": {
|
|
337
|
+
"digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
|
|
338
|
+
"document": { "type": "string", "maxLength": 262144 },
|
|
339
|
+
"version": { "type": "integer", "minimum": 1 }
|
|
340
|
+
}
|
|
341
|
+
},
|
|
335
342
|
"typePackSourceResource": {
|
|
336
343
|
"type": "object",
|
|
337
344
|
"additionalProperties": false,
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"limit": { "type": "integer", "minimum": 0 },
|
|
17
17
|
"offset": { "type": "integer", "minimum": 0 },
|
|
18
18
|
"include_body": { "type": "boolean", "default": false },
|
|
19
|
+
"output": { "const": "metadata" },
|
|
19
20
|
"frontmatter_mode": {
|
|
20
21
|
"enum": ["effective", "persisted", "both"],
|
|
21
22
|
"default": "effective"
|
|
@@ -25,6 +26,10 @@
|
|
|
25
26
|
"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" }
|
|
26
27
|
},
|
|
27
28
|
"additionalProperties": false,
|
|
29
|
+
"allOf": [{
|
|
30
|
+
"if": { "required": ["output"], "properties": { "output": { "const": "metadata" } } },
|
|
31
|
+
"then": { "properties": { "include_body": { "const": false } } }
|
|
32
|
+
}],
|
|
28
33
|
"$defs": {
|
|
29
34
|
"identifier": {
|
|
30
35
|
"type": "string",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
],
|
|
32
32
|
"file_control_messages": [
|
|
33
33
|
{ "id": "list_files", "input_schema_version": 1, "mutation": false },
|
|
34
|
+
{ "id": "stat_file", "input_schema_version": 1, "mutation": false },
|
|
34
35
|
{ "id": "open_file_upload", "input_schema_version": 1, "mutation": true },
|
|
35
36
|
{ "id": "open_file_download", "input_schema_version": 1, "mutation": false },
|
|
36
37
|
{ "id": "move_file", "input_schema_version": 1, "mutation": true },
|
|
@@ -414,6 +414,23 @@
|
|
|
414
414
|
"schema_version": 1,
|
|
415
415
|
"identifier": null
|
|
416
416
|
},
|
|
417
|
+
{
|
|
418
|
+
"operation": "file_control",
|
|
419
|
+
"input": {
|
|
420
|
+
"type": "stat_file"
|
|
421
|
+
},
|
|
422
|
+
"schema_version": 1,
|
|
423
|
+
"identifier": null
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"operation": "file_control",
|
|
427
|
+
"input": {
|
|
428
|
+
"type": "stat_file",
|
|
429
|
+
"dry_run": true
|
|
430
|
+
},
|
|
431
|
+
"schema_version": 1,
|
|
432
|
+
"identifier": null
|
|
433
|
+
},
|
|
417
434
|
{
|
|
418
435
|
"operation": "file_control",
|
|
419
436
|
"input": {
|