@nyrra/prismantix-cli 0.0.3-next.17 → 0.0.3-next.18
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/README.md +20 -28
- package/bin/dev.js +1 -3
- package/bin/run.js +1 -3
- package/dist/api.d.ts +202 -173
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +238 -110
- package/dist/command-support.d.ts +13 -0
- package/dist/command-support.d.ts.map +1 -0
- package/dist/command-support.js +40 -0
- package/dist/commands/object/details.d.ts +13 -0
- package/dist/commands/object/details.d.ts.map +1 -0
- package/dist/commands/object/details.js +28 -0
- package/dist/commands/object/list.d.ts +13 -0
- package/dist/commands/object/list.d.ts.map +1 -0
- package/dist/commands/object/list.js +27 -0
- package/dist/commands/ontology/list.d.ts +10 -0
- package/dist/commands/ontology/list.d.ts.map +1 -0
- package/dist/commands/ontology/list.js +25 -0
- package/dist/commands/records/cancel.d.ts +13 -0
- package/dist/commands/records/cancel.d.ts.map +1 -0
- package/dist/commands/records/cancel.js +21 -0
- package/dist/commands/records/generate.d.ts +15 -0
- package/dist/commands/records/generate.d.ts.map +1 -0
- package/dist/commands/records/generate.js +56 -0
- package/dist/commands/{download.d.ts → records/pull.d.ts} +5 -11
- package/dist/commands/records/pull.d.ts.map +1 -0
- package/dist/commands/records/pull.js +59 -0
- package/dist/commands/records/status.d.ts +13 -0
- package/dist/commands/records/status.d.ts.map +1 -0
- package/dist/commands/records/status.js +22 -0
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +39 -0
- package/dist/generation.d.ts +13 -0
- package/dist/generation.d.ts.map +1 -0
- package/dist/generation.js +77 -0
- package/dist/io.d.ts.map +1 -1
- package/dist/io.js +1 -1
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +10 -0
- package/dist/workflow.d.ts +3 -14
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +85 -61
- package/oclif.manifest.json +262 -36
- package/package.json +22 -22
- package/dist/commands/download.d.ts.map +0 -1
- package/dist/commands/download.js +0 -136
- package/dist/commands/guided.d.ts +0 -7
- package/dist/commands/guided.d.ts.map +0 -1
- package/dist/commands/guided.js +0 -15
- package/dist/ui/guided-flow.d.ts +0 -20
- package/dist/ui/guided-flow.d.ts.map +0 -1
- package/dist/ui/guided-flow.js +0 -156
package/dist/api.js
CHANGED
|
@@ -1,120 +1,248 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Config, ConfigProvider, Context, Effect, Layer, Predicate, Redacted, Schema, } from "effect";
|
|
2
2
|
import { DEFAULT_API_BASE_URL } from "./constants.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
const ExportOutputSchema = Schema.Union([
|
|
4
|
+
Schema.Struct({ kind: Schema.Literal("csv_bundle") }),
|
|
5
|
+
Schema.Struct({ kind: Schema.Literal("sqlite_seed_script") }),
|
|
6
|
+
]);
|
|
7
|
+
const ManifestFileSchema = Schema.Struct({
|
|
8
|
+
columns: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
9
|
+
fileName: Schema.String,
|
|
10
|
+
mimeType: Schema.optionalKey(Schema.String),
|
|
11
|
+
rowCount: Schema.optionalKey(Schema.Number),
|
|
12
|
+
sha256: Schema.optionalKey(Schema.String),
|
|
13
|
+
sizeBytes: Schema.optionalKey(Schema.Number),
|
|
14
|
+
storageKey: Schema.optionalKey(Schema.String),
|
|
15
|
+
tableName: Schema.String,
|
|
12
16
|
});
|
|
13
|
-
const
|
|
14
|
-
clientId:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const ExportManifestSchema = Schema.Struct({
|
|
18
|
+
clientId: Schema.String,
|
|
19
|
+
completedAt: Schema.optionalKey(Schema.Number),
|
|
20
|
+
createdAt: Schema.optionalKey(Schema.Number),
|
|
21
|
+
exportId: Schema.String,
|
|
22
|
+
files: Schema.Array(ManifestFileSchema),
|
|
23
|
+
output: ExportOutputSchema,
|
|
24
|
+
schemaVersion: Schema.optionalKey(Schema.String),
|
|
25
|
+
totalRows: Schema.Number,
|
|
19
26
|
});
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
manifestUrl: z.string().url().nullable().optional(),
|
|
29
|
-
startedAt: z.number().optional(),
|
|
30
|
-
status: z.enum(["queued", "running", "completed", "failed"]),
|
|
31
|
-
totalFiles: z.number().optional(),
|
|
32
|
-
totalRows: z.number().optional(),
|
|
27
|
+
const ExportStatusFileSchema = Schema.Struct({
|
|
28
|
+
downloadUrl: Schema.NullOr(Schema.String),
|
|
29
|
+
fileName: Schema.String,
|
|
30
|
+
mimeType: Schema.optionalKey(Schema.String),
|
|
31
|
+
rowCount: Schema.optionalKey(Schema.Number),
|
|
32
|
+
sha256: Schema.optionalKey(Schema.String),
|
|
33
|
+
sizeBytes: Schema.optionalKey(Schema.Number),
|
|
34
|
+
tableName: Schema.String,
|
|
33
35
|
});
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
const ExportStatusSchema = Schema.Struct({
|
|
37
|
+
clientId: Schema.String,
|
|
38
|
+
completedAt: Schema.optionalKey(Schema.Number),
|
|
39
|
+
createdAt: Schema.optionalKey(Schema.Number),
|
|
40
|
+
errorMessage: Schema.optionalKey(Schema.String),
|
|
41
|
+
exportId: Schema.String,
|
|
42
|
+
failedAt: Schema.optionalKey(Schema.Number),
|
|
43
|
+
files: Schema.Array(ExportStatusFileSchema),
|
|
44
|
+
manifestUrl: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
45
|
+
output: ExportOutputSchema,
|
|
46
|
+
startedAt: Schema.optionalKey(Schema.Number),
|
|
47
|
+
status: Schema.Literals(["completed", "failed", "queued", "running"]),
|
|
48
|
+
totalFiles: Schema.optionalKey(Schema.Number),
|
|
49
|
+
totalRows: Schema.optionalKey(Schema.Number),
|
|
37
50
|
});
|
|
38
|
-
const
|
|
39
|
-
.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
51
|
+
const ExportCreatedSchema = Schema.Struct({
|
|
52
|
+
clientId: Schema.String,
|
|
53
|
+
exportId: Schema.String,
|
|
54
|
+
status: Schema.Literal("queued"),
|
|
55
|
+
});
|
|
56
|
+
const OntologySummarySchema = Schema.Struct({
|
|
57
|
+
description: Schema.String,
|
|
58
|
+
displayName: Schema.String,
|
|
59
|
+
id: Schema.String,
|
|
60
|
+
objectCount: Schema.Number,
|
|
61
|
+
});
|
|
62
|
+
const OntologyObjectSummarySchema = Schema.Struct({
|
|
63
|
+
defaultRecordCount: Schema.NullOr(Schema.Number),
|
|
64
|
+
description: Schema.String,
|
|
65
|
+
displayName: Schema.String,
|
|
66
|
+
generationEligible: Schema.Boolean,
|
|
67
|
+
owningOntologyId: Schema.String,
|
|
68
|
+
pluralDisplayName: Schema.String,
|
|
69
|
+
slug: Schema.String,
|
|
70
|
+
});
|
|
71
|
+
const OntologyObjectDetailSchema = Schema.Struct({
|
|
72
|
+
...OntologyObjectSummarySchema.fields,
|
|
73
|
+
fields: Schema.Array(Schema.Struct({
|
|
74
|
+
array: Schema.Boolean,
|
|
75
|
+
description: Schema.String,
|
|
76
|
+
displayName: Schema.String,
|
|
77
|
+
enumValues: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
78
|
+
name: Schema.String,
|
|
79
|
+
nullable: Schema.Boolean,
|
|
80
|
+
optional: Schema.Boolean,
|
|
81
|
+
type: Schema.String,
|
|
82
|
+
})),
|
|
83
|
+
generationDependencies: Schema.Array(Schema.String),
|
|
84
|
+
guidance: Schema.Array(Schema.String),
|
|
85
|
+
relationships: Schema.Array(Schema.Struct({ field: Schema.String, many: Schema.Boolean, targetObjectSlug: Schema.String })),
|
|
86
|
+
});
|
|
87
|
+
const GenerationStateSchema = Schema.Literals([
|
|
88
|
+
"queued",
|
|
89
|
+
"running",
|
|
90
|
+
"completed",
|
|
91
|
+
"failed",
|
|
92
|
+
"canceled",
|
|
93
|
+
]);
|
|
94
|
+
const RecordGenerationCreatedSchema = Schema.Struct({
|
|
95
|
+
clientId: Schema.String,
|
|
96
|
+
createdAt: Schema.Number,
|
|
97
|
+
ontologyId: Schema.String,
|
|
98
|
+
operationId: Schema.String,
|
|
99
|
+
status: Schema.Literal("queued"),
|
|
100
|
+
statusUrl: Schema.String,
|
|
101
|
+
});
|
|
102
|
+
const RecordGenerationStatusSchema = Schema.Struct({
|
|
103
|
+
canceledAt: Schema.optionalKey(Schema.Number),
|
|
104
|
+
clientId: Schema.String,
|
|
105
|
+
completedAt: Schema.optionalKey(Schema.Number),
|
|
106
|
+
createdAt: Schema.Number,
|
|
107
|
+
failure: Schema.optionalKey(Schema.Struct({ code: Schema.String, message: Schema.String })),
|
|
108
|
+
ontologyId: Schema.String,
|
|
109
|
+
operationId: Schema.String,
|
|
110
|
+
startedAt: Schema.optionalKey(Schema.Number),
|
|
111
|
+
status: GenerationStateSchema,
|
|
112
|
+
steps: Schema.Array(Schema.Struct({
|
|
113
|
+
issues: Schema.Array(Schema.String),
|
|
114
|
+
objectSlug: Schema.String,
|
|
115
|
+
persistedCount: Schema.Number,
|
|
116
|
+
rejectedCount: Schema.Number,
|
|
117
|
+
requestedCount: Schema.Number,
|
|
118
|
+
state: GenerationStateSchema,
|
|
119
|
+
})),
|
|
120
|
+
totals: Schema.Struct({
|
|
121
|
+
objectCount: Schema.Number,
|
|
122
|
+
persistedCount: Schema.Number,
|
|
123
|
+
rejectedCount: Schema.Number,
|
|
124
|
+
requestedCount: Schema.Number,
|
|
125
|
+
}),
|
|
126
|
+
});
|
|
127
|
+
export class ApiConfigurationError extends Schema.TaggedError()("ApiConfigurationError", { message: Schema.String }) {
|
|
128
|
+
}
|
|
129
|
+
export class ApiHttpError extends Schema.TaggedError()("ApiHttpError", {
|
|
130
|
+
message: Schema.String,
|
|
131
|
+
status: Schema.Number,
|
|
132
|
+
}) {
|
|
133
|
+
}
|
|
134
|
+
export class ApiTransportError extends Schema.TaggedError()("ApiTransportError", { message: Schema.String }) {
|
|
135
|
+
}
|
|
136
|
+
export class ApiDecodeError extends Schema.TaggedError()("ApiDecodeError", {
|
|
137
|
+
message: Schema.String,
|
|
138
|
+
}) {
|
|
139
|
+
}
|
|
140
|
+
export class PrismantixApiClient extends Context.Service()("@prismantix/cli/PrismantixApiClient") {
|
|
141
|
+
}
|
|
142
|
+
const apiConfig = (apiKeyOverride) => Config.all({
|
|
143
|
+
apiBaseUrl: Config.withDefault(Config.nonEmptyString("PRISMANTIX_API_BASE"), DEFAULT_API_BASE_URL),
|
|
144
|
+
apiKey: apiKeyOverride
|
|
145
|
+
? Config.succeed(Redacted.make(apiKeyOverride))
|
|
146
|
+
: Config.redacted("PRISMANTIX_API_KEY"),
|
|
147
|
+
});
|
|
148
|
+
export const makePrismantixApiClientLayer = (options = {}) => Layer.effect(PrismantixApiClient, Effect.gen(function* () {
|
|
149
|
+
const config = yield* apiConfig(options.apiKey).pipe(Effect.mapError(() => new ApiConfigurationError({
|
|
150
|
+
message: "Set PRISMANTIX_API_KEY before running the CLI.",
|
|
151
|
+
})));
|
|
152
|
+
const apiKey = Redacted.value(config.apiKey).trim();
|
|
153
|
+
if (!apiKey)
|
|
154
|
+
return yield* new ApiConfigurationError({
|
|
155
|
+
message: "Set PRISMANTIX_API_KEY before running the CLI.",
|
|
156
|
+
});
|
|
157
|
+
const baseUrl = (options.apiBaseUrl ?? config.apiBaseUrl).replace(/\/+$/, "");
|
|
158
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
159
|
+
const request = (method, path, schema, init = {}, retryTransport = false) => {
|
|
160
|
+
const effect = requestJson(fetchImpl, `${baseUrl}${path}`, apiKey, method, schema, init);
|
|
161
|
+
return retryTransport ? retryTransportErrors(effect, 2) : effect;
|
|
162
|
+
};
|
|
163
|
+
return PrismantixApiClient.of({
|
|
164
|
+
cancelRecordGeneration: (operationId) => request("POST", `/v1/record-generations/${encodeURIComponent(operationId)}/cancel`, RecordGenerationStatusSchema, {}, true),
|
|
165
|
+
createExport: (clientId) => request("POST", `/v1/clients/${encodeURIComponent(clientId)}/exports`, ExportCreatedSchema, { body: JSON.stringify({ output: { kind: "csv_bundle" } }) }),
|
|
166
|
+
createRecordGeneration: (clientId, ontologyId, idempotencyKey) => request("POST", `/v1/clients/${encodeURIComponent(clientId)}/record-generations`, RecordGenerationCreatedSchema, {
|
|
167
|
+
body: JSON.stringify({ ontologyId }),
|
|
168
|
+
headers: { "Idempotency-Key": idempotencyKey },
|
|
169
|
+
}, true),
|
|
170
|
+
getExportStatus: (exportId) => request("GET", `/v1/exports/${encodeURIComponent(exportId)}`, ExportStatusSchema, {}, true),
|
|
171
|
+
getFile: (exportId, tableName) => getExportFile(fetchImpl, baseUrl, apiKey, exportId, tableName),
|
|
172
|
+
getManifest: (exportId) => request("GET", `/v1/exports/${encodeURIComponent(exportId)}/manifest`, ExportManifestSchema, {}, true),
|
|
173
|
+
getOntologyObject: (objectSlug) => request("GET", `/v1/objects/${encodeURIComponent(objectSlug)}`, OntologyObjectDetailSchema, {}, true),
|
|
174
|
+
getRecordGeneration: (operationId) => request("GET", `/v1/record-generations/${encodeURIComponent(operationId)}`, RecordGenerationStatusSchema, {}, true),
|
|
175
|
+
listOntologies: () => request("GET", "/v1/ontologies", Schema.Array(OntologySummarySchema), {}, true),
|
|
176
|
+
listOntologyObjects: (ontologyId) => request("GET", `/v1/ontologies/${encodeURIComponent(ontologyId)}/objects`, Schema.Array(OntologyObjectSummarySchema), {}, true),
|
|
177
|
+
});
|
|
178
|
+
}).pipe(Effect.provide(ConfigProvider.layer(options.configProvider ?? ConfigProvider.fromEnv()))));
|
|
179
|
+
function requestJson(fetchImpl, url, apiKey, method, schema, init) {
|
|
180
|
+
return Effect.gen(function* () {
|
|
181
|
+
const response = yield* Effect.tryPromise({
|
|
182
|
+
try: (signal) => fetchImpl(url, {
|
|
183
|
+
...init,
|
|
184
|
+
headers: {
|
|
185
|
+
Accept: "application/json",
|
|
186
|
+
Authorization: `Bearer ${apiKey}`,
|
|
187
|
+
"Content-Type": "application/json",
|
|
188
|
+
...init.headers,
|
|
189
|
+
},
|
|
190
|
+
method,
|
|
191
|
+
signal,
|
|
192
|
+
}),
|
|
193
|
+
catch: (cause) => new ApiTransportError({ message: cause instanceof Error ? cause.message : String(cause) }),
|
|
87
194
|
});
|
|
88
|
-
if (response.ok)
|
|
89
|
-
return response;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
195
|
+
if (!response.ok)
|
|
196
|
+
return yield* httpError(response);
|
|
197
|
+
const payload = yield* Effect.tryPromise({
|
|
198
|
+
try: () => response.json(),
|
|
199
|
+
catch: (cause) => new ApiDecodeError({ message: cause instanceof Error ? cause.message : String(cause) }),
|
|
200
|
+
});
|
|
201
|
+
return yield* Schema.decodeUnknownEffect(schema)(payload).pipe(Effect.mapError((error) => new ApiDecodeError({ message: String(error) })));
|
|
202
|
+
});
|
|
93
203
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
catch {
|
|
100
|
-
return `API returned ${response.status}.`;
|
|
101
|
-
}
|
|
204
|
+
function retryTransportErrors(effect, remainingRetries) {
|
|
205
|
+
return effect.pipe(Effect.catchTag("ApiTransportError", (error) => remainingRetries > 0
|
|
206
|
+
? retryTransportErrors(effect, remainingRetries - 1)
|
|
207
|
+
: Effect.fail(error)));
|
|
102
208
|
}
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
209
|
+
function httpError(response) {
|
|
210
|
+
return Effect.gen(function* () {
|
|
211
|
+
const payload = yield* Effect.promise(async () => {
|
|
212
|
+
try {
|
|
213
|
+
return (await response.json());
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
const message = Predicate.isObject(payload) && typeof payload.message === "string"
|
|
220
|
+
? payload.message
|
|
221
|
+
: `API returned ${response.status}.`;
|
|
222
|
+
return yield* new ApiHttpError({ message, status: response.status });
|
|
223
|
+
});
|
|
117
224
|
}
|
|
118
|
-
function
|
|
119
|
-
return
|
|
225
|
+
function getExportFile(fetchImpl, baseUrl, apiKey, exportId, tableName) {
|
|
226
|
+
return Effect.gen(function* () {
|
|
227
|
+
const redirect = yield* Effect.tryPromise({
|
|
228
|
+
try: (signal) => fetchImpl(`${baseUrl}/v1/exports/${encodeURIComponent(exportId)}/files/${encodeURIComponent(tableName)}`, {
|
|
229
|
+
headers: { Accept: "application/json", Authorization: `Bearer ${apiKey}` },
|
|
230
|
+
redirect: "manual",
|
|
231
|
+
signal,
|
|
232
|
+
}),
|
|
233
|
+
catch: (cause) => new ApiTransportError({ message: cause instanceof Error ? cause.message : String(cause) }),
|
|
234
|
+
});
|
|
235
|
+
if (redirect.status >= 400)
|
|
236
|
+
return yield* httpError(redirect);
|
|
237
|
+
const location = redirect.headers.get("location");
|
|
238
|
+
if (!location)
|
|
239
|
+
return yield* new ApiDecodeError({ message: "API returned a redirect without a location." });
|
|
240
|
+
const response = yield* Effect.tryPromise({
|
|
241
|
+
try: (signal) => fetchImpl(location, { headers: { Accept: "*/*" }, signal }),
|
|
242
|
+
catch: (cause) => new ApiTransportError({ message: cause instanceof Error ? cause.message : String(cause) }),
|
|
243
|
+
});
|
|
244
|
+
if (!response.ok)
|
|
245
|
+
return yield* httpError(response);
|
|
246
|
+
return response;
|
|
247
|
+
});
|
|
120
248
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Command } from "@oclif/core";
|
|
2
|
+
import type { Effect } from "effect";
|
|
3
|
+
import { PrismantixApiClient } from "./api.js";
|
|
4
|
+
export declare const apiFlags: {
|
|
5
|
+
"api-base": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
export declare const runApiEffect: <A, E>(effect: Effect.Effect<A, E, PrismantixApiClient>, apiBaseUrl?: string) => Promise<A>;
|
|
9
|
+
export declare function printResult(command: Command, result: unknown, json: boolean, printHuman: () => void): void;
|
|
10
|
+
export declare function failCommand(command: Command, error: unknown, json: boolean): never;
|
|
11
|
+
export declare function requireValue(value: string | undefined, flagName: string): string;
|
|
12
|
+
export declare function validatePositiveInteger(value: number | undefined, flagName: string): void;
|
|
13
|
+
//# sourceMappingURL=command-support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-support.d.ts","sourceRoot":"","sources":["../src/command-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAgC,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAI7E,eAAO,MAAM,QAAQ;;;CAQpB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,CAAC,EAChC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,mBAAmB,CAAC,EAChD,aAAa,MAAM,eACmD,CAAC;AAExE,wBAAgB,WAAW,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,IAAI,QAOtB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK,CASlF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,UAIvE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,QAGlF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { makePrismantixApiClientLayer } from "./api.js";
|
|
3
|
+
import { CliUserError, toCliUserError } from "./errors.js";
|
|
4
|
+
import { runCliEffect } from "./runtime.js";
|
|
5
|
+
export const apiFlags = {
|
|
6
|
+
"api-base": Flags.string({
|
|
7
|
+
description: "PrismantiX API base URL.",
|
|
8
|
+
env: "PRISMANTIX_API_BASE",
|
|
9
|
+
}),
|
|
10
|
+
json: Flags.boolean({
|
|
11
|
+
description: "Print one machine-readable JSON result to stdout.",
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
export const runApiEffect = (effect, apiBaseUrl) => runCliEffect(effect, makePrismantixApiClientLayer({ apiBaseUrl }));
|
|
15
|
+
export function printResult(command, result, json, printHuman) {
|
|
16
|
+
if (json) {
|
|
17
|
+
command.log(JSON.stringify(result, null, 2));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
printHuman();
|
|
21
|
+
}
|
|
22
|
+
export function failCommand(command, error, json) {
|
|
23
|
+
const userError = toCliUserError(error);
|
|
24
|
+
if (json) {
|
|
25
|
+
command.logToStderr(JSON.stringify({ code: userError.code, error: userError.message, ok: false }));
|
|
26
|
+
command.exit(userError.exitCode);
|
|
27
|
+
}
|
|
28
|
+
command.error(userError.message, { code: userError.code, exit: userError.exitCode });
|
|
29
|
+
}
|
|
30
|
+
export function requireValue(value, flagName) {
|
|
31
|
+
const normalized = value?.trim();
|
|
32
|
+
if (normalized)
|
|
33
|
+
return normalized;
|
|
34
|
+
throw new CliUserError("invalid_argument", `${flagName} is required.`);
|
|
35
|
+
}
|
|
36
|
+
export function validatePositiveInteger(value, flagName) {
|
|
37
|
+
if (value !== undefined && Number.isInteger(value) && value > 0)
|
|
38
|
+
return;
|
|
39
|
+
throw new CliUserError("invalid_argument", `${flagName} must be a positive integer.`);
|
|
40
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class ObjectDetails extends Command {
|
|
3
|
+
static args: {
|
|
4
|
+
objectSlug: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static flags: {
|
|
8
|
+
"api-base": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=details.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"details.d.ts","sourceRoot":"","sources":["../../../src/commands/object/details.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAE,MAAM,aAAa,CAAC;AAW5C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IACjD,OAAgB,IAAI;;MAAmD;IACvE,OAAgB,WAAW,SAA2D;IACtF,OAAgB,KAAK;;;MAAY;IAEpB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAqBjC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Args, Command } from "@oclif/core";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { PrismantixApiClient } from "../../api.js";
|
|
4
|
+
import { apiFlags, failCommand, printResult, requireValue, runApiEffect, } from "../../command-support.js";
|
|
5
|
+
export default class ObjectDetails extends Command {
|
|
6
|
+
static args = { objectSlug: Args.string({ required: true }) };
|
|
7
|
+
static description = "Show the authored public details for one object slug.";
|
|
8
|
+
static flags = apiFlags;
|
|
9
|
+
async run() {
|
|
10
|
+
const { args, flags } = await this.parse(ObjectDetails);
|
|
11
|
+
try {
|
|
12
|
+
const objectSlug = requireValue(args.objectSlug, "objectSlug");
|
|
13
|
+
const result = await runApiEffect(Effect.gen(function* () {
|
|
14
|
+
const api = yield* PrismantixApiClient;
|
|
15
|
+
return yield* api.getOntologyObject(objectSlug);
|
|
16
|
+
}), flags["api-base"]);
|
|
17
|
+
printResult(this, result, flags.json, () => {
|
|
18
|
+
this.log(`${result.displayName} (${result.slug})`);
|
|
19
|
+
this.log(result.description);
|
|
20
|
+
this.log(`Owning ontology: ${result.owningOntologyId}`);
|
|
21
|
+
this.log(`Fields: ${result.fields.length}`);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
failCommand(this, error, flags.json);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class ObjectList extends Command {
|
|
3
|
+
static args: {
|
|
4
|
+
ontologyId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static flags: {
|
|
8
|
+
"api-base": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/object/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAE,MAAM,aAAa,CAAC;AAW5C,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC9C,OAAgB,IAAI;;MAAmD;IACvE,OAAgB,WAAW,SAA6D;IACxF,OAAgB,KAAK;;;MAAY;IAEpB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoBjC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Args, Command } from "@oclif/core";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { PrismantixApiClient } from "../../api.js";
|
|
4
|
+
import { apiFlags, failCommand, printResult, requireValue, runApiEffect, } from "../../command-support.js";
|
|
5
|
+
export default class ObjectList extends Command {
|
|
6
|
+
static args = { ontologyId: Args.string({ required: true }) };
|
|
7
|
+
static description = "List the complete effective object set for an ontology.";
|
|
8
|
+
static flags = apiFlags;
|
|
9
|
+
async run() {
|
|
10
|
+
const { args, flags } = await this.parse(ObjectList);
|
|
11
|
+
try {
|
|
12
|
+
const ontologyId = requireValue(args.ontologyId, "ontologyId");
|
|
13
|
+
const result = await runApiEffect(Effect.gen(function* () {
|
|
14
|
+
const api = yield* PrismantixApiClient;
|
|
15
|
+
return yield* api.listOntologyObjects(ontologyId);
|
|
16
|
+
}), flags["api-base"]);
|
|
17
|
+
printResult(this, result, flags.json, () => {
|
|
18
|
+
for (const object of result) {
|
|
19
|
+
this.log(`${object.slug}\t${object.displayName}\t${object.owningOntologyId}`);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
failCommand(this, error, flags.json);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class OntologyList extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
"api-base": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/ontology/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAKtC,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAChD,OAAgB,WAAW,SAAgD;IAC3E,OAAgB,KAAK;;;MAAY;IAEpB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBjC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { PrismantixApiClient } from "../../api.js";
|
|
4
|
+
import { apiFlags, failCommand, printResult, runApiEffect } from "../../command-support.js";
|
|
5
|
+
export default class OntologyList extends Command {
|
|
6
|
+
static description = "List every registered PrismantiX ontology.";
|
|
7
|
+
static flags = apiFlags;
|
|
8
|
+
async run() {
|
|
9
|
+
const { flags } = await this.parse(OntologyList);
|
|
10
|
+
try {
|
|
11
|
+
const result = await runApiEffect(Effect.gen(function* () {
|
|
12
|
+
const api = yield* PrismantixApiClient;
|
|
13
|
+
return yield* api.listOntologies();
|
|
14
|
+
}), flags["api-base"]);
|
|
15
|
+
printResult(this, result, flags.json, () => {
|
|
16
|
+
for (const ontology of result) {
|
|
17
|
+
this.log(`${ontology.id}\t${ontology.displayName}\t${ontology.objectCount} objects`);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
failCommand(this, error, flags.json);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class RecordsCancel extends Command {
|
|
3
|
+
static args: {
|
|
4
|
+
operationId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static flags: {
|
|
8
|
+
"api-base": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=cancel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cancel.d.ts","sourceRoot":"","sources":["../../../src/commands/records/cancel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAE,MAAM,aAAa,CAAC;AAU5C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IACjD,OAAgB,IAAI;;MAAoD;IACxE,OAAgB,WAAW,SAAuD;IAClF,OAAgB,KAAK;;;MAAY;IAEpB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAYjC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Args, Command } from "@oclif/core";
|
|
2
|
+
import { apiFlags, failCommand, printResult, requireValue, runApiEffect, } from "../../command-support.js";
|
|
3
|
+
import { cancelRecordGeneration } from "../../generation.js";
|
|
4
|
+
export default class RecordsCancel extends Command {
|
|
5
|
+
static args = { operationId: Args.string({ required: true }) };
|
|
6
|
+
static description = "Best-effort cancel a record-generation operation.";
|
|
7
|
+
static flags = apiFlags;
|
|
8
|
+
async run() {
|
|
9
|
+
const { args, flags } = await this.parse(RecordsCancel);
|
|
10
|
+
try {
|
|
11
|
+
const operationId = requireValue(args.operationId, "operation-id");
|
|
12
|
+
const result = await runApiEffect(cancelRecordGeneration(operationId), flags["api-base"]);
|
|
13
|
+
printResult(this, result, flags.json, () => {
|
|
14
|
+
this.log(`Record generation ${result.operationId}: ${result.status}`);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
failCommand(this, error, flags.json);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class RecordsGenerate extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
client: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
+
ontology: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
"poll-interval": import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
timeout: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
wait: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
"api-base": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/commands/records/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAa7C,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IACnD,OAAgB,WAAW,SAAuE;IAClG,OAAgB,KAAK;;;;;;;;MAiBnB;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA8BjC"}
|