@keboola/api-fixtures 19.0.0 → 22.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.
package/AGENTS.md ADDED
@@ -0,0 +1,63 @@
1
+ # @keboola/api-fixtures
2
+
3
+ Hand-written, typed test fixtures keyed by Keboola API endpoint.
4
+
5
+ ## What's in this package
6
+
7
+ Static factory functions that return realistic data objects matching the shapes
8
+ returned by `@keboola/api-client`. Each fixture is typed against the OpenAPI-derived
9
+ types in `api-client` so that any contract drift between fixtures and the live schema
10
+ becomes a TypeScript compile error.
11
+
12
+ Current slices:
13
+
14
+ - `storage.tables` — `getTable()`, `listTables()`, `tableFixtures`
15
+ - `apps.apps` / `apps.deployments` / `apps.runs` — the sandboxes-service `/v2` App Deployments
16
+ surface. The three compose into one coherent app (an app's `production` names a deployment in
17
+ `listDeployments()`; runs name deployments that exist), so a fixture added here must keep that
18
+ join intact — `apps.test.ts` is what enforces it.
19
+
20
+ ## When to use fixtures vs MSW vs real API
21
+
22
+ | Need | Reach for |
23
+ | --------------------------------------------------------- | ---------------------------------------------- |
24
+ | Unit / component tests, pure rendering | **This package** — zero network, deterministic |
25
+ | Integration tests that need request/response interception | **MSW** (`msw` handlers) |
26
+ | Full end-to-end or contract validation | Real API (see `@keboola/e2e-testing`) |
27
+
28
+ ## Adding a new endpoint slice
29
+
30
+ 1. Create `src/clients/<service>/<resource>.ts`.
31
+ 2. Import the relevant type(s) from `@keboola/api-client/<service>/types`.
32
+ 3. Write named factory functions (`get<Resource>()`, `list<Resources>()`) with explicit
33
+ return types drawn from the OpenAPI-generated types. Do not introduce `any` or `unknown`
34
+ yourself; `unknown` is acceptable only when it propagates from the contract type (e.g.
35
+ `TableDetail['attributes']` is `unknown[]`). Prefer `T['prop']` aliases or contextual
36
+ typing via `satisfies T` over re-asserting the upstream type.
37
+ 4. Export a named fixtures object (`<resource>Fixtures`) using
38
+ `satisfies Record<'<key1>' | '<key2>' | …, T>` so missing or renamed keys become a
39
+ compile-time error.
40
+ 5. Re-export everything from `src/index.ts`.
41
+ 6. Add a vitest smoke test in `<resource>.test.ts` that verifies shape + assigns to the
42
+ typed variable (compile-time contract check).
43
+ 7. Wire the slice into `src/fixtures.ts` under the appropriate namespace.
44
+
45
+ ## The typing rule
46
+
47
+ Every fixture **must** be typed by the corresponding OpenAPI schema type from
48
+ `@keboola/api-client`. This is intentional SSOT enforcement: the OpenAPI contract is the
49
+ source of truth; fixtures are downstream consumers.
50
+
51
+ ```ts
52
+ // Good — type checked against contract
53
+ export const getTable = (): TableDetail => myFixture;
54
+
55
+ // Bad — drifts silently
56
+ export const getTable = () => myFixture;
57
+ ```
58
+
59
+ ## Generation (future)
60
+
61
+ Hand-written + typed-against-schema is the current strategy. A `scripts/generate.ts`
62
+ that reads OpenAPI `example` fields and emits fixture stubs is tracked as a follow-up
63
+ to UT-3930 (epic UT-3919).
package/dist/index.cjs CHANGED
@@ -1,5 +1,262 @@
1
1
  'use strict';
2
2
 
