@siloy/hubspot-provisioning 0.0.0-stage → 0.1.1

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -2
  3. package/dist/engine/src/blueprint/associations.d.ts +17 -0
  4. package/dist/engine/src/blueprint/associations.js +22 -0
  5. package/dist/engine/src/blueprint/field-types.d.ts +14 -0
  6. package/dist/engine/src/blueprint/field-types.js +22 -0
  7. package/dist/engine/src/blueprint/formula.d.ts +25 -0
  8. package/dist/engine/src/blueprint/formula.js +106 -0
  9. package/dist/engine/src/blueprint/groups.d.ts +16 -0
  10. package/dist/engine/src/blueprint/groups.js +30 -0
  11. package/dist/engine/src/blueprint/index.d.ts +10 -0
  12. package/dist/engine/src/blueprint/index.js +11 -0
  13. package/dist/engine/src/blueprint/mapping-targets.d.ts +10 -0
  14. package/dist/engine/src/blueprint/mapping-targets.js +5 -0
  15. package/dist/engine/src/blueprint/object-names.d.ts +11 -0
  16. package/dist/engine/src/blueprint/object-names.js +22 -0
  17. package/dist/engine/src/blueprint/pipelines.d.ts +40 -0
  18. package/dist/engine/src/blueprint/pipelines.js +99 -0
  19. package/dist/engine/src/blueprint/schema.d.ts +422 -0
  20. package/dist/engine/src/blueprint/schema.js +163 -0
  21. package/dist/engine/src/blueprint/serialize.d.ts +22 -0
  22. package/dist/engine/src/blueprint/serialize.js +70 -0
  23. package/dist/engine/src/blueprint/validate.d.ts +35 -0
  24. package/dist/engine/src/blueprint/validate.js +385 -0
  25. package/dist/engine/src/errors.d.ts +40 -0
  26. package/dist/engine/src/errors.js +73 -0
  27. package/dist/provisioning/src/api/client.d.ts +36 -0
  28. package/dist/provisioning/src/api/client.js +186 -0
  29. package/dist/provisioning/src/api/commit.d.ts +13 -0
  30. package/dist/provisioning/src/api/commit.js +12 -0
  31. package/dist/provisioning/src/api/types.d.ts +98 -0
  32. package/dist/provisioning/src/api/types.js +5 -0
  33. package/dist/provisioning/src/cli/commands.d.ts +16 -0
  34. package/dist/provisioning/src/cli/commands.js +373 -0
  35. package/dist/provisioning/src/cli/hints.d.ts +4 -0
  36. package/dist/provisioning/src/cli/hints.js +21 -0
  37. package/dist/provisioning/src/cli/main.d.ts +2 -0
  38. package/dist/provisioning/src/cli/main.js +24 -0
  39. package/dist/provisioning/src/cli/render.d.ts +25 -0
  40. package/dist/provisioning/src/cli/render.js +149 -0
  41. package/dist/provisioning/src/index.d.ts +6 -0
  42. package/dist/provisioning/src/index.js +5 -0
  43. package/dist/provisioning/src/limits.d.ts +2 -0
  44. package/dist/provisioning/src/limits.js +2 -0
  45. package/dist/provisioning/src/targets.d.ts +16 -0
  46. package/dist/provisioning/src/targets.js +27 -0
  47. package/dist/provisioning/src/validate.d.ts +10 -0
  48. package/dist/provisioning/src/validate.js +15 -0
  49. package/dist/provisioning/src/version.d.ts +2 -0
  50. package/dist/provisioning/src/version.js +17 -0
  51. package/package.json +38 -4
  52. package/schema/blueprint.schema.json +420 -0
