@metabase/client 0.0.0-stage → 0.1.1
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/CHANGELOG.md +28 -0
- package/LICENSE +661 -0
- package/README.md +490 -2
- package/dist/api-key-DJeN1-7G.d.ts +46 -0
- package/dist/auth/credential.d.ts +2 -0
- package/dist/auth/credential.js +61 -0
- package/dist/auth/oauth-login.d.ts +2 -0
- package/dist/auth/oauth-login.js +2 -0
- package/dist/auth/oauth-session.d.ts +2 -0
- package/dist/auth/oauth-session.js +31 -0
- package/dist/card-BxBzr5Uj.d.ts +1392 -0
- package/dist/card-DN0sLkCG.d.ts +33 -0
- package/dist/client-DdXLlH1B.d.ts +3380 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +99 -0
- package/dist/collection-DGnTvD6R.d.ts +294 -0
- package/dist/collection-fFahL-ub.d.ts +53 -0
- package/dist/content-translation-zfUkE_OG.d.ts +8 -0
- package/dist/credential-6aOEGqMH.d.ts +30 -0
- package/dist/cron-DThzerR6.d.ts +9 -0
- package/dist/csv-upload--K35QedP.d.ts +8 -0
- package/dist/dashboard-CM7RmNeE.d.ts +38 -0
- package/dist/dashboard-DtLXVgtf.d.ts +978 -0
- package/dist/data-action-CkXVrOUH.d.ts +97 -0
- package/dist/data-app-CqP5_fpB.d.ts +76 -0
- package/dist/database-B0JNZjDN.d.ts +27 -0
- package/dist/database-BxqDmfcj.d.ts +997 -0
- package/dist/dataset-BBNGPVec.d.ts +4144 -0
- package/dist/dataset-BUirJ1rO.d.ts +23 -0
- package/dist/dependency-CzpXmeu7.d.ts +299 -0
- package/dist/dependency-arB8Cr2H.d.ts +879 -0
- package/dist/document-tLd6pYWe.d.ts +115 -0
- package/dist/domain/api-key.d.ts +2 -0
- package/dist/domain/api-key.js +31 -0
- package/dist/domain/card.d.ts +2 -0
- package/dist/domain/card.js +140 -0
- package/dist/domain/collection.d.ts +2 -0
- package/dist/domain/collection.js +137 -0
- package/dist/domain/content-translation.d.ts +2 -0
- package/dist/domain/content-translation.js +5 -0
- package/dist/domain/cron.d.ts +2 -0
- package/dist/domain/cron.js +5 -0
- package/dist/domain/dashboard.d.ts +2 -0
- package/dist/domain/dashboard.js +211 -0
- package/dist/domain/data-action.d.ts +2 -0
- package/dist/domain/data-action.js +91 -0
- package/dist/domain/data-app.d.ts +2 -0
- package/dist/domain/data-app.js +52 -0
- package/dist/domain/database.d.ts +2 -0
- package/dist/domain/database.js +56 -0
- package/dist/domain/dataset.d.ts +2 -0
- package/dist/domain/dataset.js +56 -0
- package/dist/domain/dependency.d.ts +2 -0
- package/dist/domain/dependency.js +168 -0
- package/dist/domain/document.d.ts +2 -0
- package/dist/domain/document.js +94 -0
- package/dist/domain/eid-translation.d.ts +2 -0
- package/dist/domain/eid-translation.js +36 -0
- package/dist/domain/embedding.d.ts +2 -0
- package/dist/domain/embedding.js +9 -0
- package/dist/domain/erd.d.ts +2 -0
- package/dist/domain/erd.js +45 -0
- package/dist/domain/field.d.ts +2 -0
- package/dist/domain/field.js +274 -0
- package/dist/domain/git-sync.d.ts +2 -0
- package/dist/domain/git-sync.js +147 -0
- package/dist/domain/glossary.d.ts +2 -0
- package/dist/domain/glossary.js +30 -0
- package/dist/domain/library.d.ts +2 -0
- package/dist/domain/library.js +89 -0
- package/dist/domain/measure.d.ts +2 -0
- package/dist/domain/measure.js +43 -0
- package/dist/domain/metric.d.ts +2 -0
- package/dist/domain/metric.js +139 -0
- package/dist/domain/moderation-review.d.ts +2 -0
- package/dist/domain/moderation-review.js +31 -0
- package/dist/domain/notification.d.ts +2 -0
- package/dist/domain/notification.js +143 -0
- package/dist/domain/parameter.d.ts +2 -0
- package/dist/domain/parameter.js +109 -0
- package/dist/domain/permission.d.ts +2 -0
- package/dist/domain/permission.js +36 -0
- package/dist/domain/pulse.d.ts +2 -0
- package/dist/domain/pulse.js +140 -0
- package/dist/domain/query.d.ts +2 -0
- package/dist/domain/query.js +13 -0
- package/dist/domain/replacement.d.ts +2 -0
- package/dist/domain/replacement.js +93 -0
- package/dist/domain/revision.d.ts +2 -0
- package/dist/domain/revision.js +90 -0
- package/dist/domain/search.d.ts +2 -0
- package/dist/domain/search.js +63 -0
- package/dist/domain/segment.d.ts +2 -0
- package/dist/domain/segment.js +46 -0
- package/dist/domain/session-properties.d.ts +2 -0
- package/dist/domain/session-properties.js +14 -0
- package/dist/domain/setting.d.ts +2 -0
- package/dist/domain/setting.js +22 -0
- package/dist/domain/setup.d.ts +2 -0
- package/dist/domain/setup.js +21 -0
- package/dist/domain/snippet.d.ts +2 -0
- package/dist/domain/snippet.js +38 -0
- package/dist/domain/table.d.ts +2 -0
- package/dist/domain/table.js +187 -0
- package/dist/domain/text.d.ts +5 -0
- package/dist/domain/text.js +6 -0
- package/dist/domain/timeline.d.ts +2 -0
- package/dist/domain/timeline.js +97 -0
- package/dist/domain/transform-dag-run.d.ts +2 -0
- package/dist/domain/transform-dag-run.js +19 -0
- package/dist/domain/transform-inspector.d.ts +2 -0
- package/dist/domain/transform-inspector.js +142 -0
- package/dist/domain/transform-job.d.ts +2 -0
- package/dist/domain/transform-job.js +115 -0
- package/dist/domain/transform-python.d.ts +2 -0
- package/dist/domain/transform-python.js +51 -0
- package/dist/domain/transform-tag.d.ts +2 -0
- package/dist/domain/transform-tag.js +17 -0
- package/dist/domain/transform-test.d.ts +2 -0
- package/dist/domain/transform-test.js +176 -0
- package/dist/domain/transform.d.ts +2 -0
- package/dist/domain/transform.js +304 -0
- package/dist/domain/upload.d.ts +2 -0
- package/dist/domain/upload.js +13 -0
- package/dist/domain/user.d.ts +2 -0
- package/dist/domain/user.js +16 -0
- package/dist/eid-translation-CH6NPWd-.d.ts +143 -0
- package/dist/embedding-oU3gqfgX.d.ts +10 -0
- package/dist/erd-BdeFEeSy.d.ts +842 -0
- package/dist/erd-CbV7xvAc.d.ts +51 -0
- package/dist/errors-DdMlaXqq.js +330 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +189 -0
- package/dist/features-SMSfJhB6.d.ts +295 -0
- package/dist/field-D1Pfk-0S.d.ts +50 -0
- package/dist/field-p9Rme2zB.d.ts +2549 -0
- package/dist/git-sync-BTf1aYHr.d.ts +205 -0
- package/dist/git-sync-C99SVdJ9.d.ts +258 -0
- package/dist/glossary-CHK3elPj.d.ts +35 -0
- package/dist/glossary-DFvnz-E5.d.ts +15 -0
- package/dist/http/errors.d.ts +2 -0
- package/dist/http/errors.js +2 -0
- package/dist/http/oauth.d.ts +2 -0
- package/dist/http/oauth.js +201 -0
- package/dist/http/retry.d.ts +19 -0
- package/dist/http/retry.js +33 -0
- package/dist/http/transport.d.ts +2 -0
- package/dist/http/transport.js +2 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +64 -0
- package/dist/input-gate-registry-Dai7SfXb.js +14 -0
- package/dist/input-gates-DwKoTJVQ.d.ts +28 -0
- package/dist/json-BksZpXDC.d.ts +19 -0
- package/dist/json-pointer.d.ts +5 -0
- package/dist/json-pointer.js +10 -0
- package/dist/json.d.ts +2 -0
- package/dist/json.js +44 -0
- package/dist/known-range-DTOBgTEC.d.ts +7 -0
- package/dist/library-B9pEq7qP.d.ts +230 -0
- package/dist/list-BT_bBm9Z.d.ts +7 -0
- package/dist/list.d.ts +2 -0
- package/dist/list.js +1 -0
- package/dist/measure-CgH14YQZ.d.ts +44 -0
- package/dist/measure-lPz8qnwz.d.ts +108 -0
- package/dist/metric-DcYloqOQ.d.ts +2655 -0
- package/dist/moderation-review-B4RUTZ6_.d.ts +56 -0
- package/dist/network-error-5g4U1iul.js +62 -0
- package/dist/notification-Cp5GJErS.d.ts +22 -0
- package/dist/notification-D1MThyKE.d.ts +443 -0
- package/dist/oauth-C4ordeoJ.d.ts +59 -0
- package/dist/oauth-login-CJsT_3EE.d.ts +19 -0
- package/dist/oauth-login-D734Jvbq.js +179 -0
- package/dist/oauth-session-BlIlcd8Q.d.ts +6 -0
- package/dist/paginate-COuL0Gzl.d.ts +24 -0
- package/dist/paginate.d.ts +2 -0
- package/dist/paginate.js +49 -0
- package/dist/parameter-ak-J-IOj.d.ts +190 -0
- package/dist/permission-BnCQw5Kp.d.ts +149 -0
- package/dist/poll-CIwnee7h.d.ts +15 -0
- package/dist/poll.d.ts +2 -0
- package/dist/poll.js +47 -0
- package/dist/predicates.d.ts +10 -0
- package/dist/predicates.js +18 -0
- package/dist/pulse-0LG3K6qO.d.ts +598 -0
- package/dist/pulse-BzKmz3Yn.d.ts +18 -0
- package/dist/query-Xsin530u.d.ts +23 -0
- package/dist/refusal-B9aeHMc9.js +130 -0
- package/dist/replacement-BGyggp-G.d.ts +2467 -0
- package/dist/replacement-CVebCuNp.d.ts +128 -0
- package/dist/requirement-check-glU7wqhQ.d.ts +17 -0
- package/dist/requirements-Dx_ZVzl7.d.ts +227 -0
- package/dist/resources/api-key.d.ts +11 -0
- package/dist/resources/api-key.js +35 -0
- package/dist/resources/card.d.ts +2 -0
- package/dist/resources/card.js +103 -0
- package/dist/resources/collection.d.ts +2 -0
- package/dist/resources/collection.js +134 -0
- package/dist/resources/content-translation.d.ts +11 -0
- package/dist/resources/content-translation.js +27 -0
- package/dist/resources/csv-upload.d.ts +2 -0
- package/dist/resources/csv-upload.js +9 -0
- package/dist/resources/dashboard.d.ts +2 -0
- package/dist/resources/dashboard.js +221 -0
- package/dist/resources/data-action.d.ts +60 -0
- package/dist/resources/data-action.js +79 -0
- package/dist/resources/data-app.d.ts +112 -0
- package/dist/resources/data-app.js +75 -0
- package/dist/resources/database.d.ts +2 -0
- package/dist/resources/database.js +103 -0
- package/dist/resources/dataset.d.ts +2 -0
- package/dist/resources/dataset.js +81 -0
- package/dist/resources/dependency.d.ts +2 -0
- package/dist/resources/dependency.js +156 -0
- package/dist/resources/document.d.ts +55 -0
- package/dist/resources/document.js +60 -0
- package/dist/resources/eid-translation.d.ts +8 -0
- package/dist/resources/eid-translation.js +19 -0
- package/dist/resources/erd.d.ts +2 -0
- package/dist/resources/erd.js +26 -0
- package/dist/resources/field.d.ts +2 -0
- package/dist/resources/field.js +99 -0
- package/dist/resources/git-sync.d.ts +2 -0
- package/dist/resources/git-sync.js +362 -0
- package/dist/resources/glossary.d.ts +2 -0
- package/dist/resources/glossary.js +51 -0
- package/dist/resources/library.d.ts +85 -0
- package/dist/resources/library.js +90 -0
- package/dist/resources/measure.d.ts +2 -0
- package/dist/resources/measure.js +57 -0
- package/dist/resources/metric.d.ts +2 -0
- package/dist/resources/metric.js +50 -0
- package/dist/resources/moderation-review.d.ts +23 -0
- package/dist/resources/moderation-review.js +24 -0
- package/dist/resources/notification.d.ts +2 -0
- package/dist/resources/notification.js +93 -0
- package/dist/resources/optional-parsed.d.ts +7 -0
- package/dist/resources/optional-parsed.js +14 -0
- package/dist/resources/permission.d.ts +10 -0
- package/dist/resources/permission.js +31 -0
- package/dist/resources/pivot-export.d.ts +10 -0
- package/dist/resources/pivot-export.js +16 -0
- package/dist/resources/pulse.d.ts +2 -0
- package/dist/resources/pulse.js +76 -0
- package/dist/resources/replacement.d.ts +2 -0
- package/dist/resources/replacement.js +82 -0
- package/dist/resources/request-body.d.ts +9 -0
- package/dist/resources/request-body.js +13 -0
- package/dist/resources/revision.d.ts +70 -0
- package/dist/resources/revision.js +46 -0
- package/dist/resources/search.d.ts +2 -0
- package/dist/resources/search.js +78 -0
- package/dist/resources/segment.d.ts +2 -0
- package/dist/resources/segment.js +55 -0
- package/dist/resources/setting.d.ts +11 -0
- package/dist/resources/setting.js +43 -0
- package/dist/resources/setup.d.ts +8 -0
- package/dist/resources/setup.js +18 -0
- package/dist/resources/snippet.d.ts +2 -0
- package/dist/resources/snippet.js +52 -0
- package/dist/resources/table.d.ts +2 -0
- package/dist/resources/table.js +274 -0
- package/dist/resources/timeline-event.d.ts +12 -0
- package/dist/resources/timeline-event.js +51 -0
- package/dist/resources/timeline.d.ts +2 -0
- package/dist/resources/timeline.js +82 -0
- package/dist/resources/transform-dag-run.d.ts +22 -0
- package/dist/resources/transform-dag-run.js +32 -0
- package/dist/resources/transform-inspector.d.ts +214 -0
- package/dist/resources/transform-inspector.js +47 -0
- package/dist/resources/transform-job.d.ts +2 -0
- package/dist/resources/transform-job.js +90 -0
- package/dist/resources/transform-python.d.ts +59 -0
- package/dist/resources/transform-python.js +57 -0
- package/dist/resources/transform-tag.d.ts +35 -0
- package/dist/resources/transform-tag.js +47 -0
- package/dist/resources/transform-test.d.ts +2 -0
- package/dist/resources/transform-test.js +75 -0
- package/dist/resources/transform.d.ts +2 -0
- package/dist/resources/transform.js +227 -0
- package/dist/resources/upload.d.ts +2 -0
- package/dist/resources/upload.js +48 -0
- package/dist/resources/user.d.ts +8 -0
- package/dist/resources/user.js +11 -0
- package/dist/revision-Dyl-8p7d.d.ts +106 -0
- package/dist/search-Cm5IxKss.d.ts +92 -0
- package/dist/search-Cten2h0I.d.ts +26 -0
- package/dist/segment-CbAgVO-5.d.ts +47 -0
- package/dist/segment-DQLX6r1E.d.ts +16 -0
- package/dist/session-properties-COtlxAcK.d.ts +15 -0
- package/dist/setting-DXuQGXGF.d.ts +25 -0
- package/dist/setup-JqcJ2unJ.d.ts +26 -0
- package/dist/signal.d.ts +8 -0
- package/dist/signal.js +25 -0
- package/dist/snippet-C_Ilx7tR.d.ts +41 -0
- package/dist/snippet-Djn0rL21.d.ts +16 -0
- package/dist/table-CDZbLNow.d.ts +176 -0
- package/dist/table-Od6uvDVW.d.ts +3234 -0
- package/dist/tag-qzjGGci8.d.ts +48 -0
- package/dist/timeline-BK45hy-h.d.ts +218 -0
- package/dist/timeline-BTs6fuRp.d.ts +21 -0
- package/dist/transform-C5thnJwW.d.ts +559 -0
- package/dist/transform-WASQAXeA.d.ts +652 -0
- package/dist/transform-dag-run-BgZwv1yx.d.ts +49 -0
- package/dist/transform-inspector-CMCh8WKV.d.ts +374 -0
- package/dist/transform-job-D8jTQtdX.d.ts +98 -0
- package/dist/transform-job-DmTwKxhc.d.ts +237 -0
- package/dist/transform-python-DtL3xxMj.d.ts +101 -0
- package/dist/transform-tag-C6j5EUkX.d.ts +25 -0
- package/dist/transform-test-CR_i54IV.d.ts +412 -0
- package/dist/transform-test-CeMzDpUC.d.ts +346 -0
- package/dist/transport-BsXqRujn.d.ts +476 -0
- package/dist/transport-HP7cyo9N.js +397 -0
- package/dist/upload-B5YjVkSW.d.ts +12 -0
- package/dist/upload-UPfZFdbH.d.ts +22 -0
- package/dist/url-CI0pxHOc.d.ts +7 -0
- package/dist/url.d.ts +2 -0
- package/dist/url.js +34 -0
- package/dist/user-Sqqv7rqh.d.ts +18 -0
- package/dist/version/capability-error.d.ts +2 -0
- package/dist/version/capability-error.js +42 -0
- package/dist/version/features.d.ts +2 -0
- package/dist/version/features.js +171 -0
- package/dist/version/input-gates.d.ts +2 -0
- package/dist/version/input-gates.js +13 -0
- package/dist/version/known-range.d.ts +2 -0
- package/dist/version/known-range.js +7 -0
- package/dist/version/probe.d.ts +2 -0
- package/dist/version/probe.js +30 -0
- package/dist/version/profile.d.ts +2 -0
- package/dist/version/profile.js +64 -0
- package/dist/version/requirement-check.d.ts +2 -0
- package/dist/version/requirement-check.js +62 -0
- package/dist/version/requirements.d.ts +2 -0
- package/dist/version/requirements.js +229 -0
- package/dist/version/tag.d.ts +2 -0
- package/dist/version/tag.js +52 -0
- package/package.json +66 -4
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { f as RequestOptions, h as Transport } from "../transport-BsXqRujn.js";
|
|
2
|
+
import { t as ListResult } from "../list-BT_bBm9Z.js";
|
|
3
|
+
//#region src/resources/revision.d.ts
|
|
4
|
+
declare function revisionResource(transport: Transport): {
|
|
5
|
+
list: (entity: "transform" | "card" | "dashboard" | "document" | "measure" | "segment" | "transform-test", id: number, options?: RequestOptions | undefined) => Promise<ListResult<{
|
|
6
|
+
[x: string]: unknown;
|
|
7
|
+
id: number;
|
|
8
|
+
timestamp: string;
|
|
9
|
+
is_creation: boolean;
|
|
10
|
+
is_reversion: boolean;
|
|
11
|
+
most_recent: boolean;
|
|
12
|
+
diff: {
|
|
13
|
+
[x: string]: unknown;
|
|
14
|
+
} | null;
|
|
15
|
+
description: string;
|
|
16
|
+
has_multiple_changes: boolean;
|
|
17
|
+
user: {
|
|
18
|
+
[x: string]: unknown;
|
|
19
|
+
id: number;
|
|
20
|
+
first_name: string | null;
|
|
21
|
+
last_name: string | null;
|
|
22
|
+
common_name: string;
|
|
23
|
+
};
|
|
24
|
+
}>>;
|
|
25
|
+
revert: (params: {
|
|
26
|
+
entity: "transform" | "card" | "dashboard" | "document" | "measure" | "segment" | "transform-test";
|
|
27
|
+
id: number;
|
|
28
|
+
revision_id: number;
|
|
29
|
+
}, options?: RequestOptions | undefined) => Promise<{
|
|
30
|
+
outcome: "reverted";
|
|
31
|
+
revision: {
|
|
32
|
+
[x: string]: unknown;
|
|
33
|
+
id: number;
|
|
34
|
+
timestamp: string;
|
|
35
|
+
is_creation: boolean;
|
|
36
|
+
is_reversion: boolean;
|
|
37
|
+
most_recent: boolean;
|
|
38
|
+
diff: {
|
|
39
|
+
[x: string]: unknown;
|
|
40
|
+
} | null;
|
|
41
|
+
description: string;
|
|
42
|
+
has_multiple_changes: boolean;
|
|
43
|
+
user: {
|
|
44
|
+
[x: string]: unknown;
|
|
45
|
+
id: number;
|
|
46
|
+
first_name: string | null;
|
|
47
|
+
last_name: string | null;
|
|
48
|
+
common_name: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
} | {
|
|
52
|
+
outcome: "unchanged";
|
|
53
|
+
revision: {
|
|
54
|
+
[x: string]: unknown;
|
|
55
|
+
id: number;
|
|
56
|
+
model: string;
|
|
57
|
+
model_id: number;
|
|
58
|
+
user_id: number;
|
|
59
|
+
object: {
|
|
60
|
+
[x: string]: unknown;
|
|
61
|
+
};
|
|
62
|
+
timestamp: string;
|
|
63
|
+
is_creation: boolean;
|
|
64
|
+
is_reversion: boolean;
|
|
65
|
+
most_recent: boolean;
|
|
66
|
+
};
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
//#endregion
|
|
70
|
+
export { revisionResource };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { t as explainer } from "../refusal-B9aeHMc9.js";
|
|
2
|
+
import { gateTriggered } from "../version/input-gates.js";
|
|
3
|
+
import { REVISION_ENTITY_GATES, Revision, RevisionRow } from "../domain/revision.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region src/resources/revision.ts
|
|
6
|
+
const RevisionApiList = z.array(Revision);
|
|
7
|
+
const RevisionApiRevert = z.union([Revision.transform((revision) => ({
|
|
8
|
+
outcome: "reverted",
|
|
9
|
+
revision
|
|
10
|
+
})), RevisionRow.transform((revision) => ({
|
|
11
|
+
outcome: "unchanged",
|
|
12
|
+
revision
|
|
13
|
+
}))]);
|
|
14
|
+
function entityFeatures(entity) {
|
|
15
|
+
return REVISION_ENTITY_GATES.filter((gate) => gateTriggered(gate, entity)).map((gate) => ({
|
|
16
|
+
feature: gate.feature,
|
|
17
|
+
fields: ["entity"]
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function revisionResource(transport) {
|
|
21
|
+
const { explain } = explainer(transport, "revision");
|
|
22
|
+
/** List the revisions of an entity the caller may read, newest first, each with its diff. */
|
|
23
|
+
async function list(entity, id, options = {}) {
|
|
24
|
+
return {
|
|
25
|
+
data: await transport.requestParsed(RevisionApiList, `/api/revision/${entity}/${id}`, { ...options }),
|
|
26
|
+
total: null
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Revert an entity to one of its prior revisions. Needs write access to the entity, and for a
|
|
31
|
+
* card the permission to run the query being restored.
|
|
32
|
+
*/
|
|
33
|
+
async function revert(params, options = {}) {
|
|
34
|
+
return transport.requestParsed(RevisionApiRevert, "/api/revision/revert", {
|
|
35
|
+
...options,
|
|
36
|
+
method: "POST",
|
|
37
|
+
body: params
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
list: explain("list", list, entityFeatures),
|
|
42
|
+
revert: explain("revert", revert, (params) => entityFeatures(params.entity))
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { revisionResource };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { t as explainer } from "../refusal-B9aeHMc9.js";
|
|
2
|
+
import { SearchResult } from "../domain/search.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
//#region src/resources/search.ts
|
|
5
|
+
const SearchApiResponse = z.object({
|
|
6
|
+
data: z.array(SearchResult),
|
|
7
|
+
total: z.number().int().nonnegative()
|
|
8
|
+
}).loose();
|
|
9
|
+
function verifiedFeatures(params = {}) {
|
|
10
|
+
return params.verified === true ? [{
|
|
11
|
+
feature: "contentVerification",
|
|
12
|
+
fields: ["verified"]
|
|
13
|
+
}] : [];
|
|
14
|
+
}
|
|
15
|
+
const MODELS_FIELDS = ["models"];
|
|
16
|
+
const SEARCH_MODEL_FEATURES = {
|
|
17
|
+
measure: "measures",
|
|
18
|
+
transform: "transforms",
|
|
19
|
+
exploration: "explorations"
|
|
20
|
+
};
|
|
21
|
+
function modelFeatures(params) {
|
|
22
|
+
if (params.models === void 0) return [];
|
|
23
|
+
return params.models.flatMap((model) => {
|
|
24
|
+
const feature = SEARCH_MODEL_FEATURES[model];
|
|
25
|
+
return feature === void 0 ? [] : [{
|
|
26
|
+
feature,
|
|
27
|
+
fields: MODELS_FIELDS
|
|
28
|
+
}];
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function queryFeatures(params = {}) {
|
|
32
|
+
return [...verifiedFeatures(params), ...modelFeatures(params)];
|
|
33
|
+
}
|
|
34
|
+
function searchResource(transport) {
|
|
35
|
+
const { explain } = explainer(transport, "search");
|
|
36
|
+
/**
|
|
37
|
+
* Search over the instance's content, ranked against `q`. `models` narrows which kinds of entity
|
|
38
|
+
* may match, `archived` swaps the active set for the archived one, `table_db_id` restricts to
|
|
39
|
+
* items on one database, `verified` to verified content, `collection` to one collection and its
|
|
40
|
+
* descendants, `created_by` to items created by any of those users, `search_native_query` also
|
|
41
|
+
* matches native query text but narrows to the models that carry one (cards, models, metrics,
|
|
42
|
+
* actions, transforms), `include_metadata` attaches each card's `result_metadata`,
|
|
43
|
+
* `include_dashboard_questions` also matches questions saved into a dashboard (excluded by
|
|
44
|
+
* default), and `limit`/`offset` are the window the server applies before ranking hydration.
|
|
45
|
+
* `verified` needs the `content_verification` premium feature, and is refused before the wire
|
|
46
|
+
* without it: a server granting neither it nor `official_collections` refuses the filter, and one
|
|
47
|
+
* granting `official_collections` alone takes it without applying it. `models` takes `measure`
|
|
48
|
+
* only with `measures`, `transform` with `transforms` or on a Metabase 58 enterprise build, and
|
|
49
|
+
* `exploration` only with `explorations`.
|
|
50
|
+
*/
|
|
51
|
+
async function query(params = {}, options = {}) {
|
|
52
|
+
await transport.requireFeatures(verifiedFeatures(params).map((requirement) => requirement.feature), options);
|
|
53
|
+
const response = await transport.requestParsed(SearchApiResponse, "/api/search", {
|
|
54
|
+
...options,
|
|
55
|
+
query: {
|
|
56
|
+
q: params.q,
|
|
57
|
+
models: params.models,
|
|
58
|
+
archived: params.archived,
|
|
59
|
+
limit: params.limit,
|
|
60
|
+
offset: params.offset,
|
|
61
|
+
table_db_id: params.table_db_id,
|
|
62
|
+
verified: params.verified,
|
|
63
|
+
collection: params.collection,
|
|
64
|
+
created_by: params.created_by,
|
|
65
|
+
search_native_query: params.search_native_query,
|
|
66
|
+
include_metadata: params.include_metadata,
|
|
67
|
+
include_dashboard_questions: params.include_dashboard_questions
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
data: response.data,
|
|
72
|
+
total: response.total
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { query: explain("query", query, queryFeatures) };
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { searchResource };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Segment } from "../domain/segment.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/resources/segment.ts
|
|
4
|
+
const SegmentApiList = z.array(Segment);
|
|
5
|
+
function segmentResource(transport) {
|
|
6
|
+
/** List every segment the caller can see. */
|
|
7
|
+
async function list(options = {}) {
|
|
8
|
+
return {
|
|
9
|
+
data: await transport.requestParsed(SegmentApiList, "/api/segment", { ...options }),
|
|
10
|
+
total: null
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/** Get one segment by id. */
|
|
14
|
+
async function get(id, options = {}) {
|
|
15
|
+
return transport.requestParsed(Segment, `/api/segment/${id}`, { ...options });
|
|
16
|
+
}
|
|
17
|
+
/** Create a segment — a reusable row filter over one table — from a full segment body. */
|
|
18
|
+
async function create(params, options = {}) {
|
|
19
|
+
return transport.requestParsed(Segment, "/api/segment", {
|
|
20
|
+
...options,
|
|
21
|
+
method: "POST",
|
|
22
|
+
body: params
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Update a segment by id, patching only the fields the body carries. `revision_message` is
|
|
27
|
+
* required: Metabase records every segment change in its revision history.
|
|
28
|
+
*/
|
|
29
|
+
async function update(id, params, options = {}) {
|
|
30
|
+
return transport.requestParsed(Segment, `/api/segment/${id}`, {
|
|
31
|
+
...options,
|
|
32
|
+
method: "PUT",
|
|
33
|
+
body: params
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Archive (soft-delete) a segment by id. Metabase models this as an update, so it carries the
|
|
38
|
+
* same required `revision_message`.
|
|
39
|
+
*/
|
|
40
|
+
async function archive(id, params, options = {}) {
|
|
41
|
+
return update(id, {
|
|
42
|
+
archived: true,
|
|
43
|
+
revision_message: params.revision_message
|
|
44
|
+
}, options);
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
list,
|
|
48
|
+
get,
|
|
49
|
+
create,
|
|
50
|
+
update,
|
|
51
|
+
archive
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { segmentResource };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { f as RequestOptions, h as Transport } from "../transport-BsXqRujn.js";
|
|
2
|
+
import { t as ListResult } from "../list-BT_bBm9Z.js";
|
|
3
|
+
import { t as Setting } from "../setting-DXuQGXGF.js";
|
|
4
|
+
//#region src/resources/setting.d.ts
|
|
5
|
+
declare function settingResource(transport: Transport): {
|
|
6
|
+
list: (options?: RequestOptions) => Promise<ListResult<Setting>>;
|
|
7
|
+
get: (key: string, options?: RequestOptions) => Promise<unknown>;
|
|
8
|
+
set: (key: string, value: unknown, options?: RequestOptions) => Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { settingResource };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ConfigError, errorMessage } from "../errors.js";
|
|
2
|
+
import { fetchOptionalParsed } from "./optional-parsed.js";
|
|
3
|
+
import { Setting } from "../domain/setting.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region src/resources/setting.ts
|
|
6
|
+
const SettingApiList = z.array(Setting);
|
|
7
|
+
const UNKNOWN_SETTING_PREFIX = "Unknown setting:";
|
|
8
|
+
function rethrowSettingError(error, key) {
|
|
9
|
+
if (errorMessage(error).startsWith(UNKNOWN_SETTING_PREFIX)) throw new ConfigError(`unknown setting: ${key}`);
|
|
10
|
+
throw error;
|
|
11
|
+
}
|
|
12
|
+
function settingResource(transport) {
|
|
13
|
+
/** Get all settings and their values, with descriptions and environment-variable names. */
|
|
14
|
+
async function list(options = {}) {
|
|
15
|
+
return {
|
|
16
|
+
data: await transport.requestParsed(SettingApiList, "/api/setting", { ...options }),
|
|
17
|
+
total: null
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Fetch a single setting's value by key. An unset setting answers 204 rather than 404, which
|
|
22
|
+
* reaches the caller as `null`; a string-typed setting answers bare text rather than JSON.
|
|
23
|
+
*/
|
|
24
|
+
async function get(key, options = {}) {
|
|
25
|
+
return fetchOptionalParsed(transport, `/api/setting/${encodeURIComponent(key)}`, z.unknown(), options).catch((error) => rethrowSettingError(error, key));
|
|
26
|
+
}
|
|
27
|
+
/** Set a single setting's value by key. The endpoint answers 204 with no body. */
|
|
28
|
+
async function set(key, value, options = {}) {
|
|
29
|
+
await transport.requestRaw(`/api/setting/${encodeURIComponent(key)}`, {
|
|
30
|
+
...options,
|
|
31
|
+
method: "PUT",
|
|
32
|
+
body: { value },
|
|
33
|
+
expectContentType: "binary"
|
|
34
|
+
}).catch((error) => rethrowSettingError(error, key));
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
list,
|
|
38
|
+
get,
|
|
39
|
+
set
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { settingResource };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { f as RequestOptions, h as Transport } from "../transport-BsXqRujn.js";
|
|
2
|
+
import { n as SetupResult, t as SetupInput } from "../setup-JqcJ2unJ.js";
|
|
3
|
+
//#region src/resources/setup.d.ts
|
|
4
|
+
declare function setupResource(transport: Transport): {
|
|
5
|
+
create: (params: SetupInput, options?: RequestOptions) => Promise<SetupResult>;
|
|
6
|
+
};
|
|
7
|
+
//#endregion
|
|
8
|
+
export { setupResource };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SetupResult } from "../domain/setup.js";
|
|
2
|
+
//#region src/resources/setup.ts
|
|
3
|
+
function setupResource(transport) {
|
|
4
|
+
/**
|
|
5
|
+
* Complete the initial setup wizard on a fresh instance, creating its first admin user and
|
|
6
|
+
* applying the instance preferences. The setup token is single-use.
|
|
7
|
+
*/
|
|
8
|
+
async function create(params, options = {}) {
|
|
9
|
+
return transport.requestParsed(SetupResult, "/api/setup", {
|
|
10
|
+
...options,
|
|
11
|
+
method: "POST",
|
|
12
|
+
body: params
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return { create };
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { setupResource };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Snippet } from "../domain/snippet.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/resources/snippet.ts
|
|
4
|
+
const SnippetApiList = z.array(Snippet);
|
|
5
|
+
function snippetResource(transport) {
|
|
6
|
+
/** List native query snippets. `archived` swaps the listing to archived snippets. */
|
|
7
|
+
async function list(params = {}, options = {}) {
|
|
8
|
+
return {
|
|
9
|
+
data: await transport.requestParsed(SnippetApiList, "/api/native-query-snippet", {
|
|
10
|
+
...options,
|
|
11
|
+
query: { archived: params.archived }
|
|
12
|
+
}),
|
|
13
|
+
total: null
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** Get one native query snippet by id. */
|
|
17
|
+
async function get(id, options = {}) {
|
|
18
|
+
return transport.requestParsed(Snippet, `/api/native-query-snippet/${id}`, { ...options });
|
|
19
|
+
}
|
|
20
|
+
/** Create a native query snippet from a name, its SQL fragment, and an optional collection. */
|
|
21
|
+
async function create(params, options = {}) {
|
|
22
|
+
return transport.requestParsed(Snippet, "/api/native-query-snippet", {
|
|
23
|
+
...options,
|
|
24
|
+
method: "POST",
|
|
25
|
+
body: params
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Update a native query snippet by id, patching only the fields the body carries. */
|
|
29
|
+
async function update(id, params, options = {}) {
|
|
30
|
+
return transport.requestParsed(Snippet, `/api/native-query-snippet/${id}`, {
|
|
31
|
+
...options,
|
|
32
|
+
method: "PUT",
|
|
33
|
+
body: params
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Archive (soft-delete) a native query snippet by id. Metabase models this as an update, not its
|
|
38
|
+
* own endpoint.
|
|
39
|
+
*/
|
|
40
|
+
async function archive(id, options = {}) {
|
|
41
|
+
return update(id, { archived: true }, options);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
list,
|
|
45
|
+
get,
|
|
46
|
+
create,
|
|
47
|
+
update,
|
|
48
|
+
archive
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { snippetResource };
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { PartialWriteError } from "../errors.js";
|
|
2
|
+
import { CapabilityError } from "../version/capability-error.js";
|
|
3
|
+
import { supersedingFeature } from "../version/requirement-check.js";
|
|
4
|
+
import { DATA_AUTHORITY_WITHDRAWAL_GATE, DATA_LAYER_MEDALLION_GATE, DATA_LAYER_TIER_GATE, Table, TableDataLayerTier, TableForeignKey, TableQueryMetadata, TableSelectors } from "../domain/table.js";
|
|
5
|
+
import { t as explainer } from "../refusal-B9aeHMc9.js";
|
|
6
|
+
import { buildCsvFormData } from "./csv-upload.js";
|
|
7
|
+
import { parseRequestBody } from "./request-body.js";
|
|
8
|
+
import { gateTriggered } from "../version/input-gates.js";
|
|
9
|
+
import { fetchOptionalParsed } from "./optional-parsed.js";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
//#region src/resources/table.ts
|
|
12
|
+
const TableApiList = z.array(Table);
|
|
13
|
+
const TableApiFks = z.array(TableForeignKey);
|
|
14
|
+
const SyncSchemaResponse = z.object({ status: z.literal("ok") });
|
|
15
|
+
const FieldValuesResponse = z.object({ status: z.literal("success") });
|
|
16
|
+
const BulkEditResponse = z.object({});
|
|
17
|
+
const BULK_EDIT_PATH = "/api/data-studio/table/edit";
|
|
18
|
+
const BULK_SYNC_SCHEMA_PATH = "/api/data-studio/table/sync-schema";
|
|
19
|
+
const BULK_RESCAN_VALUES_PATH = "/api/data-studio/table/rescan-values";
|
|
20
|
+
const BULK_DISCARD_VALUES_PATH = "/api/data-studio/table/discard-values";
|
|
21
|
+
const LIST_PARAM_FEATURES = [
|
|
22
|
+
["can-query", "tableListAccessFilters"],
|
|
23
|
+
["can-write", "tableListAccessFilters"],
|
|
24
|
+
["include-transform-targets", "tableListTransformTargets"],
|
|
25
|
+
["unused-only", "tableUnusedFilter"],
|
|
26
|
+
["published-only", "tableListPublishedFilter"]
|
|
27
|
+
];
|
|
28
|
+
function listParamFeatures(params) {
|
|
29
|
+
return LIST_PARAM_FEATURES.filter(([param]) => params[param] === true).map(([, feature]) => feature);
|
|
30
|
+
}
|
|
31
|
+
function dataLayerFeatures(value, field) {
|
|
32
|
+
return gateTriggered(DATA_LAYER_TIER_GATE, value) ? [{
|
|
33
|
+
feature: DATA_LAYER_TIER_GATE.feature,
|
|
34
|
+
fields: [field]
|
|
35
|
+
}] : [];
|
|
36
|
+
}
|
|
37
|
+
const UPLOAD_UPDATE_PATHS = {
|
|
38
|
+
append: "append-csv",
|
|
39
|
+
replace: "replace-csv"
|
|
40
|
+
};
|
|
41
|
+
function tableResource(transport) {
|
|
42
|
+
const { explain } = explainer(transport, "table");
|
|
43
|
+
/**
|
|
44
|
+
* List every table the caller can see, across all databases. `term` matches names and display
|
|
45
|
+
* names; `can-query` and `can-write` keep only the tables the caller may query or edit the
|
|
46
|
+
* metadata of; `include-transform-targets` adds tables a transform writes to; `unused-only` keeps
|
|
47
|
+
* tables nothing depends on; `published-only` keeps tables published to the library.
|
|
48
|
+
*/
|
|
49
|
+
async function list(params = {}, options = {}) {
|
|
50
|
+
await transport.requireFeatures(listParamFeatures(params), options);
|
|
51
|
+
return {
|
|
52
|
+
data: await transport.requestParsed(TableApiList, "/api/table", {
|
|
53
|
+
...options,
|
|
54
|
+
query: {
|
|
55
|
+
term: params.term,
|
|
56
|
+
"visibility-type": params["visibility-type"],
|
|
57
|
+
"data-layer": params["data-layer"],
|
|
58
|
+
"data-source": params["data-source"],
|
|
59
|
+
"owner-user-id": params["owner-user-id"],
|
|
60
|
+
"owner-email": params["owner-email"],
|
|
61
|
+
"orphan-only": params["orphan-only"],
|
|
62
|
+
"unused-only": params["unused-only"],
|
|
63
|
+
"published-only": params["published-only"],
|
|
64
|
+
"can-query": params["can-query"],
|
|
65
|
+
"can-write": params["can-write"],
|
|
66
|
+
"include-transform-targets": params["include-transform-targets"]
|
|
67
|
+
}
|
|
68
|
+
}),
|
|
69
|
+
total: null
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Get one table by id, without its fields. */
|
|
73
|
+
async function get(id, options = {}) {
|
|
74
|
+
return transport.requestParsed(Table, `/api/table/${id}`, { ...options });
|
|
75
|
+
}
|
|
76
|
+
/** Update a table by id, patching only the fields the body carries. */
|
|
77
|
+
async function update(id, params, options = {}) {
|
|
78
|
+
await refuseRewrittenDataLayer(params.data_layer, options);
|
|
79
|
+
await requireDataAuthorityNull(params.data_authority, options);
|
|
80
|
+
const path = `/api/table/${id}`;
|
|
81
|
+
const updated = await transport.requestParsed(Table, path, {
|
|
82
|
+
...options,
|
|
83
|
+
method: "PUT",
|
|
84
|
+
body: params
|
|
85
|
+
});
|
|
86
|
+
assertCollectionWritten(path, params.collection_id, updated);
|
|
87
|
+
return updated;
|
|
88
|
+
}
|
|
89
|
+
async function refuseRewrittenDataLayer(value, options) {
|
|
90
|
+
if (!gateTriggered(DATA_LAYER_MEDALLION_GATE, value)) return;
|
|
91
|
+
const profile = await transport.preflightServer(options);
|
|
92
|
+
if (profile === null) return;
|
|
93
|
+
const detail = `data_layer "${value}" is a medallion name; this server names a table's layer ${TableDataLayerTier.options.join(", ")} and would map it onto one of those without a word`;
|
|
94
|
+
const failure = supersedingFeature(DATA_LAYER_MEDALLION_GATE.feature, profile, detail);
|
|
95
|
+
if (failure !== null) transport.refuseBeforeSending(new CapabilityError(failure));
|
|
96
|
+
}
|
|
97
|
+
/** Get a table by id with its fields hydrated — the metadata the query builder runs on. */
|
|
98
|
+
async function queryMetadata(id, options = {}) {
|
|
99
|
+
return transport.requestParsed(TableQueryMetadata, `/api/table/${id}/query_metadata`, { ...options });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get every foreign key whose destination is a field of this table. A table with no active
|
|
103
|
+
* fields answers no content, which is the same empty list.
|
|
104
|
+
*/
|
|
105
|
+
async function fks(id, options = {}) {
|
|
106
|
+
return {
|
|
107
|
+
data: await fetchOptionalParsed(transport, `/api/table/${id}/fks`, TableApiFks, { ...options }) ?? [],
|
|
108
|
+
total: null
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Trigger a sync of this table: its columns, their fingerprints and its cached field values. It
|
|
113
|
+
* never discovers new tables. The sync runs after the call returns; a warehouse the server cannot
|
|
114
|
+
* connect to is a 422.
|
|
115
|
+
*/
|
|
116
|
+
async function syncSchema(id, options = {}) {
|
|
117
|
+
return {
|
|
118
|
+
id,
|
|
119
|
+
status: (await transport.requestParsed(SyncSchemaResponse, `/api/table/${id}/sync_schema`, {
|
|
120
|
+
...options,
|
|
121
|
+
method: "POST"
|
|
122
|
+
})).status
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Trigger an update of the field values of every eligible field of this table that already has a
|
|
127
|
+
* cached set. The scan runs after the call returns.
|
|
128
|
+
*/
|
|
129
|
+
async function rescanValues(id, options = {}) {
|
|
130
|
+
return {
|
|
131
|
+
id,
|
|
132
|
+
status: (await transport.requestParsed(FieldValuesResponse, `/api/table/${id}/rescan_values`, {
|
|
133
|
+
...options,
|
|
134
|
+
method: "POST"
|
|
135
|
+
})).status
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Discard the cached field values of every field of this table, custom display values included.
|
|
140
|
+
* No scan recreates a discarded set; the server rebuilds it, without the display values, the next
|
|
141
|
+
* time the field's values are read.
|
|
142
|
+
*/
|
|
143
|
+
async function discardValues(id, options = {}) {
|
|
144
|
+
return {
|
|
145
|
+
id,
|
|
146
|
+
status: (await transport.requestParsed(FieldValuesResponse, `/api/table/${id}/discard_values`, {
|
|
147
|
+
...options,
|
|
148
|
+
method: "POST"
|
|
149
|
+
})).status
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Set the same metadata on every table the selectors pick out. A table leaving the `hidden` data
|
|
154
|
+
* layer is re-synced after the call returns. The server answers the same whether or not the
|
|
155
|
+
* selectors matched a table.
|
|
156
|
+
*/
|
|
157
|
+
async function bulkEdit(params, options = {}) {
|
|
158
|
+
await requireDataAuthorityNull(params.data_authority, options);
|
|
159
|
+
await transport.requestParsed(BulkEditResponse, BULK_EDIT_PATH, {
|
|
160
|
+
...options,
|
|
161
|
+
method: "POST",
|
|
162
|
+
body: params
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
accepted: true,
|
|
166
|
+
...params
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async function requireDataAuthorityNull(value, options) {
|
|
170
|
+
if (gateTriggered(DATA_AUTHORITY_WITHDRAWAL_GATE, value)) await transport.requireFeatures([DATA_AUTHORITY_WITHDRAWAL_GATE.feature], options);
|
|
171
|
+
}
|
|
172
|
+
async function postSelection(path, selectors, options) {
|
|
173
|
+
const body = parseRequestBody(TableSelectors, selectors, "table selectors");
|
|
174
|
+
await transport.requestRaw(path, {
|
|
175
|
+
...options,
|
|
176
|
+
method: "POST",
|
|
177
|
+
body,
|
|
178
|
+
expectContentType: "binary"
|
|
179
|
+
});
|
|
180
|
+
return {
|
|
181
|
+
accepted: true,
|
|
182
|
+
...body
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Trigger a sync of every table the selectors pick out: its columns, their fingerprints and its
|
|
187
|
+
* cached field values. Every database behind them must answer a connection test first, or the
|
|
188
|
+
* call is a 422; the syncs run after it returns.
|
|
189
|
+
*/
|
|
190
|
+
async function bulkSyncSchema(selectors, options = {}) {
|
|
191
|
+
return postSelection(BULK_SYNC_SCHEMA_PATH, selectors, options);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Trigger a field-values rescan of every table the selectors pick out, refreshing the sets that
|
|
195
|
+
* are already cached. The scans run after the call returns.
|
|
196
|
+
*/
|
|
197
|
+
async function bulkRescanValues(selectors, options = {}) {
|
|
198
|
+
return postSelection(BULK_RESCAN_VALUES_PATH, selectors, options);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Discard the cached field values of every table the selectors pick out, custom display values
|
|
202
|
+
* included. No scan recreates a discarded set.
|
|
203
|
+
*/
|
|
204
|
+
async function bulkDiscardValues(selectors, options = {}) {
|
|
205
|
+
return postSelection(BULK_DISCARD_VALUES_PATH, selectors, options);
|
|
206
|
+
}
|
|
207
|
+
async function updateFromCsv(id, action, file, options) {
|
|
208
|
+
await transport.requestRaw(`/api/table/${id}/${UPLOAD_UPDATE_PATHS[action]}`, {
|
|
209
|
+
...options,
|
|
210
|
+
method: "POST",
|
|
211
|
+
body: buildCsvFormData(file),
|
|
212
|
+
expectContentType: "binary"
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
table_id: id,
|
|
216
|
+
action
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Inserts the rows of an uploaded CSV file into the table identified by `id`. The table must have
|
|
221
|
+
* been created by uploading a CSV file.
|
|
222
|
+
*
|
|
223
|
+
* The file may be at most 50 MB; larger uploads are rejected with a 413 response.
|
|
224
|
+
*/
|
|
225
|
+
async function appendCsv(id, file, options = {}) {
|
|
226
|
+
return updateFromCsv(id, "append", file, options);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Replaces the contents of the table identified by `id` with the rows of an uploaded CSV file.
|
|
230
|
+
* The table must have been created by uploading a CSV file.
|
|
231
|
+
*
|
|
232
|
+
* The file may be at most 50 MB; larger uploads are rejected with a 413 response.
|
|
233
|
+
*/
|
|
234
|
+
async function replaceCsv(id, file, options = {}) {
|
|
235
|
+
return updateFromCsv(id, "replace", file, options);
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
list: explain("list", list, (params) => dataLayerFeatures(params?.["data-layer"], "data-layer")),
|
|
239
|
+
get,
|
|
240
|
+
update: explain("update", update, (_id, params) => dataLayerFeatures(params.data_layer, "data_layer")),
|
|
241
|
+
queryMetadata,
|
|
242
|
+
fks,
|
|
243
|
+
syncSchema,
|
|
244
|
+
rescanValues,
|
|
245
|
+
discardValues,
|
|
246
|
+
bulkEdit: explain("bulkEdit", bulkEdit),
|
|
247
|
+
bulkSyncSchema: explain("bulkSyncSchema", bulkSyncSchema),
|
|
248
|
+
bulkRescanValues: explain("bulkRescanValues", bulkRescanValues),
|
|
249
|
+
bulkDiscardValues: explain("bulkDiscardValues", bulkDiscardValues),
|
|
250
|
+
appendCsv,
|
|
251
|
+
replaceCsv
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function assertCollectionWritten(path, requested, table) {
|
|
255
|
+
if (requested === void 0 || table.collection_id === requested) return;
|
|
256
|
+
const answered = table.collection_id === void 0 ? { kind: "unreported" } : {
|
|
257
|
+
kind: "reported",
|
|
258
|
+
value: table.collection_id
|
|
259
|
+
};
|
|
260
|
+
throw new PartialWriteError(`the server applied the rest of the update to table ${table.id} but not collection_id: ${describeCollectionAnswer(answered)}, because this server does not move a table to a collection through an update`, {
|
|
261
|
+
method: "PUT",
|
|
262
|
+
path,
|
|
263
|
+
field: "collection_id",
|
|
264
|
+
requested,
|
|
265
|
+
answered
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
function describeCollectionAnswer(answered) {
|
|
269
|
+
if (answered.kind === "unreported") return "it answered the table without reporting a collection";
|
|
270
|
+
if (answered.value === null) return "the table stays in no collection";
|
|
271
|
+
return `the table stays in collection ${answered.value}`;
|
|
272
|
+
}
|
|
273
|
+
//#endregion
|
|
274
|
+
export { tableResource };
|