@shipfox/api-runners 10.1.0 → 11.0.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 (121) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +27 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js +8 -13
  5. package/dist/config.js.map +1 -1
  6. package/dist/core/admin-runner-instances.d.ts +34 -0
  7. package/dist/core/admin-runner-instances.d.ts.map +1 -0
  8. package/dist/core/admin-runner-instances.js +58 -0
  9. package/dist/core/admin-runner-instances.js.map +1 -0
  10. package/dist/core/errors.d.ts +6 -0
  11. package/dist/core/errors.d.ts.map +1 -1
  12. package/dist/core/errors.js +12 -0
  13. package/dist/core/errors.js.map +1 -1
  14. package/dist/core/index.d.ts +3 -2
  15. package/dist/core/index.d.ts.map +1 -1
  16. package/dist/core/index.js +3 -2
  17. package/dist/core/index.js.map +1 -1
  18. package/dist/core/provisioner-tokens.d.ts +33 -0
  19. package/dist/core/provisioner-tokens.d.ts.map +1 -1
  20. package/dist/core/provisioner-tokens.js +107 -2
  21. package/dist/core/provisioner-tokens.js.map +1 -1
  22. package/dist/db/admin-runner-instances.d.ts +34 -0
  23. package/dist/db/admin-runner-instances.d.ts.map +1 -0
  24. package/dist/db/admin-runner-instances.js +62 -0
  25. package/dist/db/admin-runner-instances.js.map +1 -0
  26. package/dist/db/db.d.ts +290 -0
  27. package/dist/db/db.d.ts.map +1 -1
  28. package/dist/db/db.js +2 -0
  29. package/dist/db/db.js.map +1 -1
  30. package/dist/db/index.d.ts +3 -1
  31. package/dist/db/index.d.ts.map +1 -1
  32. package/dist/db/index.js +2 -1
  33. package/dist/db/index.js.map +1 -1
  34. package/dist/db/job-executions.d.ts.map +1 -1
  35. package/dist/db/job-executions.js +11 -0
  36. package/dist/db/job-executions.js.map +1 -1
  37. package/dist/db/provisioner-tokens.d.ts +38 -0
  38. package/dist/db/provisioner-tokens.d.ts.map +1 -1
  39. package/dist/db/provisioner-tokens.js +157 -3
  40. package/dist/db/provisioner-tokens.js.map +1 -1
  41. package/dist/db/reservations.d.ts.map +1 -1
  42. package/dist/db/reservations.js +60 -8
  43. package/dist/db/reservations.js.map +1 -1
  44. package/dist/db/schema/admin-command-results.d.ts +134 -0
  45. package/dist/db/schema/admin-command-results.d.ts.map +1 -0
  46. package/dist/db/schema/admin-command-results.js +18 -0
  47. package/dist/db/schema/admin-command-results.js.map +1 -0
  48. package/dist/db/schema/runner-instances.d.ts +17 -0
  49. package/dist/db/schema/runner-instances.d.ts.map +1 -1
  50. package/dist/db/schema/runner-instances.js +3 -0
  51. package/dist/db/schema/runner-instances.js.map +1 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +6 -1
  54. package/dist/index.js.map +1 -1
  55. package/dist/presentation/dto/admin-provisioner-token.d.ts +16 -0
  56. package/dist/presentation/dto/admin-provisioner-token.d.ts.map +1 -0
  57. package/dist/presentation/dto/admin-provisioner-token.js +22 -0
  58. package/dist/presentation/dto/admin-provisioner-token.js.map +1 -0
  59. package/dist/presentation/dto/admin-runner-instances.d.ts +23 -0
  60. package/dist/presentation/dto/admin-runner-instances.d.ts.map +1 -0
  61. package/dist/presentation/dto/admin-runner-instances.js +19 -0
  62. package/dist/presentation/dto/admin-runner-instances.js.map +1 -0
  63. package/dist/presentation/dto/index.d.ts +2 -0
  64. package/dist/presentation/dto/index.d.ts.map +1 -1
  65. package/dist/presentation/dto/index.js +2 -0
  66. package/dist/presentation/dto/index.js.map +1 -1
  67. package/dist/presentation/routes/admin-provisioner-tokens.d.ts +4 -0
  68. package/dist/presentation/routes/admin-provisioner-tokens.d.ts.map +1 -0
  69. package/dist/presentation/routes/admin-provisioner-tokens.js +167 -0
  70. package/dist/presentation/routes/admin-provisioner-tokens.js.map +1 -0
  71. package/dist/presentation/routes/admin-runner-instances.d.ts +3 -0
  72. package/dist/presentation/routes/admin-runner-instances.d.ts.map +1 -0
  73. package/dist/presentation/routes/admin-runner-instances.js +63 -0
  74. package/dist/presentation/routes/admin-runner-instances.js.map +1 -0
  75. package/dist/presentation/routes/index.d.ts.map +1 -1
  76. package/dist/presentation/routes/index.js +11 -1
  77. package/dist/presentation/routes/index.js.map +1 -1
  78. package/dist/presentation/routes/runner-enrollment.d.ts +1 -0
  79. package/dist/presentation/routes/runner-enrollment.d.ts.map +1 -1
  80. package/dist/presentation/routes/runner-enrollment.js +11 -4
  81. package/dist/presentation/routes/runner-enrollment.js.map +1 -1
  82. package/dist/tsconfig.test.tsbuildinfo +1 -1
  83. package/drizzle/0002_special_shadowcat.sql +1 -0
  84. package/drizzle/0003_flaky_sally_floyd.sql +11 -0
  85. package/drizzle/meta/0002_snapshot.json +2099 -0
  86. package/drizzle/meta/0003_snapshot.json +2178 -0
  87. package/drizzle/meta/_journal.json +14 -0
  88. package/package.json +5 -4
  89. package/src/config.test.ts +11 -0
  90. package/src/config.ts +19 -8
  91. package/src/core/admin-runner-instances.ts +125 -0
  92. package/src/core/errors.ts +14 -0
  93. package/src/core/index.ts +12 -0
  94. package/src/core/provisioner-tokens.ts +157 -1
  95. package/src/db/admin-runner-instances.ts +121 -0
  96. package/src/db/db.ts +2 -0
  97. package/src/db/index.ts +10 -0
  98. package/src/db/job-executions.test.ts +17 -0
  99. package/src/db/job-executions.ts +22 -0
  100. package/src/db/provisioner-tokens.ts +263 -9
  101. package/src/db/reservations.test.ts +253 -0
  102. package/src/db/reservations.ts +170 -15
  103. package/src/db/schema/admin-command-results.ts +29 -0
  104. package/src/db/schema/runner-instances.ts +1 -0
  105. package/src/index.test.ts +1 -1
  106. package/src/index.ts +6 -1
  107. package/src/presentation/dto/admin-provisioner-token.ts +23 -0
  108. package/src/presentation/dto/admin-runner-instances.ts +19 -0
  109. package/src/presentation/dto/index.ts +2 -0
  110. package/src/presentation/routes/admin-provisioner-tokens.test.ts +227 -0
  111. package/src/presentation/routes/admin-provisioner-tokens.ts +177 -0
  112. package/src/presentation/routes/admin-runner-instances.test.ts +671 -0
  113. package/src/presentation/routes/admin-runner-instances.ts +67 -0
  114. package/src/presentation/routes/index.ts +8 -0
  115. package/src/presentation/routes/list-active-runners.test.ts +8 -2
  116. package/src/presentation/routes/manual-registration-tokens.test.ts +8 -2
  117. package/src/presentation/routes/provisioner-tokens.test.ts +8 -2
  118. package/src/presentation/routes/runner-enrollment.test.ts +60 -2
  119. package/src/presentation/routes/runner-enrollment.ts +24 -4
  120. package/test/globalSetup.ts +1 -0
  121. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,7 +1,10 @@
