@keboola/api-fixtures 20.0.0 → 26.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/dist/index.js CHANGED
@@ -1,106 +1,818 @@
1
- // src/clients/storage/tables.ts
2
- var bucket = {
3
- id: "in.c-main",
4
- name: "c-main",
5
- displayName: "Main",
6
- stage: "in",
7
- description: "Main input bucket",
8
- created: "2024-01-15T10:00:00+0100",
9
- lastChangeDate: "2024-03-10T08:30:00+0100",
10
- isMaintenance: false,
11
- isReadOnly: false,
12
- isSnowflakeSharedDatabase: false,
13
- hasExternalSchema: false,
14
- rowsCount: 15e4,
15
- dataSizeBytes: 52428800,
16
- uri: "https://connection.keboola.com/v2/storage/buckets/in.c-main",
17
- backend: "snowflake",
18
- backendPath: [],
19
- databaseName: null,
20
- color: null,
21
- idBranch: 0,
22
- owner: null,
23
- sharing: null,
24
- path: "in.c-main",
25
- tables: "https://connection.keboola.com/v2/storage/buckets/in.c-main/tables",
26
- updated: "2024-03-10T08:30:00+0100"
27
- };
28
- var freshTable = {
29
- id: "in.c-main.users",
30
- name: "users",
31
- displayName: "Users",
32
- primaryKey: ["id"],
33
- metadata: [],
34
- columns: ["id", "email", "name", "created_at"],
35
- columnMetadata: {},
36
- attributes: [],
37
- bucket,
38
- isTyped: false,
39
- isAlias: false
40
- };
41
- var recentlyUpdatedTable = {
42
- id: "in.c-main.orders",
43
- name: "orders",
44
- displayName: "Orders",
45
- primaryKey: ["order_id"],
46
- metadata: [
47
- {
48
- id: "mt1",
49
- key: "KBC.createdBy.component.id",
50
- value: "keboola.python-transformation",
51
- provider: "keboola",
52
- timestamp: "2024-06-01T09:00:00+0200"
53
- }
54
- ],
55
- columns: ["order_id", "user_id", "total", "status", "created_at", "updated_at"],
56
- columnMetadata: {
57
- order_id: [
58
- {
59
- id: "m1",
60
- key: "KBC.datatype.type",
61
- value: "INTEGER",
62
- provider: "keboola",
63
- timestamp: "2024-06-01T09:00:00+0200"
64
- }
65
- ]
66
- },
67
- attributes: [],
68
- bucket,
69
- isTyped: false,
70
- isAlias: false
71
- };
72
- var largeTable = {
73
- id: "in.c-main.events",
74
- name: "events",
75
- displayName: "Events",
76
- primaryKey: [],
77
- metadata: [],
78
- columns: ["event_id", "user_id", "event_type", "properties", "occurred_at"],
79
- columnMetadata: {},
80
- attributes: [],
81
- bucket,
82
- isTyped: false,
83
- isAlias: false
84
- };
85
- var getTable = () => freshTable;
86
- var listTables = () => [freshTable, recentlyUpdatedTable, largeTable];
87
- var tableFixtures = {
88
- fresh: freshTable,
89
- recentlyUpdated: recentlyUpdatedTable,
90
- large: largeTable
1
+ //#region src/clients/apps/deployments.ts
2
+ /**
3
+ * Deployment ids are the deterministic Kubernetes CR name — `app-{appId}-dpl-{hash}` —
4
+ * so they are reproduced in that shape rather than as opaque strings.
5
+ */
6
+ const APP_ID = "374811";
7
+ const deploymentId = (hash) => `app-${APP_ID}-dpl-${hash}`;
8
+ const archivedDeployment = {
9
+ id: deploymentId("350e2cf5287c5665"),
10
+ number: 1,
11
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
12
+ configVersion: "14",
13
+ gitCommitSha: null,
14
+ size: "tiny",
15
+ buildState: "PREBUILT",
16
+ runState: "STOPPED",
17
+ archived: true,
18
+ archivedAt: "2026-08-15T11:03:02+00:00",
19
+ createdAt: "2026-08-10T09:12:44+00:00"
91
20
  };
92
-
93
- // src/fixtures.ts
94
- var fixtures = {
95
- storage: {
96
- tables: {
97
- getTable,
98
- listTables,
99
- fixtures: tableFixtures
100
- }
101
- }
21
+ const liveDeployment = {
22
+ id: deploymentId("7a4c1b9e0d3f2a81"),
23
+ number: 2,
24
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
25
+ configVersion: "16",
26
+ gitCommitSha: null,
27
+ size: "small",
28
+ buildState: "PREBUILT",
29
+ runState: "RUNNING",
30
+ archived: false,
31
+ archivedAt: null,
32
+ createdAt: "2026-08-15T11:02:58+00:00"
33
+ };
34
+ const stagedDeployment = {
35
+ id: deploymentId("c5e83f17b204de96"),
36
+ number: 3,
37
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
38
+ configVersion: "18",
39
+ gitCommitSha: null,
40
+ size: "small",
41
+ buildState: "PREBUILT",
42
+ runState: "NEVER_RUN",
43
+ archived: false,
44
+ archivedAt: null,
45
+ createdAt: "2026-08-17T08:41:19+00:00"
46
+ };
47
+ const buildFailedDeployment = {
48
+ id: deploymentId("e91d47a8c6b02f35"),
49
+ number: 4,
50
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
51
+ configVersion: "19",
52
+ gitCommitSha: null,
53
+ size: "small",
54
+ buildState: "FAILED",
55
+ runState: "NEVER_RUN",
56
+ archived: false,
57
+ archivedAt: null,
58
+ createdAt: "2026-08-17T09:05:33+00:00"
59
+ };
60
+ const runFailedDeployment = {
61
+ id: deploymentId("2b6f0a94e7d51c83"),
62
+ number: 5,
63
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
64
+ configVersion: "20",
65
+ gitCommitSha: null,
66
+ size: "small",
67
+ buildState: "PREBUILT",
68
+ runState: "FAILED",
69
+ archived: false,
70
+ archivedAt: null,
71
+ createdAt: "2026-08-17T09:31:07+00:00"
72
+ };
73
+ const deploymentFixtures = {
74
+ archived: archivedDeployment,
75
+ live: liveDeployment,
76
+ staged: stagedDeployment,
77
+ buildFailed: buildFailedDeployment,
78
+ runFailed: runFailedDeployment
79
+ };
80
+ const getDeployment = () => liveDeployment;
81
+ /**
82
+ * One continuous history: #1 retired, #2 serving, #3 staged, #4 failed to build, #5 built but its
83
+ * run failed.
84
+ *
85
+ * All five, because `runFixtures.failed` names #5 as its deployment — a list that left the failed
86
+ * ones out could not be joined to the runs, which is the join a timeline is built from.
87
+ *
88
+ * Returned in ascending `number` order. The endpoint does not specify an order, so consumers must
89
+ * sort for themselves — this order is a fixture convention, not a contract to rely on, and it is
90
+ * ascending on purpose: a consumer that assumes newest-first gets the wrong answer here rather
91
+ * than in production.
92
+ */
93
+ const listDeployments = () => [
94
+ archivedDeployment,
95
+ liveDeployment,
96
+ stagedDeployment,
97
+ buildFailedDeployment,
98
+ runFailedDeployment
99
+ ];
100
+ //#endregion
101
+ //#region src/clients/apps/apps.ts
102
+ const APP_URL = "https://hello-dashboard-374811.hub.canary-orion.keboola.dev";
103
+ const base$1 = {
104
+ id: APP_ID,
105
+ projectId: "14",
106
+ componentId: "keboola.data-apps",
107
+ branchId: "6",
108
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
109
+ type: "streamlit",
110
+ mode: "prod",
111
+ url: APP_URL
112
+ };
113
+ const production = (deployment) => ({
114
+ desiredNumber: deployment.number,
115
+ desiredId: deployment.id,
116
+ actualNumber: deployment.number,
117
+ actualId: deployment.id
118
+ });
119
+ const neverDeployedApp = {
120
+ ...base$1,
121
+ configVersion: "1",
122
+ production: {
123
+ desiredNumber: null,
124
+ desiredId: null,
125
+ actualNumber: null,
126
+ actualId: null
127
+ },
128
+ undeployedChanges: false,
129
+ state: "NOT_DEPLOYED"
130
+ };
131
+ /**
132
+ * Transcribed verbatim from canary on 17 Aug 2026 (AJDA-3140, probe P1): an app created and
133
+ * started through `/v1`, serving real traffic (HTTP 200, 8340 B) at the moment this was read,
134
+ * which `/v2` nonetheless reports as `NOT_DEPLOYED` with an empty `production` because it was
135
+ * never adopted into the deployments model.
136
+ *
137
+ * The Builder must never read "is this app serving" off `state` alone — here that answer is
138
+ * wrong in the most damaging direction.
139
+ */
140
+ const legacyV1ServingApp = {
141
+ id: "374811",
142
+ projectId: "14",
143
+ componentId: "keboola.data-apps",
144
+ branchId: "6",
145
+ configId: "01kz9kny4n49x3xk0e4k8ynpmq",
146
+ configVersion: "2",
147
+ type: "streamlit",
148
+ mode: "dev",
149
+ url: APP_URL,
150
+ production: {
151
+ desiredNumber: null,
152
+ desiredId: null,
153
+ actualNumber: null,
154
+ actualId: null
155
+ },
156
+ undeployedChanges: false,
157
+ state: "NOT_DEPLOYED"
158
+ };
159
+ const runningApp = {
160
+ ...base$1,
161
+ configVersion: deploymentFixtures.live.configVersion,
162
+ production: production(deploymentFixtures.live),
163
+ undeployedChanges: false,
164
+ state: "RUNNING"
165
+ };
166
+ const appWithUndeployedChanges = {
167
+ ...base$1,
168
+ configVersion: deploymentFixtures.staged.configVersion,
169
+ production: production(deploymentFixtures.live),
170
+ undeployedChanges: true,
171
+ state: "RUNNING"
172
+ };
173
+ const appFixtures = {
174
+ neverDeployed: neverDeployedApp,
175
+ legacyV1Serving: legacyV1ServingApp,
176
+ running: runningApp,
177
+ undeployedChanges: appWithUndeployedChanges,
178
+ promoting: {
179
+ ...base$1,
180
+ configVersion: deploymentFixtures.staged.configVersion,
181
+ production: {
182
+ desiredNumber: deploymentFixtures.staged.number,
183
+ desiredId: deploymentFixtures.staged.id,
184
+ actualNumber: deploymentFixtures.live.number,
185
+ actualId: deploymentFixtures.live.id
186
+ },
187
+ undeployedChanges: true,
188
+ state: "RUNNING"
189
+ },
190
+ sleeping: {
191
+ ...base$1,
192
+ configVersion: deploymentFixtures.live.configVersion,
193
+ production: production(deploymentFixtures.live),
194
+ undeployedChanges: false,
195
+ state: "SLEEPING"
196
+ },
197
+ suspended: {
198
+ ...base$1,
199
+ configVersion: deploymentFixtures.live.configVersion,
200
+ production: production(deploymentFixtures.live),
201
+ undeployedChanges: false,
202
+ state: "SUSPENDED"
203
+ }
204
+ };
205
+ const getApp = () => runningApp;
206
+ /**
207
+ * The named fixtures above are all the *same* app in different states, which is what a detail
208
+ * page shows. A listing shows different apps, so each entry past the first is re-addressed —
209
+ * including the deployment ids inside `production`, which embed the app id.
210
+ */
211
+ const readdress = (app, id) => ({
212
+ ...app,
213
+ id,
214
+ url: `https://data-app-${id}.hub.canary-orion.keboola.dev`,
215
+ production: {
216
+ ...app.production,
217
+ desiredId: app.production.desiredId?.replace("374811", id) ?? null,
218
+ actualId: app.production.actualId?.replace("374811", id) ?? null
219
+ }
220
+ });
221
+ const listApps = () => [
222
+ runningApp,
223
+ readdress(appWithUndeployedChanges, "374812"),
224
+ readdress(neverDeployedApp, "374813")
225
+ ];
226
+ //#endregion
227
+ //#region src/clients/apps/runs.ts
228
+ const base = {
229
+ appId: APP_ID,
230
+ runtimeSize: "small",
231
+ runtimeBackendType: "streamlit",
232
+ imageVersion: "1.14.2",
233
+ mode: "prod"
234
+ };
235
+ const runningRun = {
236
+ ...base,
237
+ id: "4f2d8c1a-0b76-4e35-9a12-5c8e7d3b0f41",
238
+ deploymentId: deploymentFixtures.live.id,
239
+ configVersion: deploymentFixtures.live.configVersion,
240
+ state: "running",
241
+ createdAt: "2026-08-15T11:02:58+00:00",
242
+ startedAt: "2026-08-15T11:03:41+00:00",
243
+ stoppedAt: null,
244
+ startupLogs: null,
245
+ failureReason: null
246
+ };
247
+ const finishedRun = {
248
+ ...base,
249
+ id: "9c0a7e42-31bd-4f88-b6d5-2ea41f907c3b",
250
+ deploymentId: deploymentFixtures.archived.id,
251
+ configVersion: deploymentFixtures.archived.configVersion,
252
+ state: "finished",
253
+ createdAt: "2026-08-10T09:12:44+00:00",
254
+ startedAt: "2026-08-10T09:13:29+00:00",
255
+ stoppedAt: "2026-08-15T11:03:02+00:00",
256
+ startupLogs: null,
257
+ failureReason: null
258
+ };
259
+ /**
260
+ * A classified failure transcribed from canary (AJDA-3140, probe P1). `startedAt` is `null`
261
+ * even though a cause was attributed — the container executed but its startup probe never
262
+ * passed, so a classified failure says nothing about how far the run got.
263
+ */
264
+ const failedRun = {
265
+ ...base,
266
+ id: "ba53f9d0-7c41-4a2e-8f16-d0b9e254a7c6",
267
+ deploymentId: deploymentFixtures.runFailed.id,
268
+ configVersion: deploymentFixtures.runFailed.configVersion,
269
+ state: "failed",
270
+ createdAt: "2026-08-17T09:31:07+00:00",
271
+ startedAt: null,
272
+ stoppedAt: "2026-08-17T09:33:52+00:00",
273
+ startupLogs: "[INFO] Starting app\n[ERROR] App must have keboola-config/nginx/ directory. Missing: /app/keboola-config/nginx\n",
274
+ failureReason: {
275
+ reason: "StartupProbeFailed",
276
+ message: "App must have keboola-config/nginx/ directory. Missing: /app/keboola-config/nginx"
277
+ }
278
+ };
279
+ /**
280
+ * A run that belongs to the app itself rather than to a deployment — what every run of a
281
+ * `/v1`-created app looks like. `deploymentId: null` is permanent for these, not drift.
282
+ */
283
+ const legacyRun = {
284
+ ...base,
285
+ id: "1d7b4e05-8a92-4c63-b0f7-3e6a5c8192d4",
286
+ deploymentId: null,
287
+ configVersion: "2",
288
+ state: "running",
289
+ createdAt: "2026-08-17T10:02:11+00:00",
290
+ startedAt: "2026-08-17T10:02:51+00:00",
291
+ stoppedAt: null,
292
+ startupLogs: null,
293
+ failureReason: null
294
+ };
295
+ const runFixtures = {
296
+ running: runningRun,
297
+ finished: finishedRun,
298
+ failed: failedRun,
299
+ legacy: legacyRun
300
+ };
301
+ const getAppRun = () => runningRun;
302
+ /**
303
+ * Every run this app has, newest first — the order the endpoint documents, so a consumer that
304
+ * relies on it (`[latest] = runs`) is exercised against data that keeps the promise rather than
305
+ * data that happens to contradict it.
306
+ */
307
+ const listAppRuns = () => [
308
+ legacyRun,
309
+ failedRun,
310
+ runningRun,
311
+ finishedRun
312
+ ];
313
+ //#endregion
314
+ //#region src/clients/developerPortal/apps.ts
315
+ const keboolaVendor = {
316
+ id: "keboola",
317
+ name: "Keboola",
318
+ email: "support@keboola.com",
319
+ address: "Prague, Czech Republic",
320
+ type: "keboola",
321
+ projectUrl: null,
322
+ isTrusted: 1
323
+ };
324
+ const thirdPartyVendor = {
325
+ id: "acme",
326
+ name: "Acme Co.",
327
+ email: "dev@acme.example",
328
+ address: "Springfield",
329
+ projectUrl: "https://connection.keboola.com/admin/projects/1234",
330
+ type: "other",
331
+ isTrusted: 0
332
+ };
333
+ /** The same vendor as `GET /vendors/{vendor}` returns it — `isTrusted` converted to a boolean. */
334
+ const vendorDetail = {
335
+ ...thirdPartyVendor,
336
+ isTrusted: false
337
+ };
338
+ const pendingVendor = {
339
+ id: "_v1699999999999",
340
+ name: "Pending Startup",
341
+ email: "hello@pending.example",
342
+ address: "Berlin",
343
+ type: "other",
344
+ projectUrl: null,
345
+ isApproved: false,
346
+ isPublic: false,
347
+ isTrusted: false
348
+ };
349
+ const keboolaAdminVendor = {
350
+ ...keboolaVendor,
351
+ isApproved: true,
352
+ isPublic: true,
353
+ isTrusted: true
354
+ };
355
+ const thirdPartyAdminVendor = {
356
+ ...thirdPartyVendor,
357
+ isApproved: true,
358
+ isPublic: true,
359
+ isTrusted: false
360
+ };
361
+ const appVendor = (vendor) => ({
362
+ id: vendor.id,
363
+ name: vendor.name,
364
+ address: vendor.address,
365
+ email: vendor.email,
366
+ type: vendor.type
367
+ });
368
+ /** A published, fully-populated extractor — the shape that passes `hasAllFieldsForPublishing`. */
369
+ const publishedExtractor = {
370
+ id: "keboola.ex-db-snowflake",
371
+ vendor: appVendor(keboolaVendor),
372
+ name: "Snowflake",
373
+ type: "extractor",
374
+ shortDescription: "Extract data from Snowflake",
375
+ longDescription: "## Snowflake extractor\n\nExtracts tables from a Snowflake database.",
376
+ licenseUrl: "https://github.com/keboola/ex-db-snowflake/blob/master/LICENSE.md",
377
+ documentationUrl: "https://help.keboola.com/components/extractors/database/snowflake/",
378
+ sourceCodeUrl: "https://github.com/keboola/ex-db-snowflake",
379
+ categories: ["Database"],
380
+ complexity: "easy",
381
+ uiOptions: ["genericDockerUI"],
382
+ defaultBucket: true,
383
+ defaultBucketStage: "in",
384
+ stagingStorageInput: "local",
385
+ stagingStorageOutput: "local",
386
+ logger: "standard",
387
+ isPublic: true,
388
+ isDeprecated: false,
389
+ fees: false,
390
+ repository: {
391
+ type: "ecr",
392
+ uri: "keboola/ex-db-snowflake",
393
+ tag: "1.9.0"
394
+ },
395
+ icon: {
396
+ "64": "https://ui.keboola-assets.com/developer-portal/icons/keboola.ex-db-snowflake/64/1699999999999.png",
397
+ "128": "https://ui.keboola-assets.com/developer-portal/icons/keboola.ex-db-snowflake/128/1699999999999.png"
398
+ },
399
+ version: 12,
400
+ createdBy: "support@keboola.com",
401
+ updatedOn: "2024-06-01T09:00:00+0200",
402
+ uri: "docker/keboola.ex-db-snowflake",
403
+ isPublished: true,
404
+ publishedVersion: 12,
405
+ publishingStatus: "public"
406
+ };
407
+ /** A private third-party app with a pending publishing request. */
408
+ const requestedApp = {
409
+ id: "acme.wr-widgets",
410
+ vendor: appVendor(thirdPartyVendor),
411
+ name: "Widget Writer",
412
+ type: "writer",
413
+ shortDescription: "Write data to Widgets",
414
+ longDescription: "Pushes tables into the Widgets API.",
415
+ licenseUrl: "https://acme.example/license",
416
+ documentationUrl: "https://acme.example/docs",
417
+ uiOptions: ["genericDockerUI"],
418
+ repository: {
419
+ type: "quay",
420
+ uri: "acme/wr-widgets",
421
+ tag: "0.3.1"
422
+ },
423
+ icon: {
424
+ "64": "https://ui.keboola-assets.com/developer-portal/icons/acme.wr-widgets/64/1699999999998.png",
425
+ "128": "https://ui.keboola-assets.com/developer-portal/icons/acme.wr-widgets/128/1699999999998.png"
426
+ },
427
+ isPublic: false,
428
+ isDeprecated: false,
429
+ version: 3,
430
+ createdBy: "dev@acme.example",
431
+ updatedOn: "2024-05-20T14:12:00+0200",
432
+ uri: "docker/acme.wr-widgets",
433
+ isPublished: false,
434
+ publishingStatus: "requested",
435
+ publishingRequest: {
436
+ createdOn: "2024-05-20T14:12:00+0200",
437
+ rejectionReason: null
438
+ }
439
+ };
440
+ /** A rejected app — carries the reason the vendor sees on its detail page. */
441
+ const rejectedApp = {
442
+ id: "acme.app-analyzer",
443
+ vendor: appVendor(thirdPartyVendor),
444
+ name: "Analyzer",
445
+ type: "application",
446
+ shortDescription: "Analyze things",
447
+ isPublic: false,
448
+ isDeprecated: false,
449
+ version: 1,
450
+ createdBy: "dev@acme.example",
451
+ uri: "docker/acme.app-analyzer",
452
+ isPublished: false,
453
+ publishingStatus: "rejected",
454
+ publishingRequest: {
455
+ createdOn: "2024-04-02T11:00:00+0200",
456
+ rejectionReason: "Documentation URL is missing and the icon is not 256×256."
457
+ }
458
+ };
459
+ /** A deprecated app with an expiry date and a suggested replacement. */
460
+ const deprecatedApp = {
461
+ id: "keboola.ex-legacy",
462
+ vendor: appVendor(keboolaVendor),
463
+ name: "Legacy Extractor",
464
+ type: "extractor",
465
+ shortDescription: "Superseded",
466
+ isPublic: true,
467
+ isDeprecated: true,
468
+ expiredOn: "2025-01-01",
469
+ replacementApp: "keboola.ex-db-snowflake",
470
+ version: 40,
471
+ uri: "docker/keboola.ex-legacy",
472
+ isPublished: true,
473
+ publishedVersion: 38,
474
+ publishingStatus: "public"
475
+ };
476
+ /**
477
+ * A `data-app`, the type whose edit form hides ~14 fields. Deliberately minimal: a fixture carrying
478
+ * `configurationSchema` or `actions` here would misrepresent what the form can produce.
479
+ */
480
+ const dataApp = {
481
+ id: "acme.data-app-dashboard",
482
+ vendor: appVendor(thirdPartyVendor),
483
+ name: "Dashboard",
484
+ type: "data-app",
485
+ shortDescription: "A Streamlit dashboard",
486
+ isPublic: false,
487
+ isDeprecated: false,
488
+ version: 2,
489
+ uri: "docker/acme.data-app-dashboard",
490
+ isPublished: false,
491
+ publishingStatus: "private"
492
+ };
493
+ /** A `code-pattern`, whose `configurationSchema.supported_components` must be a non-empty array. */
494
+ const codePatternApp = {
495
+ id: "acme.code-pattern-etl",
496
+ vendor: appVendor(thirdPartyVendor),
497
+ name: "ETL Pattern",
498
+ type: "code-pattern",
499
+ shortDescription: "Generates ETL code",
500
+ actions: ["generate"],
501
+ configurationSchema: { supported_components: ["keboola.snowflake-transformation"] },
502
+ isPublic: false,
503
+ version: 1,
504
+ uri: "docker/acme.code-pattern-etl",
505
+ isPublished: false,
506
+ publishingStatus: "private"
507
+ };
508
+ /**
509
+ * An app typed `other`. The public catalog excludes it entirely, so it exists to prove that
510
+ * exclusion rather than to be rendered.
511
+ */
512
+ const otherTypeApp = {
513
+ id: "acme.misc-thing",
514
+ vendor: appVendor(thirdPartyVendor),
515
+ name: "Misc Thing",
516
+ type: "other",
517
+ isPublic: true,
518
+ version: 1,
519
+ uri: "docker/acme.misc-thing",
520
+ isPublished: true,
521
+ publishedVersion: 1,
522
+ publishingStatus: "public"
523
+ };
524
+ const humanUser = {
525
+ username: "dev@acme.example",
526
+ name: "Dev Eloper",
527
+ vendors: ["acme"],
528
+ createdOn: "2024-01-10T08:00:00+0100"
529
+ };
530
+ /** A recently added member, for a test that orders the list by `createdOn`. */
531
+ const newestUser = {
532
+ username: "new@acme.example",
533
+ name: "New Hire",
534
+ vendors: ["acme"],
535
+ createdOn: "2024-06-25T08:00:00+0200"
536
+ };
537
+ /** A member of no vendor — reachable only through the admin list. */
538
+ const vendorlessUser = {
539
+ username: "gone@acme.example",
540
+ name: "Alan Gone",
541
+ vendors: [],
542
+ createdOn: "2023-02-01T08:00:00+0100"
543
+ };
544
+ /** A Keboola staff member — eligible for "make admin" because they belong to the `keboola` vendor. */
545
+ const keboolaStaffUser = {
546
+ username: "staff@keboola.com",
547
+ name: "Kai Staff",
548
+ vendors: ["keboola"],
549
+ createdOn: "2023-09-14T08:00:00+0200"
550
+ };
551
+ /** A freshly created service account, including the one-time `password`. */
552
+ const newServiceAccount = {
553
+ username: "acme+ci",
554
+ description: "CI deploy pipeline",
555
+ createdOn: "2024-07-01T10:00:00+0200",
556
+ password: "one-time-secret-shown-once"
557
+ };
558
+ /** The same account as later listed — note there is no `password`; it is unreadable after creation. */
559
+ const existingServiceAccount = {
560
+ username: "acme+release",
561
+ description: "Release automation",
562
+ createdOn: "2024-03-11T10:00:00+0100"
563
+ };
564
+ const appChange = {
565
+ appId: "acme.wr-widgets",
566
+ createdOn: "2024-05-20T14:12:00+0200",
567
+ createdBy: "dev@acme.example",
568
+ changes: [{
569
+ attribute: "shortDescription",
570
+ oldValue: "Writes widgets",
571
+ newValue: "Write data to Widgets"
572
+ }, {
573
+ attribute: "repository",
574
+ oldValue: {
575
+ type: "quay",
576
+ uri: "acme/wr-widgets",
577
+ tag: "0.3.0"
578
+ },
579
+ newValue: {
580
+ type: "quay",
581
+ uri: "acme/wr-widgets",
582
+ tag: "0.3.1"
583
+ }
584
+ }]
585
+ };
586
+ /** The public catalog list: published, non-`other` apps only. */
587
+ const listPublishedApps = () => [publishedExtractor, deprecatedApp];
588
+ /** A vendor's own apps, across every publishing state the table renders. */
589
+ const listVendorApps = () => [
590
+ requestedApp,
591
+ rejectedApp,
592
+ dataApp,
593
+ codePatternApp
594
+ ];
595
+ /** The admin list — every vendor, plus the `other`-typed app the public catalog drops. */
596
+ const listAllApps = () => [
597
+ publishedExtractor,
598
+ requestedApp,
599
+ rejectedApp,
600
+ deprecatedApp,
601
+ dataApp,
602
+ codePatternApp,
603
+ otherTypeApp
604
+ ];
605
+ /** `GET /vendors` — approved and public only, so the pending vendor cannot appear here. */
606
+ const listVendors = () => [keboolaVendor, thirdPartyVendor];
607
+ /** `GET /vendors/{vendor}` — the converted shape. */
608
+ const getVendor = () => vendorDetail;
609
+ /** `GET /admin/vendors` — every vendor, and the only response carrying the approval flags. */
610
+ const listAllVendors = () => [
611
+ keboolaAdminVendor,
612
+ thirdPartyAdminVendor,
613
+ pendingVendor
614
+ ];
615
+ const listUsers = () => [
616
+ humanUser,
617
+ newestUser,
618
+ vendorlessUser,
619
+ keboolaStaffUser
620
+ ];
621
+ const listServiceAccounts = () => [existingServiceAccount];
622
+ const listAppChanges = () => [appChange];
623
+ /** Named fixtures, for a test that needs one specific state. */
624
+ const developerPortalFixtures = {
625
+ apps: {
626
+ published: publishedExtractor,
627
+ requested: requestedApp,
628
+ rejected: rejectedApp,
629
+ deprecated: deprecatedApp,
630
+ dataApp,
631
+ codePattern: codePatternApp,
632
+ otherType: otherTypeApp
633
+ },
634
+ vendors: {
635
+ keboola: keboolaVendor,
636
+ thirdParty: thirdPartyVendor,
637
+ detail: vendorDetail,
638
+ pending: pendingVendor,
639
+ keboolaAdmin: keboolaAdminVendor,
640
+ thirdPartyAdmin: thirdPartyAdminVendor
641
+ },
642
+ users: {
643
+ human: humanUser,
644
+ newest: newestUser,
645
+ vendorless: vendorlessUser,
646
+ keboolaStaff: keboolaStaffUser
647
+ },
648
+ serviceAccounts: {
649
+ created: newServiceAccount,
650
+ existing: existingServiceAccount
651
+ },
652
+ changes: { single: appChange }
653
+ };
654
+ //#endregion
655
+ //#region src/clients/storage/tables.ts
656
+ const bucket = {
657
+ id: "in.c-main",
658
+ name: "c-main",
659
+ displayName: "Main",
660
+ stage: "in",
661
+ description: "Main input bucket",
662
+ created: "2024-01-15T10:00:00+0100",
663
+ lastChangeDate: "2024-03-10T08:30:00+0100",
664
+ isMaintenance: false,
665
+ isReadOnly: false,
666
+ isSnowflakeSharedDatabase: false,
667
+ hasExternalSchema: false,
668
+ rowsCount: 15e4,
669
+ dataSizeBytes: 52428800,
670
+ uri: "https://connection.keboola.com/v2/storage/buckets/in.c-main",
671
+ backend: "snowflake",
672
+ backendPath: [],
673
+ databaseName: null,
674
+ color: null,
675
+ idBranch: 0,
676
+ owner: null,
677
+ sharing: null,
678
+ path: "in.c-main",
679
+ tables: "https://connection.keboola.com/v2/storage/buckets/in.c-main/tables",
680
+ updated: "2024-03-10T08:30:00+0100"
681
+ };
682
+ const freshTable = {
683
+ id: "in.c-main.users",
684
+ name: "users",
685
+ displayName: "Users",
686
+ primaryKey: ["id"],
687
+ metadata: [],
688
+ columns: [
689
+ "id",
690
+ "email",
691
+ "name",
692
+ "created_at"
693
+ ],
694
+ columnMetadata: {},
695
+ attributes: [],
696
+ bucket,
697
+ isTyped: false,
698
+ isAlias: false
699
+ };
700
+ const recentlyUpdatedTable = {
701
+ id: "in.c-main.orders",
702
+ name: "orders",
703
+ displayName: "Orders",
704
+ primaryKey: ["order_id"],
705
+ metadata: [{
706
+ id: "mt1",
707
+ key: "KBC.createdBy.component.id",
708
+ value: "keboola.python-transformation",
709
+ provider: "keboola",
710
+ timestamp: "2024-06-01T09:00:00+0200"
711
+ }],
712
+ columns: [
713
+ "order_id",
714
+ "user_id",
715
+ "total",
716
+ "status",
717
+ "created_at",
718
+ "updated_at"
719
+ ],
720
+ columnMetadata: { order_id: [{
721
+ id: "m1",
722
+ key: "KBC.datatype.type",
723
+ value: "INTEGER",
724
+ provider: "keboola",
725
+ timestamp: "2024-06-01T09:00:00+0200"
726
+ }] },
727
+ attributes: [],
728
+ bucket,
729
+ isTyped: false,
730
+ isAlias: false
731
+ };
732
+ const largeTable = {
733
+ id: "in.c-main.events",
734
+ name: "events",
735
+ displayName: "Events",
736
+ primaryKey: [],
737
+ metadata: [],
738
+ columns: [
739
+ "event_id",
740
+ "user_id",
741
+ "event_type",
742
+ "properties",
743
+ "occurred_at"
744
+ ],
745
+ columnMetadata: {},
746
+ attributes: [],
747
+ bucket,
748
+ isTyped: false,
749
+ isAlias: false
750
+ };
751
+ /**
752
+ * Returns a single realistic typed TableDetail (fresh, no imports yet).
753
+ *
754
+ * The explicit return type ensures any divergence from the OpenAPI-derived
755
+ * `TableDetail` in `@keboola/api-client` surfaces as a TypeScript error.
756
+ */
757
+ const getTable = () => freshTable;
758
+ /**
759
+ * Returns three TableDetail objects representing different lifecycle states:
760
+ * 1. Fresh — just created, no data imported.
761
+ * 2. Recently updated — moderate size, recent import.
762
+ * 3. Large — high row count, large byte size.
763
+ */
764
+ const listTables = () => [
765
+ freshTable,
766
+ recentlyUpdatedTable,
767
+ largeTable
768
+ ];
769
+ /**
770
+ * Named fixtures for targeted access in tests.
771
+ */
772
+ const tableFixtures = {
773
+ fresh: freshTable,
774
+ recentlyUpdated: recentlyUpdatedTable,
775
+ large: largeTable
776
+ };
777
+ //#endregion
778
+ //#region src/fixtures.ts
779
+ const fixtures = {
780
+ storage: { tables: {
781
+ getTable,
782
+ listTables,
783
+ fixtures: tableFixtures
784
+ } },
785
+ apps: {
786
+ apps: {
787
+ getApp,
788
+ listApps,
789
+ fixtures: appFixtures
790
+ },
791
+ deployments: {
792
+ getDeployment,
793
+ listDeployments,
794
+ fixtures: deploymentFixtures
795
+ },
796
+ runs: {
797
+ getAppRun,
798
+ listAppRuns,
799
+ fixtures: runFixtures
800
+ }
801
+ },
802
+ developerPortal: {
803
+ listPublishedApps,
804
+ listVendorApps,
805
+ listAllApps,
806
+ listAllVendors,
807
+ getVendor,
808
+ listVendors,
809
+ listUsers,
810
+ listServiceAccounts,
811
+ listAppChanges,
812
+ fixtures: developerPortalFixtures
813
+ }
102
814
  };
815
+ //#endregion
816
+ export { appFixtures, deploymentFixtures, developerPortalFixtures, fixtures, getApp, getAppRun, getDeployment, getTable, getVendor, listAllApps, listAllVendors, listAppChanges, listAppRuns, listApps, listDeployments, listPublishedApps, listServiceAccounts, listTables, listUsers, listVendorApps, listVendors, runFixtures, tableFixtures };
103
817
 
104
- export { fixtures, getTable, listTables, tableFixtures };
105
- //# sourceMappingURL=index.js.map
106
818
  //# sourceMappingURL=index.js.map