@@ -0,0 +1,27 @@
1
+ export { mappingTargetsSchema } from '../../engine/src/blueprint/index.js';
2
+ /**
3
+ * The offline part of the mapping-target check (#105): which targets the blueprint defines, and which are assumed to
4
+ * exist in HubSpot. `assumed` is sorted by object type, then property, `null` first; a missing object is listed once.
5
+ */
6
+ export function checkMappingTargets(blueprint, targets) {
7
+ const defined = [];
8
+ const assumed = [];
9
+ for (const { objectType, properties } of targets) {
10
+ const object = blueprint.objects.find((o) => o.objectType === objectType);
11
+ if (!object) {
12
+ assumed.push({ objectType, property: null });
13
+ continue;
14
+ }
15
+ const names = new Set(object.properties.map((p) => p.name));
16
+ const inBlueprint = properties.filter((property) => names.has(property));
17
+ if (inBlueprint.length > 0)
18
+ defined.push({ objectType, properties: inBlueprint });
19
+ for (const property of properties)
20
+ if (!names.has(property))
21
+ assumed.push({ objectType, property });
22
+ }
23
+ assumed.sort((a, b) => compare(a.objectType, b.objectType) || compareProperty(a.property, b.property));
24
+ return { defined, assumed };
25
+ }
26
+ const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
27
+ const compareProperty = (a, b) => (a === b ? 0 : a === null ? -1 : b === null ? 1 : compare(a, b));
@@ -0,0 +1,10 @@
1
+ import { type Blueprint } from '../../engine/src/blueprint/index.ts';
2
+ export type ValidationResult = {
3
+ ok: true;
4
+ blueprint: Blueprint;
5
+ } | {
6
+ ok: false;
7
+ issues: string[];
8
+ };
9
+ /** Parse + validate exactly as the server's import does (parseBlueprintText in apps/web). Never throws on bad input. */
10
+ export declare function validateBlueprintText(text: string): ValidationResult;
@@ -0,0 +1,15 @@
1
+ import { parseBlueprint } from '../../engine/src/blueprint/index.js';
2
+ import { BlueprintError } from '../../engine/src/errors.js';
3
+ /** Parse + validate exactly as the server's import does (parseBlueprintText in apps/web). Never throws on bad input. */
4
+ export function validateBlueprintText(text) {
5
+ if (text.trim() === '')
6
+ return { ok: false, issues: ['The blueprint is empty.'] };
7
+ try {
8
+ return { ok: true, blueprint: parseBlueprint(text) };
9
+ }
10
+ catch (error) {
11
+ if (error instanceof BlueprintError)
12
+ return { ok: false, issues: error.issues };
13
+ throw error;
14
+ }
15
+ }
@@ -0,0 +1,2 @@
1
+ /** This package's version, from its package.json: the nearest one above both src/ and dist/provisioning/src/. */
2
+ export declare const CLI_VERSION: string;
@@ -0,0 +1,17 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /** This package's version, from its package.json: the nearest one above both src/ and dist/provisioning/src/. */
5
+ export const CLI_VERSION = readOwnVersion();
6
+ function readOwnVersion() {
7
+ let dir = dirname(fileURLToPath(import.meta.url));
8
+ for (;;) {
9
+ const file = join(dir, 'package.json');
10
+ if (existsSync(file))
11
+ return JSON.parse(readFileSync(file, 'utf8')).version;
12
+ const parent = dirname(dir);
13
+ if (parent === dir)
14
+ throw new Error('@siloy/hubspot-provisioning: package.json not found');
15
+ dir = parent;
16
+ }
17
+ }
package/package.json CHANGED
@@ -1,6 +1,40 @@
1
1
  {
2
2
  "name": "@siloy/hubspot-provisioning",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "Validate HubSpot provisioning blueprints offline and deploy them from CI.",
5
+ "type": "module",
6
+ "engines": { "node": ">=20" },
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Conversion-Crew/cc-hubspot-provisioning.git",
10
+ "directory": "packages/provisioning"
11
+ },
12
+ "publishConfig": { "access": "public" },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/provisioning/src/index.d.ts",
16
+ "default": "./dist/provisioning/src/index.js"
17
+ },
18
+ "./schema.json": "./schema/blueprint.schema.json"
19
+ },
20
+ "bin": {
21
+ "hubspot-provisioning": "./dist/provisioning/src/cli/main.js"
22
+ },
23
+ "license": "MIT",
24
+ "files": ["dist", "schema", "README.md", "LICENSE"],
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.build.json && node scripts/write-schema.ts",
27
+ "prepack": "node -e \"for (const d of ['dist', 'schema']) require('node:fs').rmSync(d, { recursive: true, force: true })\" && pnpm run build",
28
+ "test": "vitest run",
29
+ "typecheck": "tsc --noEmit -p tsconfig.json"
30
+ },
31
+ "dependencies": {
32
+ "yaml": "2.9.1",
33
+ "zod": "4.6.7"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "24.19.2",
37
+ "typescript": "7.0.2",
38
+ "vitest": "5.0.5"
39
+ }
40
+ }
@@ -0,0 +1,420 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "format": {
6
+ "type": "string",
7
+ "const": "hubspot-blueprint/v1"
8
+ },
9
+ "source": {
10
+ "type": "object",
11
+ "properties": {
12
+ "portalId": {
13
+ "type": "integer",
14
+ "minimum": -9007199254740991,
15
+ "maximum": 9007199254740991
16
+ },
17
+ "ingestedAt": {
18
+ "type": "string"
19
+ }
20
+ },
21
+ "required": [
22
+ "portalId",
23
+ "ingestedAt"
24
+ ],
25
+ "additionalProperties": false
26
+ },
27
+ "objects": {
28
+ "type": "array",
29
+ "items": {
30
+ "type": "object",
31
+ "properties": {
32
+ "objectType": {
33
+ "type": "string",
34
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
35
+ },
36
+ "schema": {
37
+ "type": "object",
38
+ "properties": {
39
+ "labels": {
40
+ "type": "object",
41
+ "properties": {
42
+ "singular": {
43
+ "type": "string",
44
+ "minLength": 1
45
+ },
46
+ "plural": {
47
+ "type": "string",
48
+ "minLength": 1
49
+ }
50
+ },
51
+ "required": [
52
+ "singular",
53
+ "plural"
54
+ ],
55
+ "additionalProperties": false
56
+ },
57
+ "description": {
58
+ "type": "string"
59
+ },
60
+ "primaryDisplayProperty": {
61
+ "type": "string",
62
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
63
+ },
64
+ "secondaryDisplayProperties": {
65
+ "default": [],
66
+ "type": "array",
67
+ "items": {
68
+ "type": "string",
69
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
70
+ }
71
+ },
72
+ "requiredProperties": {
73
+ "default": [],
74
+ "type": "array",
75
+ "items": {
76
+ "type": "string",
77
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
78
+ }
79
+ },
80
+ "searchableProperties": {
81
+ "default": [],
82
+ "type": "array",
83
+ "items": {
84
+ "type": "string",
85
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
86
+ }
87
+ }
88
+ },
89
+ "required": [
90
+ "labels",
91
+ "primaryDisplayProperty"
92
+ ],
93
+ "additionalProperties": false
94
+ },
95
+ "labels": {
96
+ "type": "object",
97
+ "properties": {
98
+ "singular": {
99
+ "type": "string",
100
+ "minLength": 1
101
+ },
102
+ "plural": {
103
+ "type": "string",
104
+ "minLength": 1
105
+ }
106
+ },
107
+ "required": [
108
+ "singular",
109
+ "plural"
110
+ ],
111
+ "additionalProperties": false
112
+ },
113
+ "propertyGroups": {
114
+ "default": [],
115
+ "type": "array",
116
+ "items": {
117
+ "type": "object",
118
+ "properties": {
119
+ "name": {
120
+ "type": "string",
121
+ "pattern": "^[^/\\u0000-\\u001f\\u007f-\\u009f]{1,100}$"
122
+ },
123
+ "label": {
124
+ "type": "string",
125
+ "minLength": 1
126
+ },
127
+ "displayOrder": {
128
+ "type": "integer",
129
+ "minimum": -9007199254740991,
130
+ "maximum": 9007199254740991
131
+ }
132
+ },
133
+ "required": [
134
+ "name",
135
+ "label"
136
+ ],
137
+ "additionalProperties": false
138
+ }
139
+ },
140
+ "properties": {
141
+ "default": [],
142
+ "type": "array",
143
+ "items": {
144
+ "type": "object",
145
+ "properties": {
146
+ "name": {
147
+ "type": "string",
148
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
149
+ },
150
+ "origin": {
151
+ "default": "custom",
152
+ "type": "string",
153
+ "enum": [
154
+ "custom",
155
+ "hubspot"
156
+ ]
157
+ },
158
+ "label": {
159
+ "type": "string",
160
+ "minLength": 1
161
+ },
162
+ "type": {
163
+ "type": "string",
164
+ "enum": [
165
+ "string",
166
+ "number",
167
+ "date",
168
+ "datetime",
169
+ "enumeration",
170
+ "bool",
171
+ "phone_number"
172
+ ]
173
+ },
174
+ "fieldType": {
175
+ "type": "string",
176
+ "minLength": 1
177
+ },
178
+ "groupName": {
179
+ "type": "string",
180
+ "pattern": "^[^/\\u0000-\\u001f\\u007f-\\u009f]{1,100}$"
181
+ },
182
+ "description": {
183
+ "type": "string"
184
+ },
185
+ "displayOrder": {
186
+ "type": "integer",
187
+ "minimum": -9007199254740991,
188
+ "maximum": 9007199254740991
189
+ },
190
+ "hidden": {
191
+ "type": "boolean"
192
+ },
193
+ "formField": {
194
+ "type": "boolean"
195
+ },
196
+ "hasUniqueValue": {
197
+ "default": false,
198
+ "type": "boolean"
199
+ },
200
+ "referencedObjectType": {
201
+ "type": "string"
202
+ },
203
+ "externalOptions": {
204
+ "type": "boolean"
205
+ },
206
+ "calculationFormula": {
207
+ "type": "string",
208
+ "minLength": 1
209
+ },
210
+ "numberDisplayHint": {
211
+ "type": "string",
212
+ "minLength": 1
213
+ },
214
+ "showCurrencySymbol": {
215
+ "type": "boolean"
216
+ },
217
+ "options": {
218
+ "default": [],
219
+ "type": "array",
220
+ "items": {
221
+ "type": "object",
222
+ "properties": {
223
+ "value": {
224
+ "type": "string",
225
+ "minLength": 1
226
+ },
227
+ "label": {
228
+ "type": "string",
229
+ "minLength": 1
230
+ },
231
+ "displayOrder": {
232
+ "type": "integer",
233
+ "minimum": -9007199254740991,
234
+ "maximum": 9007199254740991
235
+ },
236
+ "hidden": {
237
+ "default": false,
238
+ "type": "boolean"
239
+ },
240
+ "description": {
241
+ "type": "string"
242
+ }
243
+ },
244
+ "required": [
245
+ "value",
246
+ "label"
247
+ ],
248
+ "additionalProperties": false
249
+ }
250
+ }
251
+ },
252
+ "required": [
253
+ "name",
254
+ "label",
255
+ "type",
256
+ "fieldType",
257
+ "groupName"
258
+ ],
259
+ "additionalProperties": false
260
+ }
261
+ },
262
+ "pipelines": {
263
+ "default": [],
264
+ "type": "array",
265
+ "items": {
266
+ "type": "object",
267
+ "properties": {
268
+ "key": {
269
+ "type": "string",
270
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
271
+ },
272
+ "origin": {
273
+ "default": "custom",
274
+ "type": "string",
275
+ "enum": [
276
+ "custom",
277
+ "hubspot"
278
+ ]
279
+ },
280
+ "label": {
281
+ "type": "string",
282
+ "minLength": 1
283
+ },
284
+ "displayOrder": {
285
+ "type": "integer",
286
+ "minimum": -9007199254740991,
287
+ "maximum": 9007199254740991
288
+ },
289
+ "stages": {
290
+ "minItems": 1,
291
+ "type": "array",
292
+ "items": {
293
+ "type": "object",
294
+ "properties": {
295
+ "key": {
296
+ "type": "string",
297
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
298
+ },
299
+ "label": {
300
+ "type": "string",
301
+ "minLength": 1
302
+ },
303
+ "metadata": {
304
+ "type": "object",
305
+ "properties": {
306
+ "probability": {
307
+ "type": "string",
308
+ "minLength": 1
309
+ },
310
+ "ticketState": {
311
+ "type": "string",
312
+ "minLength": 1
313
+ },
314
+ "state": {
315
+ "type": "string",
316
+ "minLength": 1
317
+ }
318
+ },
319
+ "additionalProperties": false
320
+ }
321
+ },
322
+ "required": [
323
+ "key",
324
+ "label",
325
+ "metadata"
326
+ ],
327
+ "additionalProperties": false
328
+ }
329
+ }
330
+ },
331
+ "required": [
332
+ "key",
333
+ "label",
334
+ "stages"
335
+ ],
336
+ "additionalProperties": false
337
+ }
338
+ }
339
+ },
340
+ "required": [
341
+ "objectType"
342
+ ],
343
+ "additionalProperties": false
344
+ }
345
+ },
346
+ "associations": {
347
+ "default": [],
348
+ "type": "array",
349
+ "items": {
350
+ "type": "object",
351
+ "properties": {
352
+ "from": {
353
+ "type": "string",
354
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
355
+ },
356
+ "to": {
357
+ "type": "string",
358
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
359
+ },
360
+ "limit": {
361
+ "type": "integer",
362
+ "minimum": 1,
363
+ "maximum": 10000
364
+ },
365
+ "inverseLimit": {
366
+ "type": "integer",
367
+ "minimum": 1,
368
+ "maximum": 10000
369
+ },
370
+ "labels": {
371
+ "default": [],
372
+ "type": "array",
373
+ "items": {
374
+ "type": "object",
375
+ "properties": {
376
+ "key": {
377
+ "type": "string",
378
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
379
+ },
380
+ "label": {
381
+ "type": "string",
382
+ "minLength": 1
383
+ },
384
+ "inverseLabel": {
385
+ "type": "string",
386
+ "minLength": 1
387
+ },
388
+ "limit": {
389
+ "type": "integer",
390
+ "minimum": 1,
391
+ "maximum": 10000
392
+ },
393
+ "inverseLimit": {
394
+ "type": "integer",
395
+ "minimum": 1,
396
+ "maximum": 10000
397
+ }
398
+ },
399
+ "required": [
400
+ "key",
401
+ "label"
402
+ ],
403
+ "additionalProperties": false
404
+ }
405
+ }
406
+ },
407
+ "required": [
408
+ "from",
409
+ "to"
410
+ ],
411
+ "additionalProperties": false
412
+ }
413
+ }
414
+ },
415
+ "required": [
416
+ "format",
417
+ "objects"
418
+ ],
419
+ "additionalProperties": false
420
+ }