3
+ // src/clients/apps/deployments.ts
4
+ var APP_ID = "374811";
5
+ var deploymentId = (hash) => `app-${APP_ID}-dpl-${hash}`;
6
+ var archivedDeployment = {
7
+ id: deploymentId("350e2cf5287c5665"),
8
+ number: 1,
9
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
10
+ configVersion: "14",
11
+ gitCommitSha: null,
12
+ size: "tiny",
13
+ buildState: "PREBUILT",
14
+ runState: "STOPPED",
15
+ archived: true,
16
+ archivedAt: "2026-08-15T11:03:02+00:00",
17
+ createdAt: "2026-08-10T09:12:44+00:00"
18
+ };
19
+ var liveDeployment = {
20
+ id: deploymentId("7a4c1b9e0d3f2a81"),
21
+ number: 2,
22
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
23
+ configVersion: "16",
24
+ gitCommitSha: null,
25
+ size: "small",
26
+ buildState: "PREBUILT",
27
+ runState: "RUNNING",
28
+ archived: false,
29
+ archivedAt: null,
30
+ createdAt: "2026-08-15T11:02:58+00:00"
31
+ };
32
+ var stagedDeployment = {
33
+ id: deploymentId("c5e83f17b204de96"),
34
+ number: 3,
35
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
36
+ configVersion: "18",
37
+ gitCommitSha: null,
38
+ size: "small",
39
+ buildState: "PREBUILT",
40
+ runState: "NEVER_RUN",
41
+ archived: false,
42
+ archivedAt: null,
43
+ createdAt: "2026-08-17T08:41:19+00:00"
44
+ };
45
+ var buildFailedDeployment = {
46
+ id: deploymentId("e91d47a8c6b02f35"),
47
+ number: 4,
48
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
49
+ configVersion: "19",
50
+ gitCommitSha: null,
51
+ size: "small",
52
+ buildState: "FAILED",
53
+ runState: "NEVER_RUN",
54
+ archived: false,
55
+ archivedAt: null,
56
+ createdAt: "2026-08-17T09:05:33+00:00"
57
+ };
58
+ var runFailedDeployment = {
59
+ id: deploymentId("2b6f0a94e7d51c83"),
60
+ number: 5,
61
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
62
+ configVersion: "20",
63
+ gitCommitSha: null,
64
+ size: "small",
65
+ buildState: "PREBUILT",
66
+ runState: "FAILED",
67
+ archived: false,
68
+ archivedAt: null,
69
+ createdAt: "2026-08-17T09:31:07+00:00"
70
+ };
71
+ var deploymentFixtures = {
72
+ archived: archivedDeployment,
73
+ live: liveDeployment,
74
+ staged: stagedDeployment,
75
+ buildFailed: buildFailedDeployment,
76
+ runFailed: runFailedDeployment
77
+ };
78
+ var getDeployment = () => liveDeployment;
79
+ var listDeployments = () => [
80
+ archivedDeployment,
81
+ liveDeployment,
82
+ stagedDeployment,
83
+ buildFailedDeployment,
84
+ runFailedDeployment
85
+ ];
86
+
87
+ // src/clients/apps/apps.ts
88
+ var APP_URL = "https://hello-dashboard-374811.hub.canary-orion.keboola.dev";
89
+ var base = {
90
+ id: APP_ID,
91
+ projectId: "14",
92
+ componentId: "keboola.data-apps",
93
+ branchId: "6",
94
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
95
+ type: "streamlit",
96
+ mode: "prod",
97
+ url: APP_URL
98
+ };
99
+ var production = (deployment) => ({
100
+ desiredNumber: deployment.number,
101
+ desiredId: deployment.id,
102
+ actualNumber: deployment.number,
103
+ actualId: deployment.id
104
+ });
105
+ var neverDeployedApp = {
106
+ ...base,
107
+ configVersion: "1",
108
+ production: { desiredNumber: null, desiredId: null, actualNumber: null, actualId: null },
109
+ undeployedChanges: false,
110
+ state: "NOT_DEPLOYED"
111
+ };
112
+ var legacyV1ServingApp = {
113
+ id: "374811",
114
+ projectId: "14",
115
+ componentId: "keboola.data-apps",
116
+ branchId: "6",
117
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
118
+ configVersion: "2",
119
+ type: "streamlit",
120
+ mode: "dev",
121
+ url: APP_URL,
122
+ production: { desiredNumber: null, desiredId: null, actualNumber: null, actualId: null },
123
+ undeployedChanges: false,
124
+ state: "NOT_DEPLOYED"
125
+ };
126
+ var runningApp = {
127
+ ...base,
128
+ configVersion: deploymentFixtures.live.configVersion,
129
+ production: production(deploymentFixtures.live),
130
+ undeployedChanges: false,
131
+ state: "RUNNING"
132
+ };
133
+ var appWithUndeployedChanges = {
134
+ ...base,
135
+ configVersion: deploymentFixtures.staged.configVersion,
136
+ production: production(deploymentFixtures.live),
137
+ undeployedChanges: true,
138
+ state: "RUNNING"
139
+ };
140
+ var promotingApp = {
141
+ ...base,
142
+ configVersion: deploymentFixtures.staged.configVersion,
143
+ production: {
144
+ desiredNumber: deploymentFixtures.staged.number,
145
+ desiredId: deploymentFixtures.staged.id,
146
+ actualNumber: deploymentFixtures.live.number,
147
+ actualId: deploymentFixtures.live.id
148
+ },
149
+ undeployedChanges: true,
150
+ state: "RUNNING"
151
+ };
152
+ var sleepingApp = {
153
+ ...base,
154
+ configVersion: deploymentFixtures.live.configVersion,
155
+ production: production(deploymentFixtures.live),
156
+ undeployedChanges: false,
157
+ state: "SLEEPING"
158
+ };
159
+ var suspendedApp = {
160
+ ...base,
161
+ configVersion: deploymentFixtures.live.configVersion,
162
+ production: production(deploymentFixtures.live),
163
+ undeployedChanges: false,
164
+ state: "SUSPENDED"
165
+ };
166
+ var appFixtures = {
167
+ neverDeployed: neverDeployedApp,
168
+ legacyV1Serving: legacyV1ServingApp,
169
+ running: runningApp,
170
+ undeployedChanges: appWithUndeployedChanges,
171
+ promoting: promotingApp,
172
+ sleeping: sleepingApp,
173
+ suspended: suspendedApp
174
+ };
175
+ var getApp = () => runningApp;
176
+ var readdress = (app, id) => ({
177
+ ...app,
178
+ id,
179
+ url: `https://data-app-${id}.hub.canary-orion.keboola.dev`,
180
+ production: {
181
+ ...app.production,
182
+ desiredId: app.production.desiredId?.replace(APP_ID, id) ?? null,
183
+ actualId: app.production.actualId?.replace(APP_ID, id) ?? null
184
+ }
185
+ });
186
+ var listApps = () => [
187
+ runningApp,
188
+ readdress(appWithUndeployedChanges, "374812"),
189
+ readdress(neverDeployedApp, "374813")
190
+ ];
191
+
192
+ // src/clients/apps/runs.ts
193
+ var base2 = {
194
+ appId: APP_ID,
195
+ runtimeSize: "small",
196
+ runtimeBackendType: "streamlit",
197
+ imageVersion: "1.14.2",
198
+ mode: "prod"
199
+ };
200
+ var runningRun = {
201
+ ...base2,
202
+ id: "4f2d8c1a-0b76-4e35-9a12-5c8e7d3b0f41",
203
+ deploymentId: deploymentFixtures.live.id,
204
+ configVersion: deploymentFixtures.live.configVersion,
205
+ state: "running",
206
+ createdAt: "2026-08-15T11:02:58+00:00",
207
+ startedAt: "2026-08-15T11:03:41+00:00",
208
+ stoppedAt: null,
209
+ startupLogs: null,
210
+ failureReason: null
211
+ };
212
+ var finishedRun = {
213
+ ...base2,
214
+ id: "9c0a7e42-31bd-4f88-b6d5-2ea41f907c3b",
215
+ deploymentId: deploymentFixtures.archived.id,
216
+ configVersion: deploymentFixtures.archived.configVersion,
217
+ state: "finished",
218
+ createdAt: "2026-08-10T09:12:44+00:00",
219
+ startedAt: "2026-08-10T09:13:29+00:00",
220
+ stoppedAt: "2026-08-15T11:03:02+00:00",
221
+ startupLogs: null,
222
+ failureReason: null
223
+ };
224
+ var failedRun = {
225
+ ...base2,
226
+ id: "ba53f9d0-7c41-4a2e-8f16-d0b9e254a7c6",
227
+ deploymentId: deploymentFixtures.runFailed.id,
228
+ configVersion: deploymentFixtures.runFailed.configVersion,
229
+ state: "failed",
230
+ createdAt: "2026-08-17T09:31:07+00:00",
231
+ startedAt: null,
232
+ stoppedAt: "2026-08-17T09:33:52+00:00",
233
+ startupLogs: "[INFO] Starting app\n[ERROR] App must have keboola-config/nginx/ directory. Missing: /app/keboola-config/nginx\n",
234
+ failureReason: {
235
+ reason: "StartupProbeFailed",
236
+ message: "App must have keboola-config/nginx/ directory. Missing: /app/keboola-config/nginx"
237
+ }
238
+ };
239
+ var legacyRun = {
240
+ ...base2,
241
+ id: "1d7b4e05-8a92-4c63-b0f7-3e6a5c8192d4",
242
+ deploymentId: null,
243
+ configVersion: "2",
244
+ state: "running",
245
+ createdAt: "2026-08-17T10:02:11+00:00",
246
+ startedAt: "2026-08-17T10:02:51+00:00",
247
+ stoppedAt: null,
248
+ startupLogs: null,
249
+ failureReason: null
250
+ };
251
+ var runFixtures = {
252
+ running: runningRun,
253
+ finished: finishedRun,
254
+ failed: failedRun,
255
+ legacy: legacyRun
256
+ };
257
+ var getAppRun = () => runningRun;
258
+ var listAppRuns = () => [legacyRun, failedRun, runningRun, finishedRun];
259
+
3
260
  // src/clients/storage/tables.ts
