@griffin-app/griffin-ts 0.1.9 → 0.1.11

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 (48) hide show
  1. package/dist/assertions.d.ts.map +1 -1
  2. package/dist/assertions.js +18 -6
  3. package/dist/assertions.js.map +1 -1
  4. package/dist/builder.d.ts.map +1 -1
  5. package/dist/builder.js +2 -2
  6. package/dist/builder.js.map +1 -1
  7. package/dist/builder.test.js +13 -6
  8. package/dist/builder.test.js.map +1 -1
  9. package/dist/frequency.test.js +80 -20
  10. package/dist/frequency.test.js.map +1 -1
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +8 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/migrations.d.ts +51 -0
  16. package/dist/migrations.d.ts.map +1 -0
  17. package/dist/migrations.js +92 -0
  18. package/dist/migrations.js.map +1 -0
  19. package/dist/migrations.test.d.ts +5 -0
  20. package/dist/migrations.test.d.ts.map +1 -0
  21. package/dist/migrations.test.js +127 -0
  22. package/dist/migrations.test.js.map +1 -0
  23. package/dist/schema-exports.d.ts +2 -1
  24. package/dist/schema-exports.d.ts.map +1 -1
  25. package/dist/schema-exports.js +5 -3
  26. package/dist/schema-exports.js.map +1 -1
  27. package/dist/schema.d.ts +439 -2
  28. package/dist/schema.d.ts.map +1 -1
  29. package/dist/schema.js +56 -7
  30. package/dist/schema.js.map +1 -1
  31. package/dist/secrets.test.js +4 -4
  32. package/dist/secrets.test.js.map +1 -1
  33. package/dist/sequential-builder.js +3 -3
  34. package/dist/sequential-builder.js.map +1 -1
  35. package/dist/sequential-builder.test.js +7 -11
  36. package/dist/sequential-builder.test.js.map +1 -1
  37. package/dist/variable.test.js +11 -11
  38. package/dist/variable.test.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/builder.test.ts +2 -2
  41. package/src/builder.ts +2 -2
  42. package/src/index.ts +36 -0
  43. package/src/migrations.test.ts +148 -0
  44. package/src/migrations.ts +120 -0
  45. package/src/schema-exports.ts +30 -2
  46. package/src/schema.ts +69 -5
  47. package/src/sequential-builder.test.ts +2 -2
  48. package/src/sequential-builder.ts +3 -3
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Migration framework for test plan versioning.
3
+ * Provides functions to migrate plans between different schema versions.
4
+ */
5
+
6
+ import { CURRENT_PLAN_VERSION, SUPPORTED_PLAN_VERSIONS } from "./schema.js";
7
+ import type { ResolvedPlan, ResolvedPlanV1 } from "./schema.js";
8
+
9
+ /**
10
+ * Type representing a migration function from one version to another
11
+ */
12
+ type MigrationFn<From = unknown, To = unknown> = (plan: From) => To;
13
+
14
+ /**
15
+ * Registry of all available migrations between versions
16
+ * Key format: "fromVersion->toVersion"
17
+ */
18
+ const migrations: Record<string, MigrationFn<any, any>> = {
19
+ // Future migrations will be added here
20
+ // Example: "1.0->2.0": migrateV1ToV2,
21
+ };
22
+
23
+ /**
24
+ * Get the next version in the supported versions list
25
+ */
26
+ function getNextVersion(currentVersion: string): string {
27
+ const versions = SUPPORTED_PLAN_VERSIONS as readonly string[];
28
+ const currentIndex = versions.indexOf(currentVersion);
29
+
30
+ if (currentIndex === -1) {
31
+ throw new Error(`Unsupported plan version: ${currentVersion}`);
32
+ }
33
+
34
+ if (currentIndex === versions.length - 1) {
35
+ throw new Error(
36
+ `No migration path available from version ${currentVersion}`,
37
+ );
38
+ }
39
+
40
+ return versions[currentIndex + 1];
41
+ }
42
+
43
+ /**
44
+ * Migrate a plan from its current version to a target version
45
+ *
46
+ * @param plan - Plan to migrate (must have a version field)
47
+ * @param targetVersion - Target version to migrate to
48
+ * @returns Migrated plan at target version
49
+ * @throws Error if no migration path exists
50
+ */
51
+ export function migratePlan<T>(
52
+ plan: { version: string },
53
+ targetVersion: string,
54
+ ): T {
55
+ let current: any = plan;
56
+
57
+ // Already at target version
58
+ if (current.version === targetVersion) {
59
+ return current as T;
60
+ }
61
+
62
+ // Migrate step by step through versions
63
+ while (current.version !== targetVersion) {
64
+ const nextVersion = getNextVersion(current.version);
65
+ const migrationKey = `${current.version}->${nextVersion}`;
66
+ const migrate = migrations[migrationKey];
67
+
68
+ if (!migrate) {
69
+ throw new Error(
70
+ `No migration path from version ${current.version} to ${nextVersion}`,
71
+ );
72
+ }
73
+
74
+ current = migrate(current);
75
+ }
76
+
77
+ return current as T;
78
+ }
79
+
80
+ /**
81
+ * Migrate a plan to the latest supported version
82
+ *
83
+ * @param plan - Plan to migrate (must have a version field)
84
+ * @returns Plan migrated to latest version
85
+ */
86
+ export function migrateToLatest(plan: { version: string }): ResolvedPlan {
87
+ return migratePlan<ResolvedPlan>(plan, CURRENT_PLAN_VERSION);
88
+ }
89
+
90
+ /**
91
+ * Check if a plan version is supported
92
+ *
93
+ * @param version - Version string to check
94
+ * @returns True if version is supported
95
+ */
96
+ export function isSupportedVersion(version: string): boolean {
97
+ return SUPPORTED_PLAN_VERSIONS.includes(version as any);
98
+ }
99
+
100
+ /**
101
+ * Get all supported plan versions
102
+ */
103
+ export function getSupportedVersions(): readonly string[] {
104
+ return SUPPORTED_PLAN_VERSIONS;
105
+ }
106
+
107
+ /**
108
+ * Example migration function template (for future use)
109
+ *
110
+ * Uncomment and modify when creating v2.0:
111
+ *
112
+ * function migrateV1ToV2(plan: ResolvedPlanV1): ResolvedPlanV2 {
113
+ * return {
114
+ * ...plan,
115
+ * version: "2.0",
116
+ * // Add/modify fields as needed for v2.0
117
+ * newField: "default value",
118
+ * };
119
+ * }
120
+ */
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  export {
7
- // Schema values
7
+ // Schema values - DSL (what users write)
8
8
  SecretRefDataSchema,
9
9
  SecretRefSchema,
10
10
  StringLiteralSchema,
@@ -19,6 +19,7 @@ export {
19
19
  XMLPathSchema,
20
20
  TextPathSchema,
21
21
  UnaryPredicateSchema,
22
+ UnaryPredicateOperatorSchema,
22
23
  BinaryPredicateOperatorSchema,
23
24
  BinaryPredicateSchema,
24
25
  AssertionSchema,
@@ -26,6 +27,14 @@ export {
26
27
  NodeDSLSchema,
27
28
  EdgeSchema,
28
29
  PlanDSLSchema,
30
+ PlanDSLSchemaV1,
31
+
32
+ // Schema values - Resolved (what hub/executor use)
33
+ ResolvedStringSchema,
34
+ HttpRequestResolvedSchema,
35
+ NodeResolvedSchema,
36
+ ResolvedPlanV1Schema,
37
+ ResolvedPlanSchema,
29
38
 
30
39
  // Enums (runtime values)
31
40
  FrequencyUnit,
@@ -36,5 +45,24 @@ export {
36
45
  BinaryPredicateOperator,
37
46
 
38
47
  // Constants
39
- TEST_PLAN_VERSION,
48
+ CURRENT_PLAN_VERSION,
49
+ SUPPORTED_PLAN_VERSIONS,
50
+ } from "./schema.js";
51
+
52
+ // Type exports
53
+ export type {
54
+ PlanDSL,
55
+ PlanDSLV1,
56
+ NodeDSL,
57
+ HttpRequestDSL,
58
+ Edge,
59
+ Frequency,
60
+ Assertion,
61
+ Assertions,
62
+ SecretRef,
63
+ VariableRef,
64
+ ResolvedPlan,
65
+ ResolvedPlanV1,
66
+ NodeResolved,
67
+ HttpRequestResolved,
40
68
  } from "./schema.js";
package/src/schema.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { Type, type Static } from "typebox";
2
2
  import { Ref, StringEnum } from "./shared.js";
3
3
 
4
- export const TEST_PLAN_VERSION = "1.0";
4
+ // Version constants
5
+ export const CURRENT_PLAN_VERSION = "1.0";
6
+ export const SUPPORTED_PLAN_VERSIONS = ["1.0"] as const;
5
7
 
6
8
  // Secret reference schema for values that may contain secrets
7
9
  export const SecretRefDataSchema = Type.Object({
@@ -311,21 +313,27 @@ export const EdgeSchema = Type.Object(
311
313
  { $id: "Edge" },
312
314
  );
313
315
 
314
- export const PlanDSLSchema = Type.Object(
316
+ // Version-specific DSL schemas
317
+ export const PlanDSLSchemaV1 = Type.Object(
315
318
  {
316
319
  locations: Type.Optional(Type.Array(Type.String())),
317
320
  name: Type.String(),
318
- version: Type.Literal(TEST_PLAN_VERSION),
321
+ version: Type.Literal("1.0"),
319
322
  frequency: FrequencySchema,
320
323
  nodes: Type.Array(NodeDSLSchema),
321
324
  edges: Type.Array(EdgeSchema),
322
325
  },
323
326
  {
324
- $id: "PlanDSL",
327
+ $id: "PlanDSLV1",
325
328
  },
326
329
  );
327
330
 
328
- export type PlanDSL = Static<typeof PlanDSLSchema>;
331
+ // Union schema for validation (accepts any supported version)
332
+ export const PlanDSLSchema = PlanDSLSchemaV1; // Currently only v1.0, will become union when v2.0 is added
333
+
334
+ // Type extraction
335
+ export type PlanDSLV1 = Static<typeof PlanDSLSchemaV1>;
336
+ export type PlanDSL = PlanDSLV1; // Currently only v1.0, will become union when v2.0 is added
329
337
  export type VariableRef = Static<typeof VariableRefSchema>;
330
338
  export type NodeDSL = Static<typeof NodeDSLSchema>;
331
339
  export type Edge = Static<typeof EdgeSchema>;
@@ -342,3 +350,59 @@ export type SecretRefData = Static<typeof SecretRefDataSchema>;
342
350
  export type StringLiteral = Static<typeof StringLiteralSchema>;
343
351
  export type String = Static<typeof StringSchema>;
344
352
  export type Frequency = Static<typeof FrequencySchema>;
353
+
354
+ // ============================================================================
355
+ // Resolved Plan Schemas (after variable resolution, used by hub/executor)
356
+ // ============================================================================
357
+
358
+ // Union type for resolved values (variables are resolved, only secrets/literals remain)
359
+ export const ResolvedStringSchema = Type.Union([
360
+ StringLiteralSchema,
361
+ SecretRefSchema,
362
+ ]);
363
+
364
+ export const HttpRequestResolvedSchema = Type.Object(
365
+ {
366
+ id: Type.String(),
367
+ type: Type.Literal(NodeType.HTTP_REQUEST),
368
+ method: HttpMethodSchema,
369
+ path: Type.String(),
370
+ base: Type.String(),
371
+ headers: Type.Optional(Type.Record(Type.String(), ResolvedStringSchema)),
372
+ body: Type.Optional(Type.Any()), // Body can contain nested SecretRefs
373
+ response_format: ResponseFormatSchema,
374
+ },
375
+ { $id: "HttpRequestResolved" },
376
+ );
377
+
378
+ export const NodeResolvedSchema = Type.Union(
379
+ [HttpRequestResolvedSchema, WaitSchema, AssertionsSchema],
380
+ { $id: "NodeResolved" },
381
+ );
382
+
383
+ // Version-specific resolved plan schemas
384
+ export const ResolvedPlanV1Schema = Type.Object(
385
+ {
386
+ project: Type.String(),
387
+ locations: Type.Optional(Type.Array(Type.String())),
388
+ id: Type.Readonly(Type.String()),
389
+ name: Type.String(),
390
+ version: Type.Literal("1.0"),
391
+ frequency: FrequencySchema,
392
+ environment: Type.String({ default: "default" }),
393
+ nodes: Type.Array(NodeResolvedSchema),
394
+ edges: Type.Array(EdgeSchema),
395
+ },
396
+ {
397
+ $id: "ResolvedPlanV1",
398
+ },
399
+ );
400
+
401
+ // Union of all supported resolved plan versions
402
+ export const ResolvedPlanSchema = ResolvedPlanV1Schema;
403
+
404
+ // Type exports for resolved plans
405
+ export type ResolvedPlanV1 = Static<typeof ResolvedPlanV1Schema>;
406
+ export type ResolvedPlan = ResolvedPlanV1;
407
+ export type HttpRequestResolved = Static<typeof HttpRequestResolvedSchema>;
408
+ export type NodeResolved = Static<typeof NodeResolvedSchema>;
@@ -9,7 +9,7 @@ import {
9
9
  HttpMethod,
10
10
  ResponseFormat,
11
11
  NodeType,
12
- TEST_PLAN_VERSION,
12
+ CURRENT_PLAN_VERSION,
13
13
  } from "./schema.js";
14
14
 
15
15
  describe("Sequential Test Builder", () => {
@@ -28,7 +28,7 @@ describe("Sequential Test Builder", () => {
28
28
  .build();
29
29
 
30
30
  expect(plan.name).toBe("simple-check");
31
- expect(plan.version).toBe(TEST_PLAN_VERSION);
31
+ expect(plan.version).toBe(CURRENT_PLAN_VERSION);
32
32
  expect(plan.frequency).toEqual({ every: 5, unit: "MINUTE" });
33
33
  expect(plan.nodes).toHaveLength(1);
34
34
  expect(plan.edges).toEqual([
@@ -7,7 +7,7 @@ import {
7
7
  } from "./builder.js";
8
8
  import { START, END } from "./constants.js";
9
9
  import {
10
- TEST_PLAN_VERSION,
10
+ CURRENT_PLAN_VERSION,
11
11
  Edge,
12
12
  NodeDSL,
13
13
  Frequency,
@@ -177,7 +177,7 @@ class SequentialTestBuilderImpl<
177
177
  name,
178
178
  frequency,
179
179
  locations,
180
- version: TEST_PLAN_VERSION,
180
+ version: CURRENT_PLAN_VERSION,
181
181
  nodes: [],
182
182
  edges: [{ from: START, to: END }],
183
183
  };
@@ -199,7 +199,7 @@ class SequentialTestBuilderImpl<
199
199
 
200
200
  return {
201
201
  name,
202
- version: TEST_PLAN_VERSION,
202
+ version: CURRENT_PLAN_VERSION,
203
203
  frequency,
204
204
  locations,
205
205
  nodes: this.nodes,