1
+ import { createHmac } from 'node:crypto';
2
+ import { createAdministrationActionEvent } from '@shipfox/api-common-dto';
3
+ import { runnerSessionTokenKey } from '@shipfox/node-auth-root-key';
1
4
  import { extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken } from '@shipfox/node-tokens';
2
- import { createProvisionerToken, listActiveProvisionerTokens, listUsableProvisionerTokensByWorkspaceId, revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb, revokeProvisionerToken } from '#db/provisioner-tokens.js';
5
+ import { createInstallationProvisionerTokenWithAudit, createProvisionerToken, listActiveProvisionerTokens, listInstallationProvisionerTokens, listUsableProvisionerTokensByWorkspaceId, revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb, revokeInstallationProvisionerTokenWithAudit, revokeProvisionerToken } from '#db/provisioner-tokens.js';
3
6
  import { config } from '../config.js';
4
- import { ProvisionerTokenNotFoundError } from './errors.js';
7
+ import { ProvisionerAdminIdempotencyReplayUnavailableError, ProvisionerTokenNotFoundError } from './errors.js';
5
8
  export async function createWorkspaceProvisionerToken(params) {
6
9
  const rawToken = generateOpaqueToken('provisionerToken');
7
10
  const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;
@@ -54,5 +57,107 @@ export async function revokeInstallationProvisionerToken(params) {
54
57
  if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);
55
58
  return token;
56
59
  }
60
+ const ADMIN_OWNER_ROLE = 'admin-owner';
61
+ const ADMIN_OPERATOR_ROLE = 'admin-operator';
62
+ const CREATE_ADMIN_COMMAND = 'runners.provisioner_token.create';
63
+ const REVOKE_ADMIN_COMMAND = 'runners.provisioner_token.revoke';
64
+ function administrationCommandFingerprint(command, input) {
65
+ return hashOpaqueToken(`${command}:${JSON.stringify(input)}`);
66
+ }
67
+ function idempotentProvisionerToken(seed) {
68
+ const generated = generateOpaqueToken('provisionerToken');
69
+ const tokenPrefix = generated.slice(0, -43);
70
+ const key = createHmac('sha256', runnerSessionTokenKey()).update('shipfox/provisioner-token-idempotency/v1').digest();
71
+ const suffix = createHmac('sha256', key).update(seed).digest('base64url');
72
+ return `${tokenPrefix}${suffix}`;
73
+ }
74
+ function administrationEvent(params) {
75
+ return createAdministrationActionEvent({
76
+ actorId: params.actorId,
77
+ actorRole: params.actorRole,
78
+ requiredRole: params.requiredRole,
79
+ command: params.command,
80
+ targetType: 'provisioner-token',
81
+ targetId: params.targetId,
82
+ reason: params.reason,
83
+ result: 'succeeded',
84
+ correlationId: params.correlationId,
85
+ idempotencyKeyFingerprint: params.idempotencyKeyFingerprint,
86
+ occurredAt: new Date().toISOString()
87
+ });
88
+ }
89
+ export function installationProvisionerTokenStatus(token, now = new Date()) {
90
+ if (token.revokedAt) return 'revoked';
91
+ if (token.expiresAt && token.expiresAt <= now) return 'expired';
92
+ return 'active';
93
+ }
94
+ export async function listAdministratorInstallationProvisionerTokens(params) {
95
+ return await listInstallationProvisionerTokens(params);
96
+ }
97
+ export async function createAdministratorInstallationProvisionerToken(params) {
98
+ const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);
99
+ const requestFingerprint = administrationCommandFingerprint(CREATE_ADMIN_COMMAND, {
100
+ name: params.name,
101
+ ttlSeconds: params.ttlSeconds,
102
+ reason: params.reason
103
+ });
104
+ const rawToken = idempotentProvisionerToken(`${params.actorId}:${params.idempotencyKey}:${requestFingerprint}`);
105
+ const result = await createInstallationProvisionerTokenWithAudit({
106
+ actorId: params.actorId,
107
+ command: CREATE_ADMIN_COMMAND,
108
+ correlationId: params.correlationId,
109
+ idempotencyKeyFingerprint,
110
+ requestFingerprint,
111
+ hashedToken: hashOpaqueToken(rawToken),
112
+ prefix: extractDisplayPrefix(rawToken),
113
+ name: params.name,
114
+ ttlSeconds: params.ttlSeconds,
115
+ event: (tokenId)=>administrationEvent({
116
+ actorId: params.actorId,
117
+ actorRole: params.actorRole,
118
+ requiredRole: ADMIN_OWNER_ROLE,
119
+ command: CREATE_ADMIN_COMMAND,
120
+ targetId: tokenId,
121
+ reason: params.reason,
122
+ correlationId: params.correlationId,
123
+ idempotencyKeyFingerprint
124
+ })
125
+ });
126
+ if (result.replayed && hashOpaqueToken(rawToken) !== result.token.hashedToken) {
127
+ throw new ProvisionerAdminIdempotencyReplayUnavailableError();
128
+ }
129
+ return {
130
+ ...result,
131
+ rawToken,
132
+ correlationId: result.correlationId
133
+ };
134
+ }
135
+ export async function revokeAdministratorInstallationProvisionerToken(params) {
136
+ const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);
137
+ const requestFingerprint = administrationCommandFingerprint(REVOKE_ADMIN_COMMAND, {
138
+ tokenId: params.tokenId,
139
+ reason: params.reason
140
+ });
141
+ const result = await revokeInstallationProvisionerTokenWithAudit({
142
+ tokenId: params.tokenId,
143
+ actorId: params.actorId,
144
+ command: REVOKE_ADMIN_COMMAND,
145
+ correlationId: params.correlationId,
146
+ idempotencyKeyFingerprint,
147
+ requestFingerprint,
148
+ event: (tokenId)=>administrationEvent({
149
+ actorId: params.actorId,
150
+ actorRole: params.actorRole,
151
+ requiredRole: ADMIN_OPERATOR_ROLE,
152
+ command: REVOKE_ADMIN_COMMAND,
153
+ targetId: tokenId,
154
+ reason: params.reason,
155
+ correlationId: params.correlationId,
156
+ idempotencyKeyFingerprint
157
+ })
158
+ });
159
+ if (!result) throw new ProvisionerTokenNotFoundError(params.tokenId);
160
+ return result;
161
+ }
57
162
 