4
261
  var bucket = {
5
262
  id: "in.c-main",
@@ -100,12 +357,38 @@ var fixtures = {
100
357
  listTables,
101
358
  fixtures: tableFixtures
102
359
  }
360
+ },
361
+ apps: {
362
+ apps: {
363
+ getApp,
364
+ listApps,
365
+ fixtures: appFixtures
366
+ },
367
+ deployments: {
368
+ getDeployment,
369
+ listDeployments,
370
+ fixtures: deploymentFixtures
371
+ },
372
+ runs: {
373
+ getAppRun,
374
+ listAppRuns,
375
+ fixtures: runFixtures
376
+ }
103
377
  }
104
378
  };
105
379
 
380
+ exports.appFixtures = appFixtures;
381
+ exports.deploymentFixtures = deploymentFixtures;
106
382
  exports.fixtures = fixtures;
383
+ exports.getApp = getApp;
384
+ exports.getAppRun = getAppRun;
385
+ exports.getDeployment = getDeployment;
107
386
  exports.getTable = getTable;
387
+ exports.listAppRuns = listAppRuns;
388
+ exports.listApps = listApps;
389
+ exports.listDeployments = listDeployments;
108
390
  exports.listTables = listTables;
391
+ exports.runFixtures = runFixtures;
109
392
  exports.tableFixtures = tableFixtures;
