kalup 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.
Files changed (145) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +4 -0
  3. package/README.md +68 -0
  4. package/bin/kalup.mjs +13 -0
  5. package/dist/commands-C--Xsk1p.mjs +16145 -0
  6. package/dist/commands.d.mts +191 -0
  7. package/dist/commands.mjs +2 -0
  8. package/dist/context-D10Syqfd.d.mts +1265 -0
  9. package/dist/host-BJWvo3sX.mjs +390 -0
  10. package/dist/host.d.mts +44 -0
  11. package/dist/host.mjs +2 -0
  12. package/dist/index.d.mts +1 -0
  13. package/dist/index.mjs +14 -0
  14. package/dist/schemas/blueprint-1.schema.json +151 -0
  15. package/dist/schemas/blueprints-lock-1.schema.json +76 -0
  16. package/dist/schemas/ir-1.schema.json +379 -0
  17. package/dist/schemas/plan-1.schema.json +868 -0
  18. package/dist/schemas/state-1.schema.json +98 -0
  19. package/docs/apply.md +64 -0
  20. package/docs/blueprints.md +86 -0
  21. package/docs/compare.md +73 -0
  22. package/docs/config.md +88 -0
  23. package/docs/dictionary.md +43 -0
  24. package/docs/errors/E_ACCEPT_UNMATCHED.md +17 -0
  25. package/docs/errors/E_APPROVAL_REQUIRED.md +17 -0
  26. package/docs/errors/E_APPROVE_CREDENTIAL.md +17 -0
  27. package/docs/errors/E_APPROVE_MISMATCH.md +17 -0
  28. package/docs/errors/E_AUTH.md +17 -0
  29. package/docs/errors/E_BAD_CHAIN.md +21 -0
  30. package/docs/errors/E_BINDING_CHANGED.md +17 -0
  31. package/docs/errors/E_BIOME_CONFIG.md +17 -0
  32. package/docs/errors/E_BLUEPRINT_ADDED.md +17 -0
  33. package/docs/errors/E_BLUEPRINT_COLLISION.md +17 -0
  34. package/docs/errors/E_BLUEPRINT_INTEGRITY.md +17 -0
  35. package/docs/errors/E_BLUEPRINT_LOCK.md +17 -0
  36. package/docs/errors/E_BLUEPRINT_ORIGINAL.md +17 -0
  37. package/docs/errors/E_BLUEPRINT_REF.md +17 -0
  38. package/docs/errors/E_BLUEPRINT_REQUIRES.md +17 -0
  39. package/docs/errors/E_BLUEPRINT_SCHEMA.md +17 -0
  40. package/docs/errors/E_BLUEPRINT_SOURCE.md +17 -0
  41. package/docs/errors/E_BLUEPRINT_UNKNOWN.md +17 -0
  42. package/docs/errors/E_BUDGET.md +17 -0
  43. package/docs/errors/E_CANCELLED.md +21 -0
  44. package/docs/errors/E_CONFIG_EXISTS.md +17 -0
  45. package/docs/errors/E_DAILY_LIMIT.md +17 -0
  46. package/docs/errors/E_DEFAULT_TARGET.md +17 -0
  47. package/docs/errors/E_DUPLICATE_ADDRESS.md +17 -0
  48. package/docs/errors/E_DUPLICATE_ALIAS.md +24 -0
  49. package/docs/errors/E_DUPLICATE_KEY.md +24 -0
  50. package/docs/errors/E_DUPLICATE_OPTION.md +25 -0
  51. package/docs/errors/E_DUPLICATE_PORTAL.md +24 -0
  52. package/docs/errors/E_FIRST_PULL.md +18 -0
  53. package/docs/errors/E_HS_PREFIX.md +21 -0
  54. package/docs/errors/E_HTTP.md +17 -0
  55. package/docs/errors/E_INCOMPLETE.md +23 -0
  56. package/docs/errors/E_IR_SCHEMA.md +18 -0
  57. package/docs/errors/E_JOURNAL_WRITE.md +17 -0
  58. package/docs/errors/E_KEY_COLLISION.md +22 -0
  59. package/docs/errors/E_KEY_INVALID.md +19 -0
  60. package/docs/errors/E_LIFECYCLE.md +23 -0
  61. package/docs/errors/E_LOCKED.md +17 -0
  62. package/docs/errors/E_LOCK_DIR.md +17 -0
  63. package/docs/errors/E_MISSING_EXPORT.md +17 -0
  64. package/docs/errors/E_MISSING_KEY.md +17 -0
  65. package/docs/errors/E_NOT_DATA.md +21 -0
  66. package/docs/errors/E_NO_CONFIG.md +17 -0
  67. package/docs/errors/E_NO_TARGETS.md +17 -0
  68. package/docs/errors/E_OVERRIDE_AMBIGUOUS.md +21 -0
  69. package/docs/errors/E_OVERRIDE_DEFINITION.md +26 -0
  70. package/docs/errors/E_OVERRIDE_NAME.md +23 -0
  71. package/docs/errors/E_PLAN_DELETE.md +17 -0
  72. package/docs/errors/E_PLAN_DESTINATION.md +17 -0
  73. package/docs/errors/E_PLAN_DIGEST.md +17 -0
  74. package/docs/errors/E_PLAN_INVALID.md +17 -0
  75. package/docs/errors/E_PLAN_RISK.md +17 -0
  76. package/docs/errors/E_PLAN_SCHEMA.md +17 -0
  77. package/docs/errors/E_PLAN_STALE.md +17 -0
  78. package/docs/errors/E_PLAN_VERSION.md +18 -0
  79. package/docs/errors/E_POLICY_CHANGED.md +17 -0
  80. package/docs/errors/E_PORTAL_ID.md +17 -0
  81. package/docs/errors/E_PREVENT_DESTROY.md +17 -0
  82. package/docs/errors/E_PROJECT_WRITE.md +17 -0
  83. package/docs/errors/E_PROTECTED_SAVED_PLAN.md +17 -0
  84. package/docs/errors/E_PULL_INVALID.md +20 -0
  85. package/docs/errors/E_RATE_LIMIT.md +17 -0
  86. package/docs/errors/E_REBIND_STANDARD.md +17 -0
  87. package/docs/errors/E_REFERENCE_DEFINITION.md +21 -0
  88. package/docs/errors/E_RM_DEPENDENTS.md +17 -0
  89. package/docs/errors/E_SCOPE.md +17 -0
  90. package/docs/errors/E_SETTING_LEVEL.md +21 -0
  91. package/docs/errors/E_SETTING_VALUE.md +23 -0
  92. package/docs/errors/E_SNAPSHOT.md +17 -0
  93. package/docs/errors/E_STANDARD_OBJECT.md +21 -0
  94. package/docs/errors/E_STATE_CHANGED.md +19 -0
  95. package/docs/errors/E_STATE_CONFLICT.md +17 -0
  96. package/docs/errors/E_STATE_INVALID.md +17 -0
  97. package/docs/errors/E_STATE_SCHEMA.md +17 -0
  98. package/docs/errors/E_STATE_WRITE.md +19 -0
  99. package/docs/errors/E_STRICT_WITHOUT_OPTIONS.md +21 -0
  100. package/docs/errors/E_TAKE_UNMATCHED.md +19 -0
  101. package/docs/errors/E_TARGET_NAME.md +17 -0
  102. package/docs/errors/E_TARGET_PORTAL_MISMATCH.md +19 -0
  103. package/docs/errors/E_TARGET_REQUIRED.md +17 -0
  104. package/docs/errors/E_TOMBSTONE_ADDRESS.md +23 -0
  105. package/docs/errors/E_TOMBSTONE_CONFLICT.md +17 -0
  106. package/docs/errors/E_TYPE_FIELDTYPE.md +21 -0
  107. package/docs/errors/E_UNCERTAIN_WRITE.md +17 -0
  108. package/docs/errors/E_UNEXPECTED.md +17 -0
  109. package/docs/errors/E_UNKNOWN_BUILDER.md +21 -0
  110. package/docs/errors/E_UNKNOWN_GROUP.md +21 -0
  111. package/docs/errors/E_UNKNOWN_INCLUDE.md +17 -0
  112. package/docs/errors/E_UNKNOWN_OBJECT.md +17 -0
  113. package/docs/errors/E_UNKNOWN_OVERRIDE.md +17 -0
  114. package/docs/errors/E_UNKNOWN_TARGET.md +17 -0
  115. package/docs/errors/E_UNREACHABLE.md +17 -0
  116. package/docs/errors/E_UNSUPPORTED_FILE.md +17 -0
  117. package/docs/errors/E_USAGE.md +17 -0
  118. package/docs/errors/E_WRITE_IN_READ_MODE.md +17 -0
  119. package/docs/errors/E_WRITE_NOT_ALLOWED.md +17 -0
  120. package/docs/errors/W_BLUEPRINT_DOWNGRADE.md +17 -0
  121. package/docs/errors/W_CODEC_MISMATCH.md +18 -0
  122. package/docs/errors/W_INCOMPLETE.md +19 -0
  123. package/docs/errors/W_JSON_FIELDTYPE.md +17 -0
  124. package/docs/errors/W_KEY_COLLISION.md +17 -0
  125. package/docs/errors/W_LARGE_SCOPE.md +23 -0
  126. package/docs/errors/W_LIMIT_HEADROOM.md +19 -0
  127. package/docs/errors/W_LIMIT_UNREADABLE.md +17 -0
  128. package/docs/errors/W_MODE_SHADOWED.md +17 -0
  129. package/docs/errors/W_OVERRIDE_OPTION.md +17 -0
  130. package/docs/errors/W_PIN_EXPIRES.md +17 -0
  131. package/docs/errors/W_PREFIX.md +17 -0
  132. package/docs/errors/W_RATE_HEADERS.md +21 -0
  133. package/docs/errors/W_RATE_LIMIT.md +17 -0
  134. package/docs/errors/W_UNADDRESSABLE_NAME.md +21 -0
  135. package/docs/errors/W_UNFINISHED_APPLY.md +19 -0
  136. package/docs/errors/W_UNRESOLVED.md +17 -0
  137. package/docs/errors/W_UNSUPPORTED_TYPE.md +19 -0
  138. package/docs/errors/W_UNVERIFIED.md +17 -0
  139. package/docs/plan.md +85 -0
  140. package/docs/pull.md +83 -0
  141. package/docs/rm.md +44 -0
  142. package/docs/snapshot.md +52 -0
  143. package/docs/state.md +37 -0
  144. package/docs/targets.md +58 -0
  145. package/package.json +86 -0