58
163
  //# sourceMappingURL=provisioner-tokens.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/provisioner-tokens.ts"],"sourcesContent":["import {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {\n createProvisionerToken,\n listActiveProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb,\n revokeProvisionerToken,\n} from '#db/provisioner-tokens.js';\nimport {config} from '../config.js';\nimport type {ActiveProvisionerToken, ProvisionerToken} from './entities/provisioner-token.js';\nimport {ProvisionerTokenNotFoundError} from './errors.js';\n\nexport interface CreateWorkspaceProvisionerTokenParams {\n workspaceId: string;\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport interface CreateWorkspaceProvisionerTokenResult {\n token: ProvisionerToken;\n rawToken: string;\n}\n\nexport async function createWorkspaceProvisionerToken(\n params: CreateWorkspaceProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n\n const token = await createProvisionerToken({\n scope: 'workspace',\n workspaceId: params.workspaceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n\n return {token, rawToken};\n}\n\nexport interface CreateInstallationProvisionerTokenParams {\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport async function createInstallationProvisionerToken(\n params: CreateInstallationProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n const token = await createProvisionerToken({\n scope: 'installation',\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n return {token, rawToken};\n}\n\nexport function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]> {\n return listUsableProvisionerTokensByWorkspaceId(workspaceId);\n}\n\nexport function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]> {\n return listActiveProvisionerTokens({\n workspaceId,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n\nexport async function revokeWorkspaceProvisionerToken(params: {\n tokenId: string;\n workspaceId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeProvisionerToken(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n\nexport async function revokeInstallationProvisionerToken(params: {\n tokenId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeInstallationProvisionerTokenDb(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n"],"names":["extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","createProvisionerToken","listActiveProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","revokeInstallationProvisionerToken","revokeInstallationProvisionerTokenDb","revokeProvisionerToken","config","ProvisionerTokenNotFoundError","createWorkspaceProvisionerToken","params","rawToken","expiresAt","ttlSeconds","Date","now","undefined","token","scope","workspaceId","hashedToken","prefix","name","createdByUserId","createInstallationProvisionerToken","listUsableProvisionerTokens","listActiveProvisioners","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS","revokeWorkspaceProvisionerToken","tokenId"],"mappings":"AAAA,SAAQA,oBAAoB,EAAEC,mBAAmB,EAAEC,eAAe,QAAO,uBAAuB;AAChG,SACEC,sBAAsB,EACtBC,2BAA2B,EAC3BC,wCAAwC,EACxCC,sCAAsCC,oCAAoC,EAC1EC,sBAAsB,QACjB,4BAA4B;AACnC,SAAQC,MAAM,QAAO,eAAe;AAEpC,SAAQC,6BAA6B,QAAO,cAAc;AAc1D,OAAO,eAAeC,gCACpBC,MAA6C;IAE7C,MAAMC,WAAWZ,oBAAoB;IACrC,MAAMa,YAAYF,OAAOG,UAAU,GAAG,IAAIC,KAAKA,KAAKC,GAAG,KAAKL,OAAOG,UAAU,GAAG,QAAQG;IAExF,MAAMC,QAAQ,MAAMhB,uBAAuB;QACzCiB,OAAO;QACPC,aAAaT,OAAOS,WAAW;QAC/BC,aAAapB,gBAAgBW;QAC7BU,QAAQvB,qBAAqBa;QAC7BW,MAAMZ,OAAOY,IAAI;QACjBC,iBAAiBb,OAAOa,eAAe;QACvCX;IACF;IAEA,OAAO;QAACK;QAAON;IAAQ;AACzB;AAQA,OAAO,eAAea,mCACpBd,MAAgD;IAEhD,MAAMC,WAAWZ,oBAAoB;IACrC,MAAMa,YAAYF,OAAOG,UAAU,GAAG,IAAIC,KAAKA,KAAKC,GAAG,KAAKL,OAAOG,UAAU,GAAG,QAAQG;IACxF,MAAMC,QAAQ,MAAMhB,uBAAuB;QACzCiB,OAAO;QACPE,aAAapB,gBAAgBW;QAC7BU,QAAQvB,qBAAqBa;QAC7BW,MAAMZ,OAAOY,IAAI;QACjBC,iBAAiBb,OAAOa,eAAe;QACvCX;IACF;IACA,OAAO;QAACK;QAAON;IAAQ;AACzB;AAEA,OAAO,SAASc,4BAA4BN,WAAmB;IAC7D,OAAOhB,yCAAyCgB;AAClD;AAEA,OAAO,SAASO,uBAAuBP,WAAmB;IACxD,OAAOjB,4BAA4B;QACjCiB;QACAQ,eAAepB,OAAOqB,iCAAiC;IACzD;AACF;AAEA,OAAO,eAAeC,gCAAgCnB,MAIrD;IACC,MAAMO,QAAQ,MAAMX,uBAAuBI;IAC3C,IAAI,CAACO,OAAO,MAAM,IAAIT,8BAA8BE,OAAOoB,OAAO;IAClE,OAAOb;AACT;AAEA,OAAO,eAAeb,mCAAmCM,MAGxD;IACC,MAAMO,QAAQ,MAAMZ,qCAAqCK;IACzD,IAAI,CAACO,OAAO,MAAM,IAAIT,8BAA8BE,OAAOoB,OAAO;IAClE,OAAOb;AACT"}
