@vev-software/atlas-contracts 0.1.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.
- package/dist/index.d.ts +341 -0
- package/dist/index.js +7 -0
- package/package.json +21 -0
- package/schemas/v1/asset.schema.json +78 -0
- package/schemas/v1/bundle.schema.json +411 -0
- package/schemas/v1/common.schema.json +129 -0
- package/schemas/v1/discovery-observation.schema.json +218 -0
- package/schemas/v1/import.schema.json +104 -0
- package/schemas/v1/landscape.schema.json +36 -0
- package/schemas/v1/relationship.schema.json +23 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public data model for VEV Atlas. Catalogue concepts only — no integration-criticality, EOL risk,
|
|
3
|
+
* portfolio scoring or AI review (those work with the data and live in the private Atlas core).
|
|
4
|
+
* See handbook 11 §1. Mirrors the authoritative JSON Schemas in `schemas/v1`.
|
|
5
|
+
*/
|
|
6
|
+
/** The atlas-contracts schema major version. */
|
|
7
|
+
export declare const CONTRACT_VERSION: "1";
|
|
8
|
+
export type AssetKind = "system" | "application" | "server" | "infrastructure" | "data-area" | "dataset" | "column";
|
|
9
|
+
export type Lifecycle = "draft" | "active" | "retired";
|
|
10
|
+
export type RelationshipType = "runs-on" | "hosts" | "connects-to" | "depends-on" | "part-of" | "joins-on";
|
|
11
|
+
/** A manual, lightweight classification: a key with an optional value. */
|
|
12
|
+
export interface Tag {
|
|
13
|
+
key: string;
|
|
14
|
+
value?: string | null;
|
|
15
|
+
}
|
|
16
|
+
/** Held application metadata. Cataloguing only. */
|
|
17
|
+
export interface ApplicationDetails {
|
|
18
|
+
version?: string | null;
|
|
19
|
+
vendor?: string | null;
|
|
20
|
+
businessOwner?: string | null;
|
|
21
|
+
}
|
|
22
|
+
/** Held server metadata. OS is a recorded fact, not an EOL/risk assessment (paid Atlas core). */
|
|
23
|
+
export interface ServerDetails {
|
|
24
|
+
hostname?: string | null;
|
|
25
|
+
environment?: string | null;
|
|
26
|
+
operatingSystem?: string | null;
|
|
27
|
+
}
|
|
28
|
+
/** Held infrastructure metadata. Cataloguing only. */
|
|
29
|
+
export interface InfrastructureDetails {
|
|
30
|
+
category?: string | null;
|
|
31
|
+
location?: string | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Held data-area (dataområde) metadata. Cataloguing only: `realisation` is free metadata
|
|
35
|
+
* (e.g. "microservice", "reference-catalogue", "spreadsheet"), not a locked vocabulary and not analysis.
|
|
36
|
+
*/
|
|
37
|
+
export interface DataAreaDetails {
|
|
38
|
+
realisation?: string | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Held dataset (datamodel) metadata. Physical name and ownership are recorded facts, never quality
|
|
42
|
+
* or classification verdicts (those are paid Atlas core).
|
|
43
|
+
*/
|
|
44
|
+
export interface DatasetDetails {
|
|
45
|
+
physicalName?: string | null;
|
|
46
|
+
owner?: string | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Held column (kolonne) metadata. The declared data type and nullability are recorded facts.
|
|
50
|
+
* NO analysis: no quality score, no classification verdict, no PII/sensitivity flag (paid Atlas core).
|
|
51
|
+
*/
|
|
52
|
+
export interface ColumnDetails {
|
|
53
|
+
dataType?: string | null;
|
|
54
|
+
nullable?: boolean | null;
|
|
55
|
+
}
|
|
56
|
+
/** A single catalogued asset. */
|
|
57
|
+
export interface Asset {
|
|
58
|
+
id: string;
|
|
59
|
+
kind: AssetKind;
|
|
60
|
+
name: string;
|
|
61
|
+
lifecycle: Lifecycle;
|
|
62
|
+
description?: string | null;
|
|
63
|
+
tags?: Tag[];
|
|
64
|
+
application?: ApplicationDetails;
|
|
65
|
+
server?: ServerDetails;
|
|
66
|
+
infrastructure?: InfrastructureDetails;
|
|
67
|
+
dataArea?: DataAreaDetails;
|
|
68
|
+
dataset?: DatasetDetails;
|
|
69
|
+
column?: ColumnDetails;
|
|
70
|
+
}
|
|
71
|
+
/** A manual, catalogue-level typed link between two assets. */
|
|
72
|
+
export interface Relationship {
|
|
73
|
+
id: string;
|
|
74
|
+
fromId: string;
|
|
75
|
+
toId: string;
|
|
76
|
+
type: RelationshipType;
|
|
77
|
+
description?: string | null;
|
|
78
|
+
}
|
|
79
|
+
/** Provenance for an export: what produced the document. Held metadata, not analysis. */
|
|
80
|
+
export interface Generator {
|
|
81
|
+
name: string;
|
|
82
|
+
version?: string | null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The export side of the portability surface: a whole landscape carried across a boundary as a
|
|
86
|
+
* self-consistent, resolved document. The matching import side is `ImportBundle`.
|
|
87
|
+
*/
|
|
88
|
+
export interface LandscapeDocument {
|
|
89
|
+
contractVersion: typeof CONTRACT_VERSION;
|
|
90
|
+
exportedAt?: string | null;
|
|
91
|
+
generator?: Generator | null;
|
|
92
|
+
assets: Asset[];
|
|
93
|
+
relationships?: Relationship[];
|
|
94
|
+
}
|
|
95
|
+
/** How an import bundle applies to the existing catalogue. */
|
|
96
|
+
export type ImportMode = "merge" | "replace";
|
|
97
|
+
/**
|
|
98
|
+
* An asset to import. Carries at least one of `id` (an existing Atlas id) or `externalId`
|
|
99
|
+
* (a source-system id) so it can be matched and referenced.
|
|
100
|
+
*/
|
|
101
|
+
export interface ImportAsset {
|
|
102
|
+
id?: string;
|
|
103
|
+
externalId?: string;
|
|
104
|
+
kind: AssetKind;
|
|
105
|
+
name: string;
|
|
106
|
+
lifecycle: Lifecycle;
|
|
107
|
+
description?: string | null;
|
|
108
|
+
tags?: Tag[];
|
|
109
|
+
application?: ApplicationDetails;
|
|
110
|
+
server?: ServerDetails;
|
|
111
|
+
infrastructure?: InfrastructureDetails;
|
|
112
|
+
dataArea?: DataAreaDetails;
|
|
113
|
+
dataset?: DatasetDetails;
|
|
114
|
+
column?: ColumnDetails;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* A manual relationship to import. Endpoints are references — an asset `id` or `externalId`
|
|
118
|
+
* present in the bundle (or already in the catalogue).
|
|
119
|
+
*/
|
|
120
|
+
export interface ImportRelationship {
|
|
121
|
+
id?: string;
|
|
122
|
+
fromRef: string;
|
|
123
|
+
toRef: string;
|
|
124
|
+
type: RelationshipType;
|
|
125
|
+
description?: string | null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The import side of the portability surface: a batch of catalogue assets and manual
|
|
129
|
+
* relationships moved into Atlas.
|
|
130
|
+
*/
|
|
131
|
+
export interface ImportBundle {
|
|
132
|
+
contractVersion: typeof CONTRACT_VERSION;
|
|
133
|
+
kind: "import";
|
|
134
|
+
mode?: ImportMode;
|
|
135
|
+
assets: ImportAsset[];
|
|
136
|
+
relationships?: ImportRelationship[];
|
|
137
|
+
}
|
|
138
|
+
/** How a discovery observation batch was collected. */
|
|
139
|
+
export type CollectionMethod = "agent" | "agentless";
|
|
140
|
+
/** Transport protocol of an observed port. */
|
|
141
|
+
export type PortProtocol = "tcp" | "udp";
|
|
142
|
+
/**
|
|
143
|
+
* Which scanner produced a batch. The authoritative tenant binding is the authenticated
|
|
144
|
+
* machine-principal at ingestion (a Fabric concern); `tenantRef` is an optional hint only.
|
|
145
|
+
*/
|
|
146
|
+
export interface ObservationSource {
|
|
147
|
+
agentId: string;
|
|
148
|
+
method: CollectionMethod;
|
|
149
|
+
version?: string | null;
|
|
150
|
+
tenantRef?: string | null;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* One durable correlation attribute: a key and its observed value (both required — unlike a
|
|
154
|
+
* `Tag`, a fingerprint carries no valueless keys).
|
|
155
|
+
*/
|
|
156
|
+
export interface FingerprintAttribute {
|
|
157
|
+
key: string;
|
|
158
|
+
value: string;
|
|
159
|
+
}
|
|
160
|
+
/** An observed listening port. A recorded fact, not a measured integration. */
|
|
161
|
+
export interface ObservedPort {
|
|
162
|
+
port: number;
|
|
163
|
+
protocol?: PortProtocol | null;
|
|
164
|
+
address?: string | null;
|
|
165
|
+
}
|
|
166
|
+
/** An observed running process or service. A recorded fact. */
|
|
167
|
+
export interface ObservedProcess {
|
|
168
|
+
name: string;
|
|
169
|
+
port?: number | null;
|
|
170
|
+
}
|
|
171
|
+
/** An observed installed runtime or package. A recorded fact, not an EOL/risk assessment. */
|
|
172
|
+
export interface ObservedPackage {
|
|
173
|
+
name: string;
|
|
174
|
+
version?: string | null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* A single raw sighting in the landscape. Facts only: no Atlas `id` and no `lifecycle` (the
|
|
178
|
+
* private reconciler assigns catalogue identity and state). Kind-specific held facts reuse the
|
|
179
|
+
* catalogue vocabulary; ports/processes/packages are extra observations, not catalogue analysis.
|
|
180
|
+
*/
|
|
181
|
+
export interface Observation {
|
|
182
|
+
observedId: string;
|
|
183
|
+
kind: AssetKind;
|
|
184
|
+
name: string;
|
|
185
|
+
fingerprint?: FingerprintAttribute[];
|
|
186
|
+
ports?: ObservedPort[];
|
|
187
|
+
processes?: ObservedProcess[];
|
|
188
|
+
packages?: ObservedPackage[];
|
|
189
|
+
tags?: Tag[];
|
|
190
|
+
firstSeen?: string | null;
|
|
191
|
+
lastSeen?: string | null;
|
|
192
|
+
application?: ApplicationDetails;
|
|
193
|
+
server?: ServerDetails;
|
|
194
|
+
infrastructure?: InfrastructureDetails;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The public wire format a discovery scanner emits into Atlas: a batch of raw observations that
|
|
198
|
+
* the private Atlas Enterprise reconciliation engine turns into catalogue assets.
|
|
199
|
+
*/
|
|
200
|
+
export interface DiscoveryObservationBatch {
|
|
201
|
+
contractVersion: typeof CONTRACT_VERSION;
|
|
202
|
+
kind: "discovery-observation";
|
|
203
|
+
source: ObservationSource;
|
|
204
|
+
observedAt: string;
|
|
205
|
+
observations: Observation[];
|
|
206
|
+
}
|
|
207
|
+
/** The layout format of a `Diagram`. */
|
|
208
|
+
export type DiagramFormat = "atlas-layout";
|
|
209
|
+
/** The digest algorithm of a `Digest`. */
|
|
210
|
+
export type DigestAlgorithm = "sha-256";
|
|
211
|
+
/** A category of state deliberately NOT portable through the bundle. */
|
|
212
|
+
export type ExcludedCategory = "secrets" | "live-credentials" | "entitlements" | "subscription" | "billing" | "audit-logs" | "telemetry";
|
|
213
|
+
/** Counts for the embedded landscape core. */
|
|
214
|
+
export interface LandscapeCounts {
|
|
215
|
+
assetCount: number;
|
|
216
|
+
relationshipCount: number;
|
|
217
|
+
}
|
|
218
|
+
/** Machine-checkable inventory of what an `AtlasBundle` carries. Counts must match section sizes. */
|
|
219
|
+
export interface BundleManifest {
|
|
220
|
+
landscape: LandscapeCounts;
|
|
221
|
+
diagramCount?: number;
|
|
222
|
+
attachmentCount?: number;
|
|
223
|
+
moduleCount?: number;
|
|
224
|
+
}
|
|
225
|
+
/** A public module the destination should have to consume a module data section. */
|
|
226
|
+
export interface ModuleRequirement {
|
|
227
|
+
id: string;
|
|
228
|
+
minVersion?: string | null;
|
|
229
|
+
}
|
|
230
|
+
/** Producer-declared compatibility floor and provenance. */
|
|
231
|
+
export interface BundleCompatibility {
|
|
232
|
+
/** Minimum atlas-contracts major a reader must implement to safely import. */
|
|
233
|
+
minReaderContractVersion: typeof CONTRACT_VERSION;
|
|
234
|
+
producerAtlasVersion?: string | null;
|
|
235
|
+
requiredModules?: ModuleRequirement[];
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Portable workspace display metadata. Presentation only: never tenant shell, subscription,
|
|
239
|
+
* entitlement, trial or billing state (recreated or remapped at the destination).
|
|
240
|
+
*/
|
|
241
|
+
export interface WorkspaceMetadata {
|
|
242
|
+
name: string;
|
|
243
|
+
slug?: string | null;
|
|
244
|
+
description?: string | null;
|
|
245
|
+
locale?: string | null;
|
|
246
|
+
timeZone?: string | null;
|
|
247
|
+
tags?: Tag[];
|
|
248
|
+
}
|
|
249
|
+
/** A placed asset in a diagram. Position is a held layout fact, not analysis. */
|
|
250
|
+
export interface DiagramNode {
|
|
251
|
+
ref: string;
|
|
252
|
+
x: number;
|
|
253
|
+
y: number;
|
|
254
|
+
label?: string | null;
|
|
255
|
+
}
|
|
256
|
+
/** A drawn relationship in a diagram. */
|
|
257
|
+
export interface DiagramEdge {
|
|
258
|
+
ref: string;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* A portable diagram: a held layout over the landscape. Node placements reference asset ids and
|
|
262
|
+
* edges reference relationship ids present in the embedded landscape; a rendered image, if any, is
|
|
263
|
+
* carried as an attachment via `renderRef`, not inline.
|
|
264
|
+
*/
|
|
265
|
+
export interface Diagram {
|
|
266
|
+
id: string;
|
|
267
|
+
name: string;
|
|
268
|
+
format: DiagramFormat;
|
|
269
|
+
description?: string | null;
|
|
270
|
+
nodes?: DiagramNode[];
|
|
271
|
+
edges?: DiagramEdge[];
|
|
272
|
+
renderRef?: string | null;
|
|
273
|
+
}
|
|
274
|
+
/** A content digest so the destination can verify out-of-band attachment bytes. */
|
|
275
|
+
export interface Digest {
|
|
276
|
+
algorithm: DigestAlgorithm;
|
|
277
|
+
value: string;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* One attachment listed by reference and integrity digest — never inline secret bytes. The bytes
|
|
281
|
+
* travel out of band; this entry lets the destination locate and verify them.
|
|
282
|
+
*/
|
|
283
|
+
export interface AttachmentManifestEntry {
|
|
284
|
+
id: string;
|
|
285
|
+
name: string;
|
|
286
|
+
mediaType: string;
|
|
287
|
+
byteSize: number;
|
|
288
|
+
digest: Digest;
|
|
289
|
+
attachedToRef?: string | null;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* A public module / extension data section. The bundle contract fixes only the envelope (which
|
|
293
|
+
* module, which of its contract versions); `data` is governed by that module's own public contract
|
|
294
|
+
* and is opaque here. The same exclusions apply — no secrets or entitlement state.
|
|
295
|
+
*/
|
|
296
|
+
export interface ModuleData {
|
|
297
|
+
id: string;
|
|
298
|
+
version: string;
|
|
299
|
+
itemCount?: number | null;
|
|
300
|
+
data?: Record<string, unknown>;
|
|
301
|
+
}
|
|
302
|
+
/** One identity-mapping placeholder. Carries references and hints, never credentials. */
|
|
303
|
+
export interface IdentityMapping {
|
|
304
|
+
sourceRef: string;
|
|
305
|
+
displayName?: string | null;
|
|
306
|
+
bindHint?: string | null;
|
|
307
|
+
}
|
|
308
|
+
/** One secret-rebind instruction. Names what must be re-provided, never the value. */
|
|
309
|
+
export interface SecretRebind {
|
|
310
|
+
ref: string;
|
|
311
|
+
instruction?: string | null;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Non-data instructions for reconstructing the workspace at the destination. Placeholders and
|
|
315
|
+
* instructions only: never password/session material or secret values.
|
|
316
|
+
*/
|
|
317
|
+
export interface RestoreHints {
|
|
318
|
+
identityMappings?: IdentityMapping[];
|
|
319
|
+
secretRebinds?: SecretRebind[];
|
|
320
|
+
notes?: string | null;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* The public, versioned portable Atlas bundle: a self-contained migration package layered on top of
|
|
324
|
+
* the landscape export (`LandscapeDocument`). Carries the resolved landscape plus the Atlas-domain
|
|
325
|
+
* metadata a hosted <-> self-hosted move needs, without becoming a private hosted-only escape hatch.
|
|
326
|
+
*/
|
|
327
|
+
export interface AtlasBundle {
|
|
328
|
+
contractVersion: typeof CONTRACT_VERSION;
|
|
329
|
+
kind: "atlas-bundle";
|
|
330
|
+
manifest: BundleManifest;
|
|
331
|
+
landscape: LandscapeDocument;
|
|
332
|
+
createdAt?: string | null;
|
|
333
|
+
generator?: Generator | null;
|
|
334
|
+
compatibility?: BundleCompatibility | null;
|
|
335
|
+
workspace?: WorkspaceMetadata | null;
|
|
336
|
+
diagrams?: Diagram[];
|
|
337
|
+
attachments?: AttachmentManifestEntry[];
|
|
338
|
+
modules?: ModuleData[];
|
|
339
|
+
restore?: RestoreHints | null;
|
|
340
|
+
excluded?: ExcludedCategory[];
|
|
341
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public data model for VEV Atlas. Catalogue concepts only — no integration-criticality, EOL risk,
|
|
3
|
+
* portfolio scoring or AI review (those work with the data and live in the private Atlas core).
|
|
4
|
+
* See handbook 11 §1. Mirrors the authoritative JSON Schemas in `schemas/v1`.
|
|
5
|
+
*/
|
|
6
|
+
/** The atlas-contracts schema major version. */
|
|
7
|
+
export const CONTRACT_VERSION = "1";
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vev-software/atlas-contracts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Public, versioned data model and interop contracts for VEV Atlas — the catalogue asset model plus manual relationships, tags and the landscape import/export document.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": ["dist", "schemas"],
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/Vev-software/atlas-contracts"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc -p tsconfig.json",
|
|
16
|
+
"prepack": "node scripts/prepack.mjs"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^7.0.2"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://contracts.vev.software/atlas/v1/asset.schema.json",
|
|
4
|
+
"title": "Atlas asset (v1)",
|
|
5
|
+
"description": "A single catalogued asset: a system, application, server or infrastructure item, plus manual tags. Kind-specific attributes are held facts (e.g. a server's OS name), never analysis (no EOL dates/risk, no criticality). See handbook 11 §1.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"unevaluatedProperties": false,
|
|
8
|
+
"required": ["id", "kind", "name", "lifecycle"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"id": { "$ref": "common.schema.json#/$defs/AssetId" },
|
|
11
|
+
"kind": { "$ref": "common.schema.json#/$defs/AssetKind" },
|
|
12
|
+
"name": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"minLength": 1,
|
|
15
|
+
"maxLength": 256
|
|
16
|
+
},
|
|
17
|
+
"description": {
|
|
18
|
+
"type": ["string", "null"],
|
|
19
|
+
"maxLength": 4096
|
|
20
|
+
},
|
|
21
|
+
"lifecycle": { "$ref": "common.schema.json#/$defs/Lifecycle" },
|
|
22
|
+
"tags": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"items": { "$ref": "common.schema.json#/$defs/Tag" },
|
|
25
|
+
"default": []
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"allOf": [
|
|
29
|
+
{
|
|
30
|
+
"if": { "properties": { "kind": { "const": "application" } } },
|
|
31
|
+
"then": {
|
|
32
|
+
"properties": {
|
|
33
|
+
"application": { "$ref": "common.schema.json#/$defs/ApplicationDetails" }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"if": { "properties": { "kind": { "const": "server" } } },
|
|
39
|
+
"then": {
|
|
40
|
+
"properties": {
|
|
41
|
+
"server": { "$ref": "common.schema.json#/$defs/ServerDetails" }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"if": { "properties": { "kind": { "const": "infrastructure" } } },
|
|
47
|
+
"then": {
|
|
48
|
+
"properties": {
|
|
49
|
+
"infrastructure": { "$ref": "common.schema.json#/$defs/InfrastructureDetails" }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"if": { "properties": { "kind": { "const": "data-area" } } },
|
|
55
|
+
"then": {
|
|
56
|
+
"properties": {
|
|
57
|
+
"dataArea": { "$ref": "common.schema.json#/$defs/DataAreaDetails" }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"if": { "properties": { "kind": { "const": "dataset" } } },
|
|
63
|
+
"then": {
|
|
64
|
+
"properties": {
|
|
65
|
+
"dataset": { "$ref": "common.schema.json#/$defs/DatasetDetails" }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"if": { "properties": { "kind": { "const": "column" } } },
|
|
71
|
+
"then": {
|
|
72
|
+
"properties": {
|
|
73
|
+
"column": { "$ref": "common.schema.json#/$defs/ColumnDetails" }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|