@shipfox/api-runners-dto 10.0.0 → 10.2.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shipfox/api-runners-dto",
3
3
  "license": "MIT",
4
- "version": "10.0.0",
4
+ "version": "10.2.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/ShipfoxHQ/shipfox.git",
@@ -23,8 +23,8 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "zod": "^4.4.3",
26
- "@shipfox/inter-module": "0.2.2",
27
- "@shipfox/runner-labels": "0.1.3"
26
+ "@shipfox/runner-labels": "0.1.3",
27
+ "@shipfox/inter-module": "0.2.2"
28
28
  },
29
29
  "imports": {
30
30
  "#*": "./dist/*"
package/src/index.ts CHANGED
@@ -3,16 +3,20 @@ export {
3
3
  type ActiveRunnerDto,
4
4
  type ActiveRunnerStateDto,
5
5
  type ActiveRunnersResponseDto,
6
+ type AdministratorProvisionerTokenDto,
6
7
  type AssignRunnerInstancesBodyDto,
7
8
  type AssignRunnerInstancesResponseDto,
8
9
  activeProvisionerDtoSchema,
9
10
  activeRunnerDtoSchema,
10
11
  activeRunnerStateSchema,
11
12
  activeRunnersResponseSchema,
13
+ administratorProvisionerTokenSchema,
12
14
  assignRunnerInstancesBodySchema,
13
15
  assignRunnerInstancesResponseSchema,
14
16
  attachRunnerControlProviderIdBodySchema,
15
17
  type ClaimedJobResponseDto,
18
+ type CreateAdministratorProvisionerTokenBodyDto,
19
+ type CreateAdministratorProvisionerTokenResponseDto,
16
20
  type CreateManualRegistrationTokenBodyDto,
17
21
  type CreateManualRegistrationTokenResponseDto,
18
22
  type CreateProvisionerTokenBodyDto,
@@ -20,6 +24,8 @@ export {
20
24
  type CreateRunnerInstancesBodyDto,
21
25
  type CreateRunnerInstancesResponseDto,
22
26
  claimedJobResponseSchema,
27
+ createAdministratorProvisionerTokenBodySchema,
28
+ createAdministratorProvisionerTokenResponseSchema,
23
29
  createManualRegistrationTokenBodySchema,
24
30
  createManualRegistrationTokenResponseSchema,
25
31
  createProvisionerTokenBodySchema,
@@ -32,12 +38,22 @@ export {
32
38
  type HeartbeatResponseDto,
33
39
  heartbeatBodySchema,
34
40
  heartbeatResponseSchema,
41
+ type InstallationProvisionerTokenStatus,
42
+ installationProvisionerTokenStatusSchema,
35
43
  type ListActiveProvisionersResponseDto,
44
+ type ListAdministratorProvisionerTokensQueryDto,
45
+ type ListAdministratorProvisionerTokensResponseDto,
36
46
  type ListManualRegistrationTokensResponseDto,
37
47
  type ListProvisionerTokensResponseDto,
48
+ type ListRunnerAdministratorInstancesQueryDto,
49
+ type ListRunnerAdministratorInstancesResponseDto,
38
50
  listActiveProvisionersResponseSchema,
51
+ listAdministratorProvisionerTokensQuerySchema,
52
+ listAdministratorProvisionerTokensResponseSchema,
39
53
  listManualRegistrationTokensResponseSchema,
40
54
  listProvisionerTokensResponseSchema,
55
+ listRunnerAdministratorInstancesQuerySchema,
56
+ listRunnerAdministratorInstancesResponseSchema,
41
57
  MAX_MANUAL_REGISTRATION_TOKEN_TTL_SECONDS,
42
58
  MAX_OBSERVED_PROVIDER_RUNNER_ID_LENGTH,
43
59
  MAX_PROVIDER_KIND_LENGTH,
@@ -70,9 +86,14 @@ export {
70
86
  type ReportRunnerInstancesBodyDto,
71
87
  type ReportRunnerInstancesResponseDto,
72
88
  type ReservationGrantDto,
89
+ type RevokeAdministratorProvisionerTokenBodyDto,
90
+ type RevokeAdministratorProvisionerTokenResponseDto,
73
91
  type RevokeManualRegistrationTokenResponseDto,
74
92
  type RevokeProvisionerTokenResponseDto,
93
+ RUNNER_ASSIGNMENT_POLL_DEFAULT_WAIT_SECONDS,
75
94
  RUNNER_SESSION_EXHAUSTED_CODE,
95
+ type RunnerAdministratorInstanceDto,
96
+ type RunnerAssignmentPollQueryDto,
76
97
  type RunnerBootstrapExchangeBodyDto,
77
98
  type RunnerBootstrapExchangeResponseDto,
78
99
  type RunnerEnrollmentBodyDto,
@@ -91,8 +112,16 @@ export {
91
112
  reportRunnerInstancesBodySchema,
92
113
  reportRunnerInstancesResponseSchema,
93
114
  reservationGrantSchema,
115
+ revokeAdministratorProvisionerTokenBodySchema,
116
+ revokeAdministratorProvisionerTokenResponseSchema,
94
117
  revokeManualRegistrationTokenResponseSchema,
95
118
  revokeProvisionerTokenResponseSchema,
119
+ runnerAdministratorAssignmentPresenceSchema,
120
+ runnerAdministratorEnrollmentStateSchema,
121
+ runnerAdministratorInstanceSchema,
122
+ runnerAdministratorLifecycleStateSchema,
123
+ runnerAdministratorReconciliationStatusSchema,
124
+ runnerAssignmentPollQuerySchema,
96
125
  runnerAssignmentPollResponseSchema,
97
126
  runnerBootstrapExchangeBodySchema,
98
127
  runnerBootstrapExchangeResponseSchema,
@@ -0,0 +1,94 @@
1
+ import {z} from 'zod';
2
+ import {MAX_PROVISIONER_TOKEN_TTL_SECONDS} from './provisioner-token.js';
3
+
4
+ const timestampSchema = z.string().datetime();
5
+ const CONTROL_OR_FORMAT_CHARACTER_RE = /[\p{Cc}\p{Cf}]/u;
6
+ const reasonSchema = z
7
+ .string()
8
+ .min(1)
9
+ .max(512)
10
+ .refine((value) => value.trim().length > 0, {
11
+ message: 'must not be blank',
12
+ })
13
+ .refine((value) => !CONTROL_OR_FORMAT_CHARACTER_RE.test(value), {
14
+ message: 'must not contain control or format characters',
15
+ });
16
+
17
+ export const installationProvisionerTokenStatusSchema = z.enum(['active', 'expired', 'revoked']);
18
+
19
+ export type InstallationProvisionerTokenStatus = z.infer<
20
+ typeof installationProvisionerTokenStatusSchema
21
+ >;
22
+
23
+ export const administratorProvisionerTokenSchema = z.object({
24
+ id: z.string().uuid(),
25
+ scope: z.literal('installation'),
26
+ prefix: z.string().min(1),
27
+ name: z.string().nullable(),
28
+ status: installationProvisionerTokenStatusSchema,
29
+ created_by_user_id: z.string().uuid(),
30
+ revoked_by_user_id: z.string().uuid().nullable(),
31
+ expires_at: timestampSchema.nullable(),
32
+ revoked_at: timestampSchema.nullable(),
33
+ last_seen_at: timestampSchema.nullable(),
34
+ created_at: timestampSchema,
35
+ updated_at: timestampSchema,
36
+ });
37
+
38
+ export type AdministratorProvisionerTokenDto = z.infer<typeof administratorProvisionerTokenSchema>;
39
+
40
+ export const createAdministratorProvisionerTokenBodySchema = z.object({
41
+ name: z.string().min(1).max(256).optional(),
42
+ ttl_seconds: z.number().int().positive().max(MAX_PROVISIONER_TOKEN_TTL_SECONDS).optional(),
43
+ reason: reasonSchema,
44
+ });
45
+
46
+ export type CreateAdministratorProvisionerTokenBodyDto = z.infer<
47
+ typeof createAdministratorProvisionerTokenBodySchema
48
+ >;
49
+
50
+ export const createAdministratorProvisionerTokenResponseSchema =
51
+ administratorProvisionerTokenSchema.extend({
52
+ raw_token: z.string().min(1),
53
+ correlation_id: z.string().min(1).max(255),
54
+ });
55
+
56
+ export type CreateAdministratorProvisionerTokenResponseDto = z.infer<
57
+ typeof createAdministratorProvisionerTokenResponseSchema
58
+ >;
59
+
60
+ export const listAdministratorProvisionerTokensQuerySchema = z.object({
61
+ status: installationProvisionerTokenStatusSchema.optional(),
62
+ limit: z.coerce.number().int().min(1).max(100).default(50),
63
+ cursor: z.string().optional(),
64
+ });
65
+
66
+ export type ListAdministratorProvisionerTokensQueryDto = z.infer<
67
+ typeof listAdministratorProvisionerTokensQuerySchema
68
+ >;
69
+
70
+ export const listAdministratorProvisionerTokensResponseSchema = z.object({
71
+ tokens: z.array(administratorProvisionerTokenSchema),
72
+ next_cursor: z.string().nullable(),
73
+ });
74
+
75
+ export type ListAdministratorProvisionerTokensResponseDto = z.infer<
76
+ typeof listAdministratorProvisionerTokensResponseSchema
77
+ >;
78
+
79
+ export const revokeAdministratorProvisionerTokenBodySchema = z.object({
80
+ reason: reasonSchema,
81
+ });
82
+
83
+ export type RevokeAdministratorProvisionerTokenBodyDto = z.infer<
84
+ typeof revokeAdministratorProvisionerTokenBodySchema
85
+ >;
86
+
87
+ export const revokeAdministratorProvisionerTokenResponseSchema =
88
+ administratorProvisionerTokenSchema.extend({
89
+ correlation_id: z.string().min(1).max(255),
90
+ });
91
+
92
+ export type RevokeAdministratorProvisionerTokenResponseDto = z.infer<
93
+ typeof revokeAdministratorProvisionerTokenResponseSchema
94
+ >;
@@ -0,0 +1,76 @@
1
+ import {MAX_RUNNER_LABELS} from '@shipfox/runner-labels';
2
+ import {z} from 'zod';
3
+ import {runnerLabelSchema} from './register.js';
4
+ import {providerRunnerStateSchema} from './report-runner-instances.js';
5
+
6
+ export const runnerAdministratorLifecycleStateSchema = z.enum([
7
+ 'unassigned',
8
+ 'assigned',
9
+ 'activated',
10
+ 'claimed',
11
+ 'completed',
12
+ ]);
13
+
14
+ export const runnerAdministratorEnrollmentStateSchema = z.enum([
15
+ 'pending',
16
+ 'enrolled',
17
+ 'activated',
18
+ ]);
19
+
20
+ export const runnerAdministratorAssignmentPresenceSchema = z.enum(['assigned', 'unassigned']);
21
+
22
+ export const runnerAdministratorReconciliationStatusSchema = z.enum([
23
+ 'current',
24
+ 'stale',
25
+ 'terminal',
26
+ 'unknown',
27
+ ]);
28
+
29
+ const runnerAdministratorAssignedWorkspaceSchema = z.object({
30
+ id: z.string().uuid(),
31
+ });
32
+
33
+ const runnerAdministratorProvisionerSchema = z.object({
34
+ id: z.string().uuid(),
35
+ scope: z.literal('installation'),
36
+ name: z.string().nullable(),
37
+ });
38
+
39
+ export const runnerAdministratorInstanceSchema = z.object({
40
+ id: z.string().uuid(),
41
+ lifecycle_state: runnerAdministratorLifecycleStateSchema,
42
+ compute_state: providerRunnerStateSchema,
43
+ enrollment_state: runnerAdministratorEnrollmentStateSchema,
44
+ assignment_presence: runnerAdministratorAssignmentPresenceSchema,
45
+ assigned_workspace: runnerAdministratorAssignedWorkspaceSchema.nullable(),
46
+ labels: z.array(runnerLabelSchema).max(MAX_RUNNER_LABELS),
47
+ created_at: z.string().datetime(),
48
+ last_heartbeat_at: z.string().datetime(),
49
+ closure_reason: z.string().max(500).nullable(),
50
+ closed_at: z.string().datetime().nullable(),
51
+ provisioner: runnerAdministratorProvisionerSchema,
52
+ reconciliation_status: runnerAdministratorReconciliationStatusSchema,
53
+ });
54
+
55
+ export type RunnerAdministratorInstanceDto = z.infer<typeof runnerAdministratorInstanceSchema>;
56
+
57
+ export const listRunnerAdministratorInstancesQuerySchema = z.object({
58
+ state: providerRunnerStateSchema.optional(),
59
+ assignment: runnerAdministratorAssignmentPresenceSchema.optional(),
60
+ label: runnerLabelSchema.optional(),
61
+ limit: z.coerce.number().int().min(1).max(100).default(50),
62
+ cursor: z.string().optional(),
63
+ });
64
+
65
+ export type ListRunnerAdministratorInstancesQueryDto = z.infer<
66
+ typeof listRunnerAdministratorInstancesQuerySchema
67
+ >;
68
+
69
+ export const listRunnerAdministratorInstancesResponseSchema = z.object({
70
+ runners: z.array(runnerAdministratorInstanceSchema),
71
+ next_cursor: z.string().nullable(),
72
+ });
73
+
74
+ export type ListRunnerAdministratorInstancesResponseDto = z.infer<
75
+ typeof listRunnerAdministratorInstancesResponseSchema
76
+ >;
@@ -1,3 +1,33 @@
1
+ export {
2
+ type AdministratorProvisionerTokenDto,
3
+ administratorProvisionerTokenSchema,
4
+ type CreateAdministratorProvisionerTokenBodyDto,
5
+ type CreateAdministratorProvisionerTokenResponseDto,
6
+ createAdministratorProvisionerTokenBodySchema,
7
+ createAdministratorProvisionerTokenResponseSchema,
8
+ type InstallationProvisionerTokenStatus,
9
+ installationProvisionerTokenStatusSchema,
10
+ type ListAdministratorProvisionerTokensQueryDto,
11
+ type ListAdministratorProvisionerTokensResponseDto,
12
+ listAdministratorProvisionerTokensQuerySchema,
13
+ listAdministratorProvisionerTokensResponseSchema,
14
+ type RevokeAdministratorProvisionerTokenBodyDto,
15
+ type RevokeAdministratorProvisionerTokenResponseDto,
16
+ revokeAdministratorProvisionerTokenBodySchema,
17
+ revokeAdministratorProvisionerTokenResponseSchema,
18
+ } from './admin-provisioner-token.js';
19
+ export {
20
+ type ListRunnerAdministratorInstancesQueryDto,
21
+ type ListRunnerAdministratorInstancesResponseDto,
22
+ listRunnerAdministratorInstancesQuerySchema,
23
+ listRunnerAdministratorInstancesResponseSchema,
24
+ type RunnerAdministratorInstanceDto,
25
+ runnerAdministratorAssignmentPresenceSchema,
26
+ runnerAdministratorEnrollmentStateSchema,
27
+ runnerAdministratorInstanceSchema,
28
+ runnerAdministratorLifecycleStateSchema,
29
+ runnerAdministratorReconciliationStatusSchema,
30
+ } from './admin-runner-instances.js';
1
31
  export {
2
32
  type AssignRunnerInstancesBodyDto,
3
33
  type AssignRunnerInstancesResponseDto,
@@ -108,10 +138,13 @@ export {
108
138
  type CreateRunnerInstancesResponseDto,
109
139
  createRunnerInstancesBodySchema,
110
140
  createRunnerInstancesResponseSchema,
141
+ RUNNER_ASSIGNMENT_POLL_DEFAULT_WAIT_SECONDS,
142
+ type RunnerAssignmentPollQueryDto,
111
143
  type RunnerBootstrapExchangeBodyDto,
112
144
  type RunnerBootstrapExchangeResponseDto,
113
145
  type RunnerEnrollmentBodyDto,
114
146
  type RunnerEnrollmentResponseDto,
147
+ runnerAssignmentPollQuerySchema,
115
148
  runnerAssignmentPollResponseSchema,
116
149
  runnerBootstrapExchangeBodySchema,
117
150
  runnerBootstrapExchangeResponseSchema,
@@ -0,0 +1,52 @@
1
+ import {
2
+ RUNNER_ASSIGNMENT_POLL_DEFAULT_WAIT_SECONDS,
3
+ runnerAssignmentPollQuerySchema,
4
+ runnerEnrollmentBodySchema,
5
+ } from './runner-enrollment.js';
6
+
7
+ describe('runnerAssignmentPollQuerySchema', () => {
8
+ it('coerces a bounded wait from the HTTP query string', () => {
9
+ expect(runnerAssignmentPollQuerySchema.parse({wait_seconds: '12'})).toEqual({
10
+ wait_seconds: 12,
11
+ });
12
+ });
13
+
14
+ it('rejects a zero-second assignment wait', () => {
15
+ expect(runnerAssignmentPollQuerySchema.safeParse({wait_seconds: '0'}).success).toBe(false);
16
+ });
17
+
18
+ it.each(['-1', '1.5', 'not-a-number'])('rejects invalid wait_seconds %s', (waitSeconds) => {
19
+ expect(runnerAssignmentPollQuerySchema.safeParse({wait_seconds: waitSeconds}).success).toBe(
20
+ false,
21
+ );
22
+ });
23
+ });
24
+
25
+ it('keeps the protocol default explicit', () => {
26
+ expect(RUNNER_ASSIGNMENT_POLL_DEFAULT_WAIT_SECONDS).toBe(30);
27
+ });
28
+
29
+ const validEnrollment = {
30
+ capabilities: undefined,
31
+ labels: ['linux'],
32
+ provider_kind: 'docker',
33
+ protocol_version: '1',
34
+ };
35
+
36
+ test('accepts the shared maximum runner label count', () => {
37
+ const result = runnerEnrollmentBodySchema.safeParse({
38
+ ...validEnrollment,
39
+ labels: Array.from({length: 20}, (_, index) => `label-${index}`),
40
+ });
41
+
42
+ expect(result.success).toBe(true);
43
+ });
44
+
45
+ test('rejects runner enrollment above the shared maximum label count', () => {
46
+ const result = runnerEnrollmentBodySchema.safeParse({
47
+ ...validEnrollment,
48
+ labels: Array.from({length: 21}, (_, index) => `label-${index}`),
49
+ });
50
+
51
+ expect(result.success).toBe(false);
52
+ });
@@ -1,3 +1,4 @@
1
+ import {MAX_RUNNER_LABELS} from '@shipfox/runner-labels';
1
2
  import {z} from 'zod';
2
3
  import {runnerLabelSchema} from './register.js';
3
4
  import {runnerToolCapabilitiesSchema} from './tool-capabilities.js';
@@ -33,7 +34,7 @@ export const runnerBootstrapExchangeResponseSchema = z.object({
33
34
  });
34
35
  export const runnerEnrollmentBodySchema = z
35
36
  .object({
36
- labels: z.array(runnerLabelSchema).min(1).max(100),
37
+ labels: z.array(runnerLabelSchema).min(1).max(MAX_RUNNER_LABELS),
37
38
  capabilities: runnerToolCapabilitiesSchema.optional(),
38
39
  provider_kind: z.string().min(1).max(64),
39
40
  protocol_version: z.string().min(1).max(64),
@@ -46,6 +47,10 @@ export const attachRunnerControlProviderIdBodySchema = z
46
47
  .object({provider_runner_id: z.string().min(1).max(255)})
47
48
  .strict();
48
49
  export const runnerControlHeartbeatResponseSchema = z.object({ok: z.literal(true)});
50
+ export const RUNNER_ASSIGNMENT_POLL_DEFAULT_WAIT_SECONDS = 30;
51
+ export const runnerAssignmentPollQuerySchema = z
52
+ .object({wait_seconds: z.coerce.number().int().min(1).optional()})
53
+ .strict();
49
54
  export const runnerAssignmentPollResponseSchema = z.object({
50
55
  activation_token: z.string().min(1).nullable(),
51
56
  });
@@ -58,3 +63,4 @@ export type RunnerBootstrapExchangeResponseDto = z.infer<
58
63
  >;
59
64
  export type RunnerEnrollmentBodyDto = z.infer<typeof runnerEnrollmentBodySchema>;
60
65
  export type RunnerEnrollmentResponseDto = z.infer<typeof runnerEnrollmentResponseSchema>;
66
+ export type RunnerAssignmentPollQueryDto = z.infer<typeof runnerAssignmentPollQuerySchema>;