1
+ {"version":3,"sources":["../../src/core/provisioner-tokens.ts"],"sourcesContent":["import {createHmac} from 'node:crypto';\nimport type {AdministrationRole} from '@shipfox/api-common-dto';\nimport {createAdministrationActionEvent} from '@shipfox/api-common-dto';\nimport {runnerSessionTokenKey} from '@shipfox/node-auth-root-key';\nimport type {TimestampIdCursor} from '@shipfox/node-drizzle';\nimport {extractDisplayPrefix, generateOpaqueToken, hashOpaqueToken} from '@shipfox/node-tokens';\nimport {\n createInstallationProvisionerTokenWithAudit,\n createProvisionerToken,\n listActiveProvisionerTokens,\n listInstallationProvisionerTokens,\n listUsableProvisionerTokensByWorkspaceId,\n revokeInstallationProvisionerToken as revokeInstallationProvisionerTokenDb,\n revokeInstallationProvisionerTokenWithAudit,\n revokeProvisionerToken,\n} from '#db/provisioner-tokens.js';\nimport {config} from '../config.js';\nimport type {ActiveProvisionerToken, ProvisionerToken} from './entities/provisioner-token.js';\nimport {\n ProvisionerAdminIdempotencyReplayUnavailableError,\n ProvisionerTokenNotFoundError,\n} from './errors.js';\n\nexport interface CreateWorkspaceProvisionerTokenParams {\n workspaceId: string;\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport interface CreateWorkspaceProvisionerTokenResult {\n token: ProvisionerToken;\n rawToken: string;\n}\n\nexport async function createWorkspaceProvisionerToken(\n params: CreateWorkspaceProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n\n const token = await createProvisionerToken({\n scope: 'workspace',\n workspaceId: params.workspaceId,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n\n return {token, rawToken};\n}\n\nexport interface CreateInstallationProvisionerTokenParams {\n createdByUserId: string;\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n}\n\nexport async function createInstallationProvisionerToken(\n params: CreateInstallationProvisionerTokenParams,\n): Promise<CreateWorkspaceProvisionerTokenResult> {\n const rawToken = generateOpaqueToken('provisionerToken');\n const expiresAt = params.ttlSeconds ? new Date(Date.now() + params.ttlSeconds * 1000) : undefined;\n const token = await createProvisionerToken({\n scope: 'installation',\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n createdByUserId: params.createdByUserId,\n expiresAt,\n });\n return {token, rawToken};\n}\n\nexport function listUsableProvisionerTokens(workspaceId: string): Promise<ProvisionerToken[]> {\n return listUsableProvisionerTokensByWorkspaceId(workspaceId);\n}\n\nexport function listActiveProvisioners(workspaceId: string): Promise<ActiveProvisionerToken[]> {\n return listActiveProvisionerTokens({\n workspaceId,\n windowSeconds: config.PROVISIONER_ACTIVE_WINDOW_SECONDS,\n });\n}\n\nexport async function revokeWorkspaceProvisionerToken(params: {\n tokenId: string;\n workspaceId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeProvisionerToken(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n\nexport async function revokeInstallationProvisionerToken(params: {\n tokenId: string;\n revokedByUserId: string;\n}): Promise<ProvisionerToken> {\n const token = await revokeInstallationProvisionerTokenDb(params);\n if (!token) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return token;\n}\n\nconst ADMIN_OWNER_ROLE: AdministrationRole = 'admin-owner';\nconst ADMIN_OPERATOR_ROLE: AdministrationRole = 'admin-operator';\nconst CREATE_ADMIN_COMMAND = 'runners.provisioner_token.create';\nconst REVOKE_ADMIN_COMMAND = 'runners.provisioner_token.revoke';\n\nexport interface InstallationProvisionerTokenAdministrationContext {\n actorId: string;\n actorRole: AdministrationRole;\n idempotencyKey: string;\n correlationId: string;\n reason: string;\n}\n\nfunction administrationCommandFingerprint(command: string, input: unknown): string {\n return hashOpaqueToken(`${command}:${JSON.stringify(input)}`);\n}\n\nfunction idempotentProvisionerToken(seed: string): string {\n const generated = generateOpaqueToken('provisionerToken');\n const tokenPrefix = generated.slice(0, -43);\n const key = createHmac('sha256', runnerSessionTokenKey())\n .update('shipfox/provisioner-token-idempotency/v1')\n .digest();\n const suffix = createHmac('sha256', key).update(seed).digest('base64url');\n return `${tokenPrefix}${suffix}`;\n}\n\nfunction administrationEvent(params: {\n actorId: string;\n actorRole: AdministrationRole;\n requiredRole: AdministrationRole;\n command: string;\n targetId: string;\n reason: string;\n correlationId: string;\n idempotencyKeyFingerprint: string;\n}) {\n return createAdministrationActionEvent({\n actorId: params.actorId,\n actorRole: params.actorRole,\n requiredRole: params.requiredRole,\n command: params.command,\n targetType: 'provisioner-token',\n targetId: params.targetId,\n reason: params.reason,\n result: 'succeeded',\n correlationId: params.correlationId,\n idempotencyKeyFingerprint: params.idempotencyKeyFingerprint,\n occurredAt: new Date().toISOString(),\n });\n}\n\nexport type InstallationProvisionerTokenStatus = 'active' | 'expired' | 'revoked';\n\nexport function installationProvisionerTokenStatus(\n token: ProvisionerToken,\n now = new Date(),\n): InstallationProvisionerTokenStatus {\n if (token.revokedAt) return 'revoked';\n if (token.expiresAt && token.expiresAt <= now) return 'expired';\n return 'active';\n}\n\nexport async function listAdministratorInstallationProvisionerTokens(params: {\n limit: number;\n cursor?: TimestampIdCursor | undefined;\n status?: InstallationProvisionerTokenStatus | undefined;\n}) {\n return await listInstallationProvisionerTokens(params);\n}\n\nexport async function createAdministratorInstallationProvisionerToken(\n params: InstallationProvisionerTokenAdministrationContext & {\n name?: string | undefined;\n ttlSeconds?: number | undefined;\n },\n): Promise<{token: ProvisionerToken; rawToken: string; correlationId: string}> {\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n const requestFingerprint = administrationCommandFingerprint(CREATE_ADMIN_COMMAND, {\n name: params.name,\n ttlSeconds: params.ttlSeconds,\n reason: params.reason,\n });\n const rawToken = idempotentProvisionerToken(\n `${params.actorId}:${params.idempotencyKey}:${requestFingerprint}`,\n );\n const result = await createInstallationProvisionerTokenWithAudit({\n actorId: params.actorId,\n command: CREATE_ADMIN_COMMAND,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n requestFingerprint,\n hashedToken: hashOpaqueToken(rawToken),\n prefix: extractDisplayPrefix(rawToken),\n name: params.name,\n ttlSeconds: params.ttlSeconds,\n event: (tokenId) =>\n administrationEvent({\n actorId: params.actorId,\n actorRole: params.actorRole,\n requiredRole: ADMIN_OWNER_ROLE,\n command: CREATE_ADMIN_COMMAND,\n targetId: tokenId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n });\n if (result.replayed && hashOpaqueToken(rawToken) !== result.token.hashedToken) {\n throw new ProvisionerAdminIdempotencyReplayUnavailableError();\n }\n return {...result, rawToken, correlationId: result.correlationId};\n}\n\nexport async function revokeAdministratorInstallationProvisionerToken(\n params: InstallationProvisionerTokenAdministrationContext & {tokenId: string},\n): Promise<{token: ProvisionerToken; correlationId: string}> {\n const idempotencyKeyFingerprint = hashOpaqueToken(params.idempotencyKey);\n const requestFingerprint = administrationCommandFingerprint(REVOKE_ADMIN_COMMAND, {\n tokenId: params.tokenId,\n reason: params.reason,\n });\n const result = await revokeInstallationProvisionerTokenWithAudit({\n tokenId: params.tokenId,\n actorId: params.actorId,\n command: REVOKE_ADMIN_COMMAND,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n requestFingerprint,\n event: (tokenId) =>\n administrationEvent({\n actorId: params.actorId,\n actorRole: params.actorRole,\n requiredRole: ADMIN_OPERATOR_ROLE,\n command: REVOKE_ADMIN_COMMAND,\n targetId: tokenId,\n reason: params.reason,\n correlationId: params.correlationId,\n idempotencyKeyFingerprint,\n }),\n });\n if (!result) throw new ProvisionerTokenNotFoundError(params.tokenId);\n return result;\n}\n"],"names":["createHmac","createAdministrationActionEvent","runnerSessionTokenKey","extractDisplayPrefix","generateOpaqueToken","hashOpaqueToken","createInstallationProvisionerTokenWithAudit","createProvisionerToken","listActiveProvisionerTokens","listInstallationProvisionerTokens","listUsableProvisionerTokensByWorkspaceId","revokeInstallationProvisionerToken","revokeInstallationProvisionerTokenDb","revokeInstallationProvisionerTokenWithAudit","revokeProvisionerToken","config","ProvisionerAdminIdempotencyReplayUnavailableError","ProvisionerTokenNotFoundError","createWorkspaceProvisionerToken","params","rawToken","expiresAt","ttlSeconds","Date","now","undefined","token","scope","workspaceId","hashedToken","prefix","name","createdByUserId","createInstallationProvisionerToken","listUsableProvisionerTokens","listActiveProvisioners","windowSeconds","PROVISIONER_ACTIVE_WINDOW_SECONDS","revokeWorkspaceProvisionerToken","tokenId","ADMIN_OWNER_ROLE","ADMIN_OPERATOR_ROLE","CREATE_ADMIN_COMMAND","REVOKE_ADMIN_COMMAND","administrationCommandFingerprint","command","input","JSON","stringify","idempotentProvisionerToken","seed","generated","tokenPrefix","slice","key","update","digest","suffix","administrationEvent","actorId","actorRole","requiredRole","targetType","targetId","reason","result","correlationId","idempotencyKeyFingerprint","occurredAt","toISOString","installationProvisionerTokenStatus","revokedAt","listAdministratorInstallationProvisionerTokens","createAdministratorInstallationProvisionerToken","idempotencyKey","requestFingerprint","event","replayed","revokeAdministratorInstallationProvisionerToken"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type TimestampIdCursor } from '@shipfox/node-drizzle';
2
+ import type { RunnerInstanceState } from '#core/entities/runner-instance.js';
3
+ export type AdministratorRunnerAssignmentFilter = 'assigned' | 'unassigned';
4
+ export interface AdministratorRunnerInstanceRow {
5
+ id: string;
6
+ workspaceId: string | null;
7
+ state: RunnerInstanceState;
8
+ labels: string[];
9
+ runnerSessionId: string | null;
10
+ firstClaimedAt: Date | null;
11
+ hasActiveControlSession: boolean;
12
+ reason: string | null;
13
+ reportedAt: Date;
14
+ stoppedAt: Date | null;
15
+ failedAt: Date | null;
16
+ terminatedAt: Date | null;
17
+ createdAt: Date;
18
+ provisionerId: string;
19
+ provisionerName: string | null;
20
+ provisionerLastSeenAt: Date | null;
21
+ }
22
+ export interface ListAdministratorRunnerInstancesParams {
23
+ limit: number;
24
+ cursor?: TimestampIdCursor | undefined;
25
+ state?: RunnerInstanceState | undefined;
26
+ assignment?: AdministratorRunnerAssignmentFilter | undefined;
27
+ label?: string | undefined;
28
+ }
29
+ export interface ListAdministratorRunnerInstancesResult {
30
+ runners: AdministratorRunnerInstanceRow[];
31
+ nextCursor: TimestampIdCursor | null;
32
+ }
33
+ export declare function listAdministratorRunnerInstances(params: ListAdministratorRunnerInstancesParams): Promise<ListAdministratorRunnerInstancesResult>;
34
+ //# sourceMappingURL=admin-runner-instances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-runner-instances.d.ts","sourceRoot":"","sources":["../../src/db/admin-runner-instances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,iBAAiB,EAAyB,MAAM,uBAAuB,CAAC;AAcrF,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,mCAAmC,CAAC;AAM3E,MAAM,MAAM,mCAAmC,GAAG,UAAU,GAAG,YAAY,CAAC;AAE5E,MAAM,WAAW,8BAA8B;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,uBAAuB,EAAE,OAAO,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,qBAAqB,EAAE,IAAI,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,sCAAsC;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACvC,KAAK,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACxC,UAAU,CAAC,EAAE,mCAAmC,GAAG,SAAS,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,sCAAsC;IACrD,OAAO,EAAE,8BAA8B,EAAE,CAAC;IAC1C,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACtC;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,sCAAsC,GAC7C,OAAO,CAAC,sCAAsC,CAAC,CAgEjD"}
@@ -0,0 +1,62 @@
1
+ import { timestampIdCursorWhere } from '@shipfox/node-drizzle';
2
+ import { canonicalizeLabels } from '@shipfox/runner-labels';
3
+ import { and, arrayContains, desc, eq, exists, gt, isNotNull, isNull, sql } from 'drizzle-orm';
4
+ import { db } from './db.js';
5
+ import { provisionerTokens } from './schema/provisioner-tokens.js';
6
+ import { runnerControlSessions } from './schema/runner-control-sessions.js';
7
+ import { providerRunners } from './schema/runner-instances.js';
8
+ export async function listAdministratorRunnerInstances(params) {
9
+ const conditions = [
10
+ eq(provisionerTokens.scope, 'installation')
11
+ ];
12
+ const cursor = timestampIdCursorWhere({
13
+ timestampColumn: providerRunners.createdAt,
14
+ idColumn: providerRunners.id,
15
+ cursor: params.cursor
16
+ });
17
+ if (cursor) conditions.push(cursor);
18
+ if (params.state) conditions.push(eq(providerRunners.state, params.state));
19
+ if (params.assignment === 'assigned') conditions.push(isNotNull(providerRunners.workspaceId));
20
+ if (params.assignment === 'unassigned') conditions.push(isNull(providerRunners.workspaceId));
21
+ if (params.label) {
22
+ const [label] = canonicalizeLabels(params.label);
23
+ if (label) conditions.push(arrayContains(providerRunners.labels, [
24
+ label
25
+ ]));
26
+ }
27
+ const rows = await db().select({
28
+ id: providerRunners.id,
29
+ workspaceId: providerRunners.workspaceId,
30
+ state: providerRunners.state,
31
+ labels: providerRunners.labels,
32
+ runnerSessionId: providerRunners.runnerSessionId,
33
+ firstClaimedAt: providerRunners.firstClaimedAt,
34
+ hasActiveControlSession: exists(db().select({
35
+ id: runnerControlSessions.id
36
+ }).from(runnerControlSessions).where(and(eq(runnerControlSessions.runnerInstanceId, providerRunners.id), isNull(runnerControlSessions.closedAt), gt(runnerControlSessions.expiresAt, sql`now()`)))),
37
+ reason: providerRunners.reason,
38
+ reportedAt: providerRunners.reportedAt,
39
+ stoppedAt: providerRunners.stoppedAt,
40
+ failedAt: providerRunners.failedAt,
41
+ terminatedAt: providerRunners.terminatedAt,
42
+ createdAt: providerRunners.createdAt,
43
+ provisionerId: provisionerTokens.id,
44
+ provisionerName: provisionerTokens.name,
45
+ provisionerLastSeenAt: provisionerTokens.lastSeenAt
46
+ }).from(providerRunners).innerJoin(provisionerTokens, eq(provisionerTokens.id, providerRunners.provisionerId)).where(and(...conditions)).orderBy(desc(providerRunners.createdAt), desc(providerRunners.id)).limit(params.limit + 1);
47
+ const hasMore = rows.length > params.limit;
48
+ const pageRows = hasMore ? rows.slice(0, params.limit) : rows;
49
+ const last = pageRows.at(-1);
50
+ return {
51
+ runners: pageRows.map((row)=>({
52
+ ...row,
53
+ hasActiveControlSession: Boolean(row.hasActiveControlSession)
54
+ })),
55
+ nextCursor: hasMore && last ? {
56
+ createdAt: last.createdAt,
57
+ id: last.id
58
+ } : null
59
+ };
60
+ }
61
+
62
+ //# sourceMappingURL=admin-runner-instances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/db/admin-runner-instances.ts"],"sourcesContent":["import {type TimestampIdCursor, timestampIdCursorWhere} from '@shipfox/node-drizzle';\nimport {canonicalizeLabels} from '@shipfox/runner-labels';\nimport {\n and,\n arrayContains,\n desc,\n eq,\n exists,\n gt,\n isNotNull,\n isNull,\n type SQL,\n sql,\n} from 'drizzle-orm';\nimport type {RunnerInstanceState} from '#core/entities/runner-instance.js';\nimport {db} from './db.js';\nimport {provisionerTokens} from './schema/provisioner-tokens.js';\nimport {runnerControlSessions} from './schema/runner-control-sessions.js';\nimport {providerRunners} from './schema/runner-instances.js';\n\nexport type AdministratorRunnerAssignmentFilter = 'assigned' | 'unassigned';\n\nexport interface AdministratorRunnerInstanceRow {\n id: string;\n workspaceId: string | null;\n state: RunnerInstanceState;\n labels: string[];\n runnerSessionId: string | null;\n firstClaimedAt: Date | null;\n hasActiveControlSession: boolean;\n reason: string | null;\n reportedAt: Date;\n stoppedAt: Date | null;\n failedAt: Date | null;\n terminatedAt: Date | null;\n createdAt: Date;\n provisionerId: string;\n provisionerName: string | null;\n provisionerLastSeenAt: Date | null;\n}\n\nexport interface ListAdministratorRunnerInstancesParams {\n limit: number;\n cursor?: TimestampIdCursor | undefined;\n state?: RunnerInstanceState | undefined;\n assignment?: AdministratorRunnerAssignmentFilter | undefined;\n label?: string | undefined;\n}\n\nexport interface ListAdministratorRunnerInstancesResult {\n runners: AdministratorRunnerInstanceRow[];\n nextCursor: TimestampIdCursor | null;\n}\n\nexport async function listAdministratorRunnerInstances(\n params: ListAdministratorRunnerInstancesParams,\n): Promise<ListAdministratorRunnerInstancesResult> {\n const conditions: SQL[] = [eq(provisionerTokens.scope, 'installation')];\n const cursor = timestampIdCursorWhere({\n timestampColumn: providerRunners.createdAt,\n idColumn: providerRunners.id,\n cursor: params.cursor,\n });\n\n if (cursor) conditions.push(cursor);\n if (params.state) conditions.push(eq(providerRunners.state, params.state));\n if (params.assignment === 'assigned') conditions.push(isNotNull(providerRunners.workspaceId));\n if (params.assignment === 'unassigned') conditions.push(isNull(providerRunners.workspaceId));\n if (params.label) {\n const [label] = canonicalizeLabels(params.label);\n if (label) conditions.push(arrayContains(providerRunners.labels, [label]));\n }\n\n const rows = await db()\n .select({\n id: providerRunners.id,\n workspaceId: providerRunners.workspaceId,\n state: providerRunners.state,\n labels: providerRunners.labels,\n runnerSessionId: providerRunners.runnerSessionId,\n firstClaimedAt: providerRunners.firstClaimedAt,\n hasActiveControlSession: exists(\n db()\n .select({id: runnerControlSessions.id})\n .from(runnerControlSessions)\n .where(\n and(\n eq(runnerControlSessions.runnerInstanceId, providerRunners.id),\n isNull(runnerControlSessions.closedAt),\n gt(runnerControlSessions.expiresAt, sql`now()`),\n ),\n ),\n ),\n reason: providerRunners.reason,\n reportedAt: providerRunners.reportedAt,\n stoppedAt: providerRunners.stoppedAt,\n failedAt: providerRunners.failedAt,\n terminatedAt: providerRunners.terminatedAt,\n createdAt: providerRunners.createdAt,\n provisionerId: provisionerTokens.id,\n provisionerName: provisionerTokens.name,\n provisionerLastSeenAt: provisionerTokens.lastSeenAt,\n })\n .from(providerRunners)\n .innerJoin(provisionerTokens, eq(provisionerTokens.id, providerRunners.provisionerId))\n .where(and(...conditions))\n .orderBy(desc(providerRunners.createdAt), desc(providerRunners.id))\n .limit(params.limit + 1);\n\n const hasMore = rows.length > params.limit;\n const pageRows = hasMore ? rows.slice(0, params.limit) : rows;\n const last = pageRows.at(-1);\n\n return {\n runners: pageRows.map((row) => ({\n ...row,\n hasActiveControlSession: Boolean(row.hasActiveControlSession),\n })),\n nextCursor: hasMore && last ? {createdAt: last.createdAt, id: last.id} : null,\n };\n}\n"],"names":["timestampIdCursorWhere","canonicalizeLabels","and","arrayContains","desc","eq","exists","gt","isNotNull","isNull","sql","db","provisionerTokens","runnerControlSessions","providerRunners","listAdministratorRunnerInstances","params","conditions","scope","cursor","timestampColumn","createdAt","idColumn","id","push","state","assignment","workspaceId","label","labels","rows","select","runnerSessionId","firstClaimedAt","hasActiveControlSession","from","where","runnerInstanceId","closedAt","expiresAt","reason","reportedAt","stoppedAt","failedAt","terminatedAt","provisionerId","provisionerName","name","provisionerLastSeenAt","lastSeenAt","innerJoin","orderBy","limit","hasMore","length","pageRows","slice","last","at","runners","map","row","Boolean","nextCursor"],"mappings":"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"}
package/dist/db/db.d.ts CHANGED
@@ -1,5 +1,133 @@
1
1
  import { type NodePgDatabase } from '@shipfox/node-drizzle';
2
2
  export declare const schema: {
3
+ runnersAdminCommandResults: import("drizzle-orm/pg-core").PgTableWithColumns<{
4
+ name: "admin_command_results";
5
+ schema: undefined;
6
+ columns: {
7
+ id: import("drizzle-orm/pg-core").PgColumn<{
8
+ name: "id";
9
+ tableName: "admin_command_results";
10
+ dataType: "string";
11
+ columnType: "PgUUID";
12
+ data: string;
13
+ driverParam: string;
14
+ notNull: true;
15
+ hasDefault: true;
16
+ isPrimaryKey: true;
17
+ isAutoincrement: false;
18
+ hasRuntimeDefault: false;
19
+ enumValues: undefined;
20
+ baseColumn: never;
21
+ identity: undefined;
22
+ generated: undefined;
23
+ }, {}, {}>;
24
+ actorId: import("drizzle-orm/pg-core").PgColumn<{
25
+ name: "actor_id";
26
+ tableName: "admin_command_results";
27
+ dataType: "string";
28
+ columnType: "PgUUID";
29
+ data: string;
30
+ driverParam: string;
31
+ notNull: true;
32
+ hasDefault: false;
33
+ isPrimaryKey: false;
34
+ isAutoincrement: false;
35
+ hasRuntimeDefault: false;
36
+ enumValues: undefined;
37
+ baseColumn: never;
38
+ identity: undefined;
39
+ generated: undefined;
40
+ }, {}, {}>;
41
+ idempotencyKeyFingerprint: import("drizzle-orm/pg-core").PgColumn<{
42
+ name: "idempotency_key_fingerprint";
43
+ tableName: "admin_command_results";
44
+ dataType: "string";
45
+ columnType: "PgText";
46
+ data: string;
47
+ driverParam: string;
48
+ notNull: true;
49
+ hasDefault: false;
50
+ isPrimaryKey: false;
51
+ isAutoincrement: false;
52
+ hasRuntimeDefault: false;
53
+ enumValues: [string, ...string[]];
54
+ baseColumn: never;
55
+ identity: undefined;
56
+ generated: undefined;
57
+ }, {}, {}>;
58
+ command: import("drizzle-orm/pg-core").PgColumn<{
59
+ name: "command";
60
+ tableName: "admin_command_results";
61
+ dataType: "string";
62
+ columnType: "PgText";
63
+ data: string;
64
+ driverParam: string;
65
+ notNull: true;
66
+ hasDefault: false;
67
+ isPrimaryKey: false;
68
+ isAutoincrement: false;
69
+ hasRuntimeDefault: false;
70
+ enumValues: [string, ...string[]];
71
+ baseColumn: never;
72
+ identity: undefined;
73
+ generated: undefined;
74
+ }, {}, {}>;
75
+ requestFingerprint: import("drizzle-orm/pg-core").PgColumn<{
76
+ name: "request_fingerprint";
77
+ tableName: "admin_command_results";
78
+ dataType: "string";
79
+ columnType: "PgText";
80
+ data: string;
81
+ driverParam: string;
82
+ notNull: true;
83
+ hasDefault: false;
84
+ isPrimaryKey: false;
85
+ isAutoincrement: false;
86
+ hasRuntimeDefault: false;
87
+ enumValues: [string, ...string[]];
88
+ baseColumn: never;
89
+ identity: undefined;
90
+ generated: undefined;
91
+ }, {}, {}>;
92
+ result: import("drizzle-orm/pg-core").PgColumn<{
93
+ name: "result";
94
+ tableName: "admin_command_results";
95
+ dataType: "json";
96
+ columnType: "PgJsonb";
97
+ data: import("./schema/admin-command-results.js").StoredProvisionerTokenAdministrationResult;
98
+ driverParam: unknown;
99
+ notNull: true;
100
+ hasDefault: false;
101
+ isPrimaryKey: false;
102
+ isAutoincrement: false;
103
+ hasRuntimeDefault: false;
104
+ enumValues: undefined;
105
+ baseColumn: never;
106
+ identity: undefined;
107
+ generated: undefined;
108
+ }, {}, {
109
+ $type: import("./schema/admin-command-results.js").StoredProvisionerTokenAdministrationResult;
110
+ }>;
111
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
112
+ name: "created_at";
113
+ tableName: "admin_command_results";
114
+ dataType: "date";
115
+ columnType: "PgTimestamp";
116
+ data: Date;
117
+ driverParam: string;
118
+ notNull: true;
119
+ hasDefault: true;
120
+ isPrimaryKey: false;
121
+ isAutoincrement: false;
122
+ hasRuntimeDefault: false;
123
+ enumValues: undefined;
124
+ baseColumn: never;
125
+ identity: undefined;
126
+ generated: undefined;
127
+ }, {}, {}>;
128
+ };
129
+ dialect: "pg";
130
+ }>;
3
131
  ephemeralRegistrationTokens: import("drizzle-orm/pg-core").PgTableWithColumns<{
4
132
  name: "ephemeral_registration_tokens";
5
133
  schema: undefined;
@@ -614,6 +742,23 @@ export declare const schema: {
614
742
  identity: undefined;
615
743
  generated: undefined;
616
744
  }, {}, {}>;
745
+ firstClaimedAt: import("drizzle-orm/pg-core").PgColumn<{
746
+ name: "first_claimed_at";
747
+ tableName: "runner_instances";
748
+ dataType: "date";
749
+ columnType: "PgTimestamp";
750
+ data: Date;
751
+ driverParam: string;
752
+ notNull: false;
753
+ hasDefault: false;
754
+ isPrimaryKey: false;
755
+ isAutoincrement: false;
756
+ hasRuntimeDefault: false;
757
+ enumValues: undefined;
758
+ baseColumn: never;
759
+ identity: undefined;
760
+ generated: undefined;
761
+ }, {}, {}>;
617
762
  providerKind: import("drizzle-orm/pg-core").PgColumn<{
618
763
  name: "provider_kind";
619
764
  tableName: "runner_instances";
@@ -3076,6 +3221,134 @@ export declare const schema: {
3076
3221
  }>;
3077
3222
  };
3078
3223
  export declare function db(): NodePgDatabase<{
3224
+ runnersAdminCommandResults: import("drizzle-orm/pg-core").PgTableWithColumns<{
3225
+ name: "admin_command_results";
3226
+ schema: undefined;
3227
+ columns: {
3228
+ id: import("drizzle-orm/pg-core").PgColumn<{
3229
+ name: "id";
3230
+ tableName: "admin_command_results";
3231
+ dataType: "string";
3232
+ columnType: "PgUUID";
3233
+ data: string;
3234
+ driverParam: string;
3235
+ notNull: true;
3236
+ hasDefault: true;
3237
+ isPrimaryKey: true;
3238
+ isAutoincrement: false;
3239
+ hasRuntimeDefault: false;
3240
+ enumValues: undefined;
3241
+ baseColumn: never;
3242
+ identity: undefined;
3243
+ generated: undefined;
3244
+ }, {}, {}>;
3245
+ actorId: import("drizzle-orm/pg-core").PgColumn<{
3246
+ name: "actor_id";
3247
+ tableName: "admin_command_results";
3248
+ dataType: "string";
3249
+ columnType: "PgUUID";
3250
+ data: string;
3251
+ driverParam: string;
3252
+ notNull: true;
3253
+ hasDefault: false;
3254
+ isPrimaryKey: false;
3255
+ isAutoincrement: false;
3256
+ hasRuntimeDefault: false;
3257
+ enumValues: undefined;
3258
+ baseColumn: never;
3259
+ identity: undefined;
3260
+ generated: undefined;
3261
+ }, {}, {}>;
3262
+ idempotencyKeyFingerprint: import("drizzle-orm/pg-core").PgColumn<{
3263
+ name: "idempotency_key_fingerprint";
3264
+ tableName: "admin_command_results";
3265
+ dataType: "string";
3266
+ columnType: "PgText";
3267
+ data: string;
3268
+ driverParam: string;
3269
+ notNull: true;
3270
+ hasDefault: false;
3271
+ isPrimaryKey: false;
3272
+ isAutoincrement: false;
3273
+ hasRuntimeDefault: false;
3274
+ enumValues: [string, ...string[]];
3275
+ baseColumn: never;
3276
+ identity: undefined;
3277
+ generated: undefined;
3278
+ }, {}, {}>;
3279
+ command: import("drizzle-orm/pg-core").PgColumn<{
3280
+ name: "command";
3281
+ tableName: "admin_command_results";
3282
+ dataType: "string";
3283
+ columnType: "PgText";
3284
+ data: string;
3285
+ driverParam: string;
3286
+ notNull: true;
3287
+ hasDefault: false;
3288
+ isPrimaryKey: false;
3289
+ isAutoincrement: false;
3290
+ hasRuntimeDefault: false;
3291
+ enumValues: [string, ...string[]];
3292
+ baseColumn: never;
3293
+ identity: undefined;
3294
+ generated: undefined;
3295
+ }, {}, {}>;
3296
+ requestFingerprint: import("drizzle-orm/pg-core").PgColumn<{
3297
+ name: "request_fingerprint";
3298
+ tableName: "admin_command_results";
3299
+ dataType: "string";
3300
+ columnType: "PgText";
3301
+ data: string;
3302
+ driverParam: string;
3303
+ notNull: true;
3304
+ hasDefault: false;
3305
+ isPrimaryKey: false;
3306
+ isAutoincrement: false;
3307
+ hasRuntimeDefault: false;
3308
+ enumValues: [string, ...string[]];
3309
+ baseColumn: never;
3310
+ identity: undefined;
3311
+ generated: undefined;
3312
+ }, {}, {}>;
3313
+ result: import("drizzle-orm/pg-core").PgColumn<{
3314
+ name: "result";
3315
+ tableName: "admin_command_results";
3316
+ dataType: "json";
3317
+ columnType: "PgJsonb";
3318
+ data: import("./schema/admin-command-results.js").StoredProvisionerTokenAdministrationResult;
3319
+ driverParam: unknown;
3320
+ notNull: true;
3321
+ hasDefault: false;
3322
+ isPrimaryKey: false;
3323
+ isAutoincrement: false;
3324
+ hasRuntimeDefault: false;
3325
+ enumValues: undefined;
3326
+ baseColumn: never;
3327
+ identity: undefined;
3328
+ generated: undefined;
3329
+ }, {}, {
3330
+ $type: import("./schema/admin-command-results.js").StoredProvisionerTokenAdministrationResult;
3331
+ }>;
3332
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
3333
+ name: "created_at";
3334
+ tableName: "admin_command_results";
3335
+ dataType: "date";
3336
+ columnType: "PgTimestamp";
3337
+ data: Date;
3338
+ driverParam: string;
3339
+ notNull: true;
3340
+ hasDefault: true;
3341
+ isPrimaryKey: false;
3342
+ isAutoincrement: false;
3343
+ hasRuntimeDefault: false;
3344
+ enumValues: undefined;
3345
+ baseColumn: never;
3346
+ identity: undefined;
3347
+ generated: undefined;
3348
+ }, {}, {}>;
3349
+ };
3350
+ dialect: "pg";
3351
+ }>;
3079
3352
  ephemeralRegistrationTokens: import("drizzle-orm/pg-core").PgTableWithColumns<{
3080
3353
  name: "ephemeral_registration_tokens";
3081
3354
  schema: undefined;
@@ -3690,6 +3963,23 @@ export declare function db(): NodePgDatabase<{
3690
3963
  identity: undefined;
3691
3964
  generated: undefined;
3692
3965
  }, {}, {}>;
3966
+ firstClaimedAt: import("drizzle-orm/pg-core").PgColumn<{
3967
+ name: "first_claimed_at";
3968
+ tableName: "runner_instances";
3969
+ dataType: "date";
3970
+ columnType: "PgTimestamp";
3971
+ data: Date;
3972
+ driverParam: string;
3973
+ notNull: false;
3974
+ hasDefault: false;
3975
+ isPrimaryKey: false;
3976
+ isAutoincrement: false;
3977
+ hasRuntimeDefault: false;
3978
+ enumValues: undefined;
3979
+ baseColumn: never;
3980
+ identity: undefined;
3981
+ generated: undefined;
3982
+ }, {}, {}>;
3693
3983
  providerKind: import("drizzle-orm/pg-core").PgColumn<{
3694
3984
  name: "provider_kind";
3695
3985
  tableName: "runner_instances";
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAgBnE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAelB,CAAC;AAIF,wBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGjB;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B;AAED,MAAM,MAAM,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAiBnE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBlB,CAAC;AAIF,wBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGjB;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B;AAED,MAAM,MAAM,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
package/dist/db/db.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { drizzle } from '@shipfox/node-drizzle';
2
2
  import { pgClient } from '@shipfox/node-postgres';
3
+ import { runnersAdminCommandResults } from './schema/admin-command-results.js';
3
4
  import { ephemeralRegistrationTokens } from './schema/ephemeral-registration-tokens.js';
4
5
  import { manualRegistrationTokens } from './schema/manual-registration-tokens.js';
5
6
  import { runnersOutbox } from './schema/outbox.js';
@@ -14,6 +15,7 @@ import { providerRunners } from './schema/runner-instances.js';
14
15
  import { runnerSessions } from './schema/runner-sessions.js';
15
16
  import { runningJobExecutions } from './schema/running-job-executions.js';
16
17
  export const schema = {
18
+ runnersAdminCommandResults,
17
19
  ephemeralRegistrationTokens,
18
20
  pendingJobExecutions,
19
21
  providerRunners,