110
393
  //# sourceMappingURL=index.cjs.map
111
394
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/clients/storage/tables.ts","../src/fixtures.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Table, TableDetail } from '@keboola/api-client/storage/types';\n\nconst bucket = {\n id: 'in.c-main',\n name: 'c-main',\n displayName: 'Main',\n stage: 'in' as const,\n description: 'Main input bucket',\n created: '2024-01-15T10:00:00+0100',\n lastChangeDate: '2024-03-10T08:30:00+0100',\n isMaintenance: false,\n isReadOnly: false,\n isSnowflakeSharedDatabase: false,\n hasExternalSchema: false,\n rowsCount: 150000,\n dataSizeBytes: 52428800,\n uri: 'https://connection.keboola.com/v2/storage/buckets/in.c-main',\n backend: 'snowflake' as const,\n backendPath: [],\n databaseName: null,\n color: null,\n idBranch: 0,\n owner: null,\n sharing: null,\n path: 'in.c-main',\n tables: 'https://connection.keboola.com/v2/storage/buckets/in.c-main/tables',\n updated: '2024-03-10T08:30:00+0100',\n};\n\n// A freshly created table with no imports yet (non-typed, non-alias variant).\nconst freshTable = {\n id: 'in.c-main.users',\n name: 'users',\n displayName: 'Users',\n primaryKey: ['id'],\n metadata: [],\n columns: ['id', 'email', 'name', 'created_at'],\n columnMetadata: {},\n attributes: [],\n bucket,\n isTyped: false as const,\n isAlias: false as const,\n} satisfies TableDetail;\n\n// A recently updated table with a moderate size (non-typed, non-alias variant).\nconst recentlyUpdatedTable = {\n id: 'in.c-main.orders',\n name: 'orders',\n displayName: 'Orders',\n primaryKey: ['order_id'],\n metadata: [\n {\n id: 'mt1',\n key: 'KBC.createdBy.component.id',\n value: 'keboola.python-transformation',\n provider: 'keboola',\n timestamp: '2024-06-01T09:00:00+0200',\n },\n ],\n columns: ['order_id', 'user_id', 'total', 'status', 'created_at', 'updated_at'],\n columnMetadata: {\n order_id: [\n {\n id: 'm1',\n key: 'KBC.datatype.type',\n value: 'INTEGER',\n provider: 'keboola',\n timestamp: '2024-06-01T09:00:00+0200',\n },\n ],\n },\n attributes: [],\n bucket,\n isTyped: false as const,\n isAlias: false as const,\n} satisfies TableDetail;\n\n// A large table with many rows representing high-volume data (non-typed, non-alias variant).\nconst largeTable = {\n id: 'in.c-main.events',\n name: 'events',\n displayName: 'Events',\n primaryKey: [],\n metadata: [],\n columns: ['event_id', 'user_id', 'event_type', 'properties', 'occurred_at'],\n columnMetadata: {},\n attributes: [],\n bucket,\n isTyped: false as const,\n isAlias: false as const,\n} satisfies TableDetail;\n\n/**\n * Returns a single realistic typed TableDetail (fresh, no imports yet).\n *\n * The explicit return type ensures any divergence from the OpenAPI-derived\n * `TableDetail` in `@keboola/api-client` surfaces as a TypeScript error.\n */\nexport const getTable = (): TableDetail => freshTable;\n\n/**\n * Returns three TableDetail objects representing different lifecycle states:\n * 1. Fresh — just created, no data imported.\n * 2. Recently updated — moderate size, recent import.\n * 3. Large — high row count, large byte size.\n */\nexport const listTables = (): TableDetail[] => [freshTable, recentlyUpdatedTable, largeTable];\n\n/**\n * Named fixtures for targeted access in tests.\n */\nexport const tableFixtures = {\n fresh: freshTable,\n recentlyUpdated: recentlyUpdatedTable,\n large: largeTable,\n} satisfies Record<'fresh' | 'recentlyUpdated' | 'large', TableDetail>;\n\nexport type { Table, TableDetail };\n","import { getTable, listTables, tableFixtures } from './clients/storage/tables';\n\nexport const fixtures = {\n storage: {\n tables: {\n getTable,\n listTables,\n fixtures: tableFixtures,\n },\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/clients/apps/deployments.ts","../src/clients/apps/apps.ts","../src/clients/apps/runs.ts","../src/clients/storage/tables.ts","../src/fixtures.ts"],"names":["base"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Deployment } from '@keboola/api-client/apps/types';\n\n/**\n * Deployment ids are the deterministic Kubernetes CR name — `app-{appId}-dpl-{hash}` —\n * so they are reproduced in that shape rather than as opaque strings.\n */\nexport const APP_ID = '374811';\n\nconst deploymentId = (hash: string) => `app-${APP_ID}-dpl-${hash}`;\n\n// Retired: the row outlives its CR, so it stays in history with `archived: true`.\nconst archivedDeployment = {\n id: deploymentId('350e2cf5287c5665'),\n number: 1,\n configId: '01kz9kny4n49x3xk0e4k8ynpmq',\n configVersion: '14',\n gitCommitSha: null,\n size: 'tiny' as const,\n buildState: 'PREBUILT' as const,\n runState: 'STOPPED' as const,\n archived: true,\n archivedAt: '2026-08-15T11:03:02+00:00',\n createdAt: '2026-08-10T09:12:44+00:00',\n} satisfies Deployment;\n\n// Serving production — the one `appFixtures.running.production` points at.\nconst liveDeployment = {\n id: deploymentId('7a4c1b9e0d3f2a81'),\n number: 2,\n configId: '01kz9kny4n49x3xk0e4k8ynpmq',\n configVersion: '16',\n gitCommitSha: null,\n size: 'small' as const,\n buildState: 'PREBUILT' as const,\n runState: 'RUNNING' as const,\n archived: false,\n archivedAt: null,\n createdAt: '2026-08-15T11:02:58+00:00',\n} satisfies Deployment;\n\n// Created with `promote: false`: pinned and built, but nothing ever started it.\nconst stagedDeployment = {\n id: deploymentId('c5e83f17b204de96'),\n number: 3,\n configId: '01kz9kny4n49x3xk0e4k8ynpmq',\n configVersion: '18',\n gitCommitSha: null,\n size: 'small' as const,\n buildState: 'PREBUILT' as const,\n runState: 'NEVER_RUN' as const,\n archived: false,\n archivedAt: null,\n createdAt: '2026-08-17T08:41:19+00:00',\n} satisfies Deployment;\n\n// No artifact was produced, so this deployment can never run — a different problem,\n// with a different fix, from a run failure. Not reachable on the platform today\n// (every deployment is `PREBUILT`); the headline table treats it as a contract.\nconst buildFailedDeployment = {\n id: deploymentId('e91d47a8c6b02f35'),\n number: 4,\n configId: '01kz9kny4n49x3xk0e4k8ynpmq',\n configVersion: '19',\n gitCommitSha: null,\n size: 'small' as const,\n buildState: 'FAILED' as const,\n runState: 'NEVER_RUN' as const,\n archived: false,\n archivedAt: null,\n createdAt: '2026-08-17T09:05:33+00:00',\n} satisfies Deployment;\n\n// Built fine, crashed on every run — `getAppRuns` carries the cause.\nconst runFailedDeployment = {\n id: deploymentId('2b6f0a94e7d51c83'),\n number: 5,\n configId: '01kz9kny4n49x3xk0e4k8ynpmq',\n configVersion: '20',\n gitCommitSha: null,\n size: 'small' as const,\n buildState: 'PREBUILT' as const,\n runState: 'FAILED' as const,\n archived: false,\n archivedAt: null,\n createdAt: '2026-08-17T09:31:07+00:00',\n} satisfies Deployment;\n\nexport const deploymentFixtures = {\n archived: archivedDeployment,\n live: liveDeployment,\n staged: stagedDeployment,\n buildFailed: buildFailedDeployment,\n runFailed: runFailedDeployment,\n} satisfies Record<'archived' | 'live' | 'staged' | 'buildFailed' | 'runFailed', Deployment>;\n\nexport const getDeployment = (): Deployment => liveDeployment;\n\n/**\n * One continuous history: #1 retired, #2 serving, #3 staged, #4 failed to build, #5 built but its\n * run failed.\n *\n * All five, because `runFixtures.failed` names #5 as its deployment — a list that left the failed\n * ones out could not be joined to the runs, which is the join a timeline is built from.\n *\n * Returned in ascending `number` order. The endpoint does not specify an order, so consumers must\n * sort for themselves — this order is a fixture convention, not a contract to rely on, and it is\n * ascending on purpose: a consumer that assumes newest-first gets the wrong answer here rather\n * than in production.\n */\nexport const listDeployments = (): Deployment[] => [\n archivedDeployment,\n liveDeployment,\n stagedDeployment,\n buildFailedDeployment,\n runFailedDeployment,\n];\n","import type { App } from '@keboola/api-client/apps/types';\n\nimport { APP_ID, deploymentFixtures } from './deployments';\n\nconst APP_URL = 'https://hello-dashboard-374811.hub.canary-orion.keboola.dev';\n\nconst base = {\n id: APP_ID,\n projectId: '14',\n componentId: 'keboola.data-apps',\n branchId: '6',\n configId: '01kz9kny4n49x3xk0e4k8ynpmq',\n type: 'streamlit' as const,\n mode: 'prod' as const,\n url: APP_URL,\n};\n\nconst production = (deployment: (typeof deploymentFixtures)[keyof typeof deploymentFixtures]) => ({\n desiredNumber: deployment.number,\n desiredId: deployment.id,\n actualNumber: deployment.number,\n actualId: deployment.id,\n});\n\n// Created through `/v2`, nothing deployed yet: the URL is reserved and publicly 404s.\nconst neverDeployedApp = {\n ...base,\n configVersion: '1',\n production: { desiredNumber: null, desiredId: null, actualNumber: null, actualId: null },\n undeployedChanges: false,\n state: 'NOT_DEPLOYED' as const,\n} satisfies App;\n\n/**\n * Transcribed verbatim from canary on 17 Aug 2026 (AJDA-3140, probe P1): an app created and\n * started through `/v1`, serving real traffic (HTTP 200, 8340 B) at the moment this was read,\n * which `/v2` nonetheless reports as `NOT_DEPLOYED` with an empty `production` because it was\n * never adopted into the deployments model.\n *\n * The Builder must never read \"is this app serving\" off `state` alone — here that answer is\n * wrong in the most damaging direction.\n */\nconst legacyV1ServingApp = {\n id: '374811',\n projectId: '14',\n componentId: 'keboola.data-apps',\n branchId: '6',\n configId: '01kz9kny4n49x3xk0e4k8ynpmq',\n configVersion: '2',\n type: 'streamlit' as const,\n mode: 'dev' as const,\n url: APP_URL,\n production: { desiredNumber: null, desiredId: null, actualNumber: null, actualId: null },\n undeployedChanges: false,\n state: 'NOT_DEPLOYED' as const,\n} satisfies App;\n\n// Serving deployment #2, config unchanged since it was deployed.\nconst runningApp = {\n ...base,\n configVersion: deploymentFixtures.live.configVersion,\n production: production(deploymentFixtures.live),\n undeployedChanges: false,\n state: 'RUNNING' as const,\n} satisfies App;\n\n// Still serving #2 (config v16) while the config has moved on to v18.\nconst appWithUndeployedChanges = {\n ...base,\n configVersion: deploymentFixtures.staged.configVersion,\n production: production(deploymentFixtures.live),\n undeployedChanges: true,\n state: 'RUNNING' as const,\n} satisfies App;\n\n/**\n * A blue/green promotion in flight: #3 has been asked for, #2 is still what traffic reaches.\n * `state` stays `RUNNING` throughout — the rollout is only visible as `desiredId !== actualId`.\n */\nconst promotingApp = {\n ...base,\n configVersion: deploymentFixtures.staged.configVersion,\n production: {\n desiredNumber: deploymentFixtures.staged.number,\n desiredId: deploymentFixtures.staged.id,\n actualNumber: deploymentFixtures.live.number,\n actualId: deploymentFixtures.live.id,\n },\n undeployedChanges: true,\n state: 'RUNNING' as const,\n} satisfies App;\n\n// Idle between visits and armed to wake on the next request — normal, not an outage.\nconst sleepingApp = {\n ...base,\n configVersion: deploymentFixtures.live.configVersion,\n production: production(deploymentFixtures.live),\n undeployedChanges: false,\n state: 'SLEEPING' as const,\n} satisfies App;\n\n// Explicitly suspended: a visitor gets a 503 until someone resumes it.\nconst suspendedApp = {\n ...base,\n configVersion: deploymentFixtures.live.configVersion,\n production: production(deploymentFixtures.live),\n undeployedChanges: false,\n state: 'SUSPENDED' as const,\n} satisfies App;\n\nexport const appFixtures = {\n neverDeployed: neverDeployedApp,\n legacyV1Serving: legacyV1ServingApp,\n running: runningApp,\n undeployedChanges: appWithUndeployedChanges,\n promoting: promotingApp,\n sleeping: sleepingApp,\n suspended: suspendedApp,\n} satisfies Record<\n | 'neverDeployed'\n | 'legacyV1Serving'\n | 'running'\n | 'undeployedChanges'\n | 'promoting'\n | 'sleeping'\n | 'suspended',\n App\n>;\n\nexport const getApp = (): App => runningApp;\n\n/**\n * The named fixtures above are all the *same* app in different states, which is what a detail\n * page shows. A listing shows different apps, so each entry past the first is re-addressed —\n * including the deployment ids inside `production`, which embed the app id.\n */\nconst readdress = (app: App, id: string): App => ({\n ...app,\n id,\n url: `https://data-app-${id}.hub.canary-orion.keboola.dev`,\n production: {\n ...app.production,\n desiredId: app.production.desiredId?.replace(APP_ID, id) ?? null,\n actualId: app.production.actualId?.replace(APP_ID, id) ?? null,\n },\n});\n\nexport const listApps = (): App[] => [\n runningApp,\n readdress(appWithUndeployedChanges, '374812'),\n readdress(neverDeployedApp, '374813'),\n];\n","import type { AppRun } from '@keboola/api-client/apps/types';\n\nimport { APP_ID, deploymentFixtures } from './deployments';\n\nconst base = {\n appId: APP_ID,\n runtimeSize: 'small',\n runtimeBackendType: 'streamlit',\n imageVersion: '1.14.2',\n mode: 'prod',\n};\n\nconst runningRun = {\n ...base,\n id: '4f2d8c1a-0b76-4e35-9a12-5c8e7d3b0f41',\n deploymentId: deploymentFixtures.live.id,\n configVersion: deploymentFixtures.live.configVersion,\n state: 'running' as const,\n createdAt: '2026-08-15T11:02:58+00:00',\n startedAt: '2026-08-15T11:03:41+00:00',\n stoppedAt: null,\n startupLogs: null,\n failureReason: null,\n} satisfies AppRun;\n\nconst finishedRun = {\n ...base,\n id: '9c0a7e42-31bd-4f88-b6d5-2ea41f907c3b',\n deploymentId: deploymentFixtures.archived.id,\n configVersion: deploymentFixtures.archived.configVersion,\n state: 'finished' as const,\n createdAt: '2026-08-10T09:12:44+00:00',\n startedAt: '2026-08-10T09:13:29+00:00',\n stoppedAt: '2026-08-15T11:03:02+00:00',\n startupLogs: null,\n failureReason: null,\n} satisfies AppRun;\n\n/**\n * A classified failure transcribed from canary (AJDA-3140, probe P1). `startedAt` is `null`\n * even though a cause was attributed — the container executed but its startup probe never\n * passed, so a classified failure says nothing about how far the run got.\n */\nconst failedRun = {\n ...base,\n id: 'ba53f9d0-7c41-4a2e-8f16-d0b9e254a7c6',\n deploymentId: deploymentFixtures.runFailed.id,\n configVersion: deploymentFixtures.runFailed.configVersion,\n state: 'failed' as const,\n createdAt: '2026-08-17T09:31:07+00:00',\n startedAt: null,\n stoppedAt: '2026-08-17T09:33:52+00:00',\n startupLogs:\n '[INFO] Starting app\\n[ERROR] App must have keboola-config/nginx/ directory. Missing: /app/keboola-config/nginx\\n',\n failureReason: {\n reason: 'StartupProbeFailed',\n message: 'App must have keboola-config/nginx/ directory. Missing: /app/keboola-config/nginx',\n },\n} satisfies AppRun;\n\n/**\n * A run that belongs to the app itself rather than to a deployment — what every run of a\n * `/v1`-created app looks like. `deploymentId: null` is permanent for these, not drift.\n */\nconst legacyRun = {\n ...base,\n id: '1d7b4e05-8a92-4c63-b0f7-3e6a5c8192d4',\n deploymentId: null,\n configVersion: '2',\n state: 'running' as const,\n createdAt: '2026-08-17T10:02:11+00:00',\n startedAt: '2026-08-17T10:02:51+00:00',\n stoppedAt: null,\n startupLogs: null,\n failureReason: null,\n} satisfies AppRun;\n\nexport const runFixtures = {\n running: runningRun,\n finished: finishedRun,\n failed: failedRun,\n legacy: legacyRun,\n} satisfies Record<'running' | 'finished' | 'failed' | 'legacy', AppRun>;\n\nexport const getAppRun = (): AppRun => runningRun;\n\n/**\n * Every run this app has, newest first — the order the endpoint documents, so a consumer that\n * relies on it (`[latest] = runs`) is exercised against data that keeps the promise rather than\n * data that happens to contradict it.\n */\nexport const listAppRuns = (): AppRun[] => [legacyRun, failedRun, runningRun, finishedRun];\n","import type { Table, TableDetail } from '@keboola/api-client/storage/types';\n\nconst bucket = {\n id: 'in.c-main',\n name: 'c-main',\n displayName: 'Main',\n stage: 'in' as const,\n description: 'Main input bucket',\n created: '2024-01-15T10:00:00+0100',\n lastChangeDate: '2024-03-10T08:30:00+0100',\n isMaintenance: false,\n isReadOnly: false,\n isSnowflakeSharedDatabase: false,\n hasExternalSchema: false,\n rowsCount: 150000,\n dataSizeBytes: 52428800,\n uri: 'https://connection.keboola.com/v2/storage/buckets/in.c-main',\n backend: 'snowflake' as const,\n backendPath: [],\n databaseName: null,\n color: null,\n idBranch: 0,\n owner: null,\n sharing: null,\n path: 'in.c-main',\n tables: 'https://connection.keboola.com/v2/storage/buckets/in.c-main/tables',\n updated: '2024-03-10T08:30:00+0100',\n};\n\n// A freshly created table with no imports yet (non-typed, non-alias variant).\nconst freshTable = {\n id: 'in.c-main.users',\n name: 'users',\n displayName: 'Users',\n primaryKey: ['id'],\n metadata: [],\n columns: ['id', 'email', 'name', 'created_at'],\n columnMetadata: {},\n attributes: [],\n bucket,\n isTyped: false as const,\n isAlias: false as const,\n} satisfies TableDetail;\n\n// A recently updated table with a moderate size (non-typed, non-alias variant).\nconst recentlyUpdatedTable = {\n id: 'in.c-main.orders',\n name: 'orders',\n displayName: 'Orders',\n primaryKey: ['order_id'],\n metadata: [\n {\n id: 'mt1',\n key: 'KBC.createdBy.component.id',\n value: 'keboola.python-transformation',\n provider: 'keboola',\n timestamp: '2024-06-01T09:00:00+0200',\n },\n ],\n columns: ['order_id', 'user_id', 'total', 'status', 'created_at', 'updated_at'],\n columnMetadata: {\n order_id: [\n {\n id: 'm1',\n key: 'KBC.datatype.type',\n value: 'INTEGER',\n provider: 'keboola',\n timestamp: '2024-06-01T09:00:00+0200',\n },\n ],\n },\n attributes: [],\n bucket,\n isTyped: false as const,\n isAlias: false as const,\n} satisfies TableDetail;\n\n// A large table with many rows representing high-volume data (non-typed, non-alias variant).\nconst largeTable = {\n id: 'in.c-main.events',\n name: 'events',\n displayName: 'Events',\n primaryKey: [],\n metadata: [],\n columns: ['event_id', 'user_id', 'event_type', 'properties', 'occurred_at'],\n columnMetadata: {},\n attributes: [],\n bucket,\n isTyped: false as const,\n isAlias: false as const,\n} satisfies TableDetail;\n\n/**\n * Returns a single realistic typed TableDetail (fresh, no imports yet).\n *\n * The explicit return type ensures any divergence from the OpenAPI-derived\n * `TableDetail` in `@keboola/api-client` surfaces as a TypeScript error.\n */\nexport const getTable = (): TableDetail => freshTable;\n\n/**\n * Returns three TableDetail objects representing different lifecycle states:\n * 1. Fresh — just created, no data imported.\n * 2. Recently updated — moderate size, recent import.\n * 3. Large — high row count, large byte size.\n */\nexport const listTables = (): TableDetail[] => [freshTable, recentlyUpdatedTable, largeTable];\n\n/**\n * Named fixtures for targeted access in tests.\n */\nexport const tableFixtures = {\n fresh: freshTable,\n recentlyUpdated: recentlyUpdatedTable,\n large: largeTable,\n} satisfies Record<'fresh' | 'recentlyUpdated' | 'large', TableDetail>;\n\nexport type { Table, TableDetail };\n","import { appFixtures, getApp, listApps } from './clients/apps/apps';\nimport { deploymentFixtures, getDeployment, listDeployments } from './clients/apps/deployments';\nimport { getAppRun, listAppRuns, runFixtures } from './clients/apps/runs';\nimport { getTable, listTables, tableFixtures } from './clients/storage/tables';\n\nexport const fixtures = {\n storage: {\n tables: {\n getTable,\n listTables,\n fixtures: tableFixtures,\n },\n },\n apps: {\n apps: {\n getApp,\n listApps,\n fixtures: appFixtures,\n },\n deployments: {\n getDeployment,\n listDeployments,\n fixtures: deploymentFixtures,\n },\n runs: {\n getAppRun,\n listAppRuns,\n fixtures: runFixtures,\n },\n },\n};\n"]}