@@ -0,0 +1,379 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kalup.dev/schemas/ir-1.schema.json",
4
+ "title": "Kalup IR, version 1",
5
+ "description": "What a Kalup project's config files mean, derived by `kalup ir`, or what a portal holds, captured by `kalup snapshot` with an observation block. Change inside a version is additive and readers keep unknown fields, so the document and each resource accept fields this schema does not list. Below a resource everything is closed except `x` and the definition of a resource type this schema does not describe, which stays open until a later ir/1 release describes that type.",
6
+ "type": "object",
7
+ "required": ["irVersion", "project", "generator", "resources", "targets", "tombstones"],
8
+ "properties": {
9
+ "irVersion": { "const": 1 },
10
+ "project": { "type": "string" },
11
+ "generator": {
12
+ "type": "object",
13
+ "required": ["name", "version", "frontend"],
14
+ "properties": {
15
+ "name": { "type": "string" },
16
+ "version": { "type": "string" },
17
+ "frontend": { "enum": ["ts", "portal"] }
18
+ },
19
+ "additionalProperties": false
20
+ },
21
+ "resources": {
22
+ "type": "object",
23
+ "patternProperties": { "^[a-z]+:\\S+$": { "$ref": "#/$defs/resource" } },
24
+ "additionalProperties": false
25
+ },
26
+ "targets": {
27
+ "type": "object",
28
+ "additionalProperties": { "$ref": "#/$defs/target" }
29
+ },
30
+ "tombstones": {
31
+ "type": "object",
32
+ "patternProperties": { "^[a-z]+:\\S+$": { "$ref": "#/$defs/tombstone" } },
33
+ "additionalProperties": false
34
+ },
35
+ "observation": { "$ref": "#/$defs/observation" },
36
+ "x": { "type": "object" }
37
+ },
38
+ "allOf": [
39
+ {
40
+ "if": {
41
+ "required": ["generator"],
42
+ "properties": { "generator": { "required": ["frontend"], "properties": { "frontend": { "const": "portal" } } } }
43
+ },
44
+ "then": { "required": ["observation"] }
45
+ }
46
+ ],
47
+ "$defs": {
48
+ "address": {
49
+ "description": "'<type>:<path>', for example property:companies/billing_status.",
50
+ "type": "string",
51
+ "pattern": "^[a-z]+:\\S+$"
52
+ },
53
+ "ref": {
54
+ "description": "A logical reference, allowed anywhere inside a definition where HubSpot wants an ID.",
55
+ "type": "object",
56
+ "required": ["$ref"],
57
+ "properties": { "$ref": { "$ref": "#/$defs/address" } },
58
+ "additionalProperties": false
59
+ },
60
+ "resource": {
61
+ "type": "object",
62
+ "required": ["type", "managed"],
63
+ "properties": {
64
+ "type": { "type": "string" },
65
+ "managed": { "type": "boolean" },
66
+ "definition": { "type": "object" },
67
+ "lookup": { "type": "object", "additionalProperties": { "type": "string" } },
68
+ "binding": { "$ref": "#/$defs/binding" },
69
+ "lifecycle": { "$ref": "#/$defs/lifecycle" },
70
+ "provenance": { "$ref": "#/$defs/provenance" },
71
+ "x": { "type": "object" }
72
+ },
73
+ "allOf": [
74
+ {
75
+ "if": { "required": ["managed"], "properties": { "managed": { "const": true } } },
76
+ "then": { "required": ["definition"] }
77
+ },
78
+ {
79
+ "if": { "required": ["type"], "properties": { "type": { "const": "property" } } },
80
+ "then": { "properties": { "definition": { "$ref": "#/$defs/propertyFields" } } }
81
+ },
82
+ {
83
+ "if": {
84
+ "required": ["type", "managed"],
85
+ "properties": { "type": { "const": "property" }, "managed": { "const": true } }
86
+ },
87
+ "then": { "properties": { "definition": { "required": ["label", "group", "type", "fieldType"] } } }
88
+ },
89
+ {
90
+ "if": { "required": ["type"], "properties": { "type": { "const": "group" } } },
91
+ "then": { "properties": { "definition": { "$ref": "#/$defs/groupDefinition" } } }
92
+ },
93
+ {
94
+ "if": { "required": ["type"], "properties": { "type": { "const": "object" } } },
95
+ "then": { "properties": { "definition": { "$ref": "#/$defs/objectDefinition" } } }
96
+ }
97
+ ]
98
+ },
99
+ "propertyFields": {
100
+ "description": "A property definition in HubSpot terms. A managed property needs label, group, type and fieldType; an unmanaged one may carry any subset, such as the options of a HubSpot-defined enumeration.",
101
+ "type": "object",
102
+ "properties": {
103
+ "label": { "type": "string" },
104
+ "group": { "$ref": "#/$defs/ref" },
105
+ "type": { "enum": ["string", "number", "bool", "date", "datetime", "enumeration"] },
106
+ "fieldType": {
107
+ "enum": [
108
+ "text",
109
+ "textarea",
110
+ "file",
111
+ "phonenumber",
112
+ "number",
113
+ "booleancheckbox",
114
+ "select",
115
+ "radio",
116
+ "checkbox",
117
+ "date"
118
+ ]
119
+ },
120
+ "description": { "type": "string" },
121
+ "options": { "type": "array", "items": { "$ref": "#/$defs/option" } },
122
+ "hasUniqueValue": { "type": "boolean" },
123
+ "formField": { "type": "boolean" }
124
+ },
125
+ "additionalProperties": false
126
+ },
127
+ "option": {
128
+ "description": "One enumeration option. Array index is display order. The app alias lives in binding.aliases, never here.",
129
+ "type": "object",
130
+ "required": ["value", "label"],
131
+ "properties": {
132
+ "value": { "type": "string" },
133
+ "label": { "type": "string" },
134
+ "hidden": { "type": "boolean" },
135
+ "description": { "type": "string" }
136
+ },
137
+ "additionalProperties": false
138
+ },
139
+ "groupDefinition": {
140
+ "type": "object",
141
+ "required": ["label"],
142
+ "properties": { "label": { "type": "string" } },
143
+ "additionalProperties": false
144
+ },
145
+ "objectDefinition": {
146
+ "description": "A custom object schema. Its properties and groups are resources of their own.",
147
+ "type": "object",
148
+ "required": ["labels"],
149
+ "properties": {
150
+ "labels": {
151
+ "type": "object",
152
+ "required": ["singular", "plural"],
153
+ "properties": { "singular": { "type": "string" }, "plural": { "type": "string" } },
154
+ "additionalProperties": false
155
+ },
156
+ "primaryDisplayProperty": { "type": "string" },
157
+ "requiredProperties": { "type": "array", "items": { "type": "string" } },
158
+ "searchableProperties": { "type": "array", "items": { "type": "string" } },
159
+ "secondaryDisplayProperties": { "type": "array", "items": { "type": "string" } }
160
+ },
161
+ "additionalProperties": false
162
+ },
163
+ "binding": {
164
+ "description": "App terms, filled in by the loader. key and codec for properties, export for objects.",
165
+ "type": "object",
166
+ "properties": {
167
+ "key": { "type": "string" },
168
+ "codec": {
169
+ "enum": ["string", "number", "boolean", "date", "datetime", "enum", "multiEnum", "stringArray", "json"]
170
+ },
171
+ "aliases": { "type": "object", "additionalProperties": { "type": "string" } },
172
+ "required": { "type": "boolean" },
173
+ "readonly": { "type": "boolean" },
174
+ "strict": { "type": "boolean" },
175
+ "export": { "type": "string" }
176
+ },
177
+ "additionalProperties": false
178
+ },
179
+ "lifecycle": {
180
+ "type": "object",
181
+ "required": ["options"],
182
+ "properties": {
183
+ "options": { "enum": ["additive", "exact"] },
184
+ "removedOptions": { "type": "array", "items": { "type": "string" } },
185
+ "ignoreChanges": { "type": "array", "items": { "type": "string" } },
186
+ "preventDestroy": { "type": "boolean" }
187
+ },
188
+ "additionalProperties": false
189
+ },
190
+ "provenance": {
191
+ "description": "Merged from kalup/blueprints.lock.json by the loader. Absent means authored by hand.",
192
+ "type": "object",
193
+ "required": ["blueprint", "version", "sourceAddress", "prefix", "hash"],
194
+ "properties": {
195
+ "blueprint": { "type": "string" },
196
+ "version": { "type": "string" },
197
+ "sourceAddress": { "$ref": "#/$defs/address" },
198
+ "prefix": { "type": "string" },
199
+ "hash": { "type": "string" }
200
+ },
201
+ "additionalProperties": false
202
+ },
203
+ "target": {
204
+ "description": "One named portal. Credentials never enter the IR.",
205
+ "type": "object",
206
+ "required": ["portalId"],
207
+ "properties": {
208
+ "portalId": { "type": "integer", "minimum": 1 },
209
+ "protected": { "type": "boolean" },
210
+ "drift": { "enum": ["hold", "overwrite"] },
211
+ "adopt": {
212
+ "description": "What a plan does with a unit that has no base and differs. Default hold.",
213
+ "enum": ["hold", "overwrite"]
214
+ },
215
+ "allowDestroy": {
216
+ "description": "Whether a destroy tombstone or a takeover removal may delete in this portal. Default false.",
217
+ "type": "boolean"
218
+ },
219
+ "yesLimit": {
220
+ "description": "The most writes, adoptions and releases one --yes covers; 0 turns --yes off. Default 25.",
221
+ "type": "integer",
222
+ "minimum": 0,
223
+ "maximum": 1000
224
+ },
225
+ "overrides": {
226
+ "type": "object",
227
+ "patternProperties": { "^[a-z]+:\\S+$": { "$ref": "#/$defs/override" } },
228
+ "additionalProperties": false
229
+ }
230
+ },
231
+ "additionalProperties": false
232
+ },
233
+ "override": {
234
+ "type": "object",
235
+ "properties": {
236
+ "skip": { "const": true },
237
+ "name": { "type": "string" },
238
+ "definition": { "type": "object" },
239
+ "lookup": { "type": "object", "additionalProperties": { "type": "string" } }
240
+ },
241
+ "additionalProperties": false
242
+ },
243
+ "observation": {
244
+ "description": "What a snapshot read: the target, when, and how completely. A portal-frontend document requires it. observedAt is the one timestamp an ir/1 document carries.",
245
+ "type": "object",
246
+ "required": ["target", "observedAt", "coverage"],
247
+ "properties": {
248
+ "target": {
249
+ "type": "object",
250
+ "required": ["name", "portalId"],
251
+ "properties": { "name": { "type": "string" }, "portalId": { "type": "integer", "minimum": 1 } },
252
+ "additionalProperties": false
253
+ },
254
+ "observedAt": {
255
+ "description": "ISO 8601 in UTC, as Date.prototype.toISOString writes it.",
256
+ "type": "string",
257
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}([.][0-9]+)?Z$"
258
+ },
259
+ "coverage": { "$ref": "#/$defs/coverage" }
260
+ },
261
+ "additionalProperties": false
262
+ },
263
+ "coverage": {
264
+ "description": "What the read covered. Only a complete read proves that a resource is absent.",
265
+ "type": "object",
266
+ "required": ["complete", "objects", "otherObjects", "notCaptured"],
267
+ "properties": {
268
+ "complete": { "type": "boolean" },
269
+ "objects": {
270
+ "description": "One entry per config object key.",
271
+ "type": "object",
272
+ "additionalProperties": { "$ref": "#/$defs/objectCoverage" }
273
+ },
274
+ "otherObjects": {
275
+ "description": "Custom objects in the portal that config does not name, or unknown when the schemas list was not read.",
276
+ "type": ["array", "string"],
277
+ "items": { "type": "string" },
278
+ "if": { "type": "string" },
279
+ "then": { "const": "unknown" }
280
+ },
281
+ "notCaptured": {
282
+ "description": "Documented response fields Kalup does not capture, per resource type.",
283
+ "type": "object",
284
+ "required": ["property", "group", "object"],
285
+ "properties": {
286
+ "property": { "type": "array", "items": { "type": "string" } },
287
+ "group": { "type": "array", "items": { "type": "string" } },
288
+ "object": { "type": "array", "items": { "type": "string" } }
289
+ },
290
+ "additionalProperties": false
291
+ }
292
+ },
293
+ "additionalProperties": false
294
+ },
295
+ "objectCoverage": {
296
+ "type": "object",
297
+ "required": ["status"],
298
+ "properties": {
299
+ "status": { "enum": ["read", "unreadable", "absent", "excluded"] },
300
+ "missingScope": { "description": "Unreadable only.", "type": "string" },
301
+ "issue": { "description": "Unreadable only.", "type": "string" },
302
+ "objectTypeId": { "description": "A custom object that exists.", "type": "string" },
303
+ "outOfScope": {
304
+ "description": "Present properties outside the pull scope that config does not name.",
305
+ "type": "array",
306
+ "items": { "type": "string" }
307
+ },
308
+ "shadowed": {
309
+ "description": "Portal names equal to the local name of a renamed address, so not reported at it.",
310
+ "type": "array",
311
+ "items": { "type": "string" }
312
+ },
313
+ "unaddressable": {
314
+ "description": "Present properties config names that are in a group whose name no address can hold, so not captured. What they hold is unknown.",
315
+ "type": "array",
316
+ "items": { "type": "string" }
317
+ },
318
+ "unsupported": { "type": "array", "items": { "$ref": "#/$defs/unsupportedProperty" } },
319
+ "unsupportedSchema": {
320
+ "description": "A custom object HubSpot returned without a singular or plural label, its fields as returned. It is present but not a resource.",
321
+ "type": "object",
322
+ "required": ["labels"],
323
+ "properties": {
324
+ "labels": {
325
+ "type": "object",
326
+ "properties": { "singular": { "type": "string" }, "plural": { "type": "string" } },
327
+ "additionalProperties": false
328
+ },
329
+ "primaryDisplayProperty": { "type": "string" },
330
+ "requiredProperties": { "type": "array", "items": { "type": "string" } },
331
+ "searchableProperties": { "type": "array", "items": { "type": "string" } },
332
+ "secondaryDisplayProperties": { "type": "array", "items": { "type": "string" } }
333
+ },
334
+ "additionalProperties": false
335
+ },
336
+ "excluded": {
337
+ "description": "Addresses a skip override leaves out.",
338
+ "type": "array",
339
+ "items": { "$ref": "#/$defs/address" }
340
+ },
341
+ "renamed": {
342
+ "description": "Addresses a name override points at another portal name.",
343
+ "type": "object",
344
+ "patternProperties": { "^[a-z]+:\\S+$": { "type": "string" } },
345
+ "additionalProperties": false
346
+ }
347
+ },
348
+ "additionalProperties": false
349
+ },
350
+ "unsupportedProperty": {
351
+ "description": "A present property Kalup does not write: no builder carries its type or fieldType, or HubSpot fills its options (owner or externalOptions). It is compared like any property but is not a resource.",
352
+ "type": "object",
353
+ "required": ["name", "type", "fieldType", "label", "group", "hubspotDefined"],
354
+ "properties": {
355
+ "name": { "type": "string" },
356
+ "type": { "type": "string" },
357
+ "fieldType": { "type": "string" },
358
+ "label": { "type": "string" },
359
+ "group": { "$ref": "#/$defs/ref" },
360
+ "description": { "type": "string" },
361
+ "options": { "type": "array", "items": { "$ref": "#/$defs/option" } },
362
+ "hubspotDefined": { "type": "boolean" },
363
+ "externalOptions": { "type": "boolean" },
364
+ "referencedObjectType": { "type": "string" }
365
+ },
366
+ "additionalProperties": false
367
+ },
368
+ "tombstone": {
369
+ "description": "Written by `kalup rm`. destroy archives or deletes in the portal; release stops managing and leaves it.",
370
+ "type": "object",
371
+ "required": ["action"],
372
+ "properties": {
373
+ "action": { "enum": ["destroy", "release"] },
374
+ "reason": { "type": "string" }
375
+ },
376
+ "additionalProperties": false
377
+ }
378
+ }
379
+ }