@oleanderhq/sdk 0.2.1 → 0.2.2

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.cjs CHANGED
@@ -64,6 +64,19 @@ var lakeQueryResultSchema = import_zod.z.object({
64
64
  details: import_zod.z.string().optional(),
65
65
  query: import_zod.z.string().optional()
66
66
  });
67
+ var getSparkClusterOptionsSchema = import_zod.z.object({
68
+ name: import_zod.z.string()
69
+ });
70
+ var sparkClusterTypeSchema = import_zod.z.enum([
71
+ "oleander",
72
+ "emr-serverless",
73
+ "glue"
74
+ ]);
75
+ var getSparkClusterResultSchema = import_zod.z.object({
76
+ name: import_zod.z.string(),
77
+ type: sparkClusterTypeSchema,
78
+ properties: import_zod.z.any()
79
+ });
67
80
  var sparkJobListPageSchema = import_zod.z.object({
68
81
  scripts: import_zod.z.array(import_zod.z.string()),
69
82
  continuationToken: import_zod.z.string().optional()
@@ -76,11 +89,6 @@ var listSparkJobsResultSchema = import_zod.z.object({
76
89
  scripts: import_zod.z.array(import_zod.z.string()),
77
90
  hasMore: import_zod.z.boolean()
78
91
  });
79
- var sparkClusterTypeSchema = import_zod.z.enum([
80
- "oleander",
81
- "emr-serverless",
82
- "glue"
83
- ]);
84
92
  var sparkMachineTypeSchema = import_zod.z.enum([
85
93
  "spark.1.c",
86
94
  "spark.2.c",
@@ -106,7 +114,7 @@ var glueWorkerTypeSchema = import_zod.z.enum([
106
114
  "G.025X"
107
115
  ]);
108
116
  var submitOptionsSchema = import_zod.z.object({
109
- cluster: sparkClusterTypeSchema.default("oleander"),
117
+ cluster: import_zod.z.string().default("oleander"),
110
118
  namespace: import_zod.z.string().min(1, "namespace is required"),
111
119
  name: import_zod.z.string().min(1, "name is required"),
112
120
  args: import_zod.z.array(import_zod.z.string()).default([]),
@@ -177,6 +185,18 @@ function parseErrorBody(body, status) {
177
185
  }
178
186
  return `HTTP ${status}`;
179
187
  }
188
+ function buildGlueArguments(args) {
189
+ const result = {};
190
+ for (let i = 0; i < args.length; i += 2) {
191
+ const key = args[i];
192
+ const value = args[i + 1];
193
+ if (value === void 0) {
194
+ throw new Error(`Missing value for argument: ${key}`);
195
+ }
196
+ result[key] = value;
197
+ }
198
+ return result;
199
+ }
180
200
  var Oleander = class {
181
201
  constructor(options = {}) {
182
202
  const parsed = optionsSchema.safeParse(options);
@@ -222,6 +242,31 @@ var Oleander = class {
222
242
  }
223
243
  return result;
224
244
  }
245
+ /**
246
+ * Get spark cluster information
247
+ */
248
+ async getSparkCluster(options) {
249
+ const opts = getSparkClusterOptionsSchema.parse(options);
250
+ if (opts.name === "oleander") {
251
+ return {
252
+ name: "oleander",
253
+ type: "oleander",
254
+ properties: {}
255
+ };
256
+ }
257
+ const res = await fetch(
258
+ `${this.baseUrl}/api/v2/spark/clusters/${opts.name}`,
259
+ {
260
+ method: "GET",
261
+ headers: { Authorization: `Bearer ${this.apiKey}` }
262
+ }
263
+ );
264
+ const raw = await res.json().catch(() => ({}));
265
+ if (!res.ok) {
266
+ throw new Error(parseErrorBody(raw, res.status));
267
+ }
268
+ return getSparkClusterResultSchema.parse(raw);
269
+ }
225
270
  /**
226
271
  * List spark jobs (mirrors `oleander spark jobs list`).
227
272
  * Uses limit/offset pagination; pages through the API internally.
@@ -258,20 +303,9 @@ var Oleander = class {
258
303
  */
259
304
  async submitSparkJob(options) {
260
305
  const opts = submitOptionsSchema.parse(options);
261
- const buildGlueArguments = (args) => {
262
- const result = {};
263
- for (let i = 0; i < args.length; i += 2) {
264
- const key = args[i];
265
- const value = args[i + 1];
266
- if (value === void 0) {
267
- throw new Error(`Missing value for argument: ${key}`);
268
- }
269
- result[key] = value;
270
- }
271
- return result;
272
- };
306
+ const cluster = await this.getSparkCluster({ name: opts.cluster });
273
307
  let properties;
274
- if (opts.cluster === "oleander") {
308
+ if (cluster.type === "oleander") {
275
309
  properties = {
276
310
  entrypoint: opts.entrypoint,
277
311
  entrypointArguments: opts.args,
@@ -281,7 +315,7 @@ var Oleander = class {
281
315
  sparkConf: opts.sparkConf,
282
316
  packages: opts.packages
283
317
  };
284
- } else if (opts.cluster === "emr-serverless") {
318
+ } else if (cluster.type === "emr-serverless") {
285
319
  properties = {
286
320
  entrypoint: opts.entrypoint,
287
321
  entrypointArguments: opts.args,
@@ -291,7 +325,7 @@ var Oleander = class {
291
325
  packages: opts.packages,
292
326
  executionIamPolicy: opts.executionIamPolicy
293
327
  };
294
- } else if (opts.cluster === "glue") {
328
+ } else if (cluster.type === "glue") {
295
329
  properties = {
296
330
  jobName: opts.entrypoint,
297
331
  entrypointArguments: buildGlueArguments(opts.args),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/schemas.ts","../src/client.ts"],"sourcesContent":["export { Oleander } from \"./client.js\";\nexport type { OleanderOptions } from \"./schemas.js\";\nexport type {\n QueryOptions,\n LakeQueryResult,\n ApiErrorBody,\n SparkJobListPage,\n ListSparkJobsOptions,\n ListSparkJobsResult,\n SparkMachineType,\n SparkJobSubmitOptions,\n SubmitSparkJobAndWaitOptions,\n SparkJobRun,\n RunResponse,\n RunState,\n} from \"./schemas.js\";\nexport {\n optionsSchema,\n queryOptionsSchema,\n lakeQueryResultSchema,\n sparkJobListPageSchema,\n listSparkJobsOptionsSchema,\n listSparkJobsResultSchema,\n sparkMachineTypeSchema,\n submitOptionsSchema,\n submitSparkJobAndWaitOptionsSchema,\n sparkJobRunSchema,\n runResponseSchema,\n apiErrorBodySchema,\n} from \"./schemas.js\";\n","import { z } from \"zod\";\n\n/** API error response body */\nexport const apiErrorBodySchema = z.object({\n error: z.string().optional(),\n details: z.string().optional(),\n});\n\nexport type ApiErrorBody = z.infer<typeof apiErrorBodySchema>;\n\nconst DEFAULT_BASE_URL = \"https://oleander.dev\";\n\n/** Constructor options. apiKey can be omitted if OLEANDER_API_KEY env is set. */\nexport const optionsSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z\n .string()\n .default(DEFAULT_BASE_URL)\n .transform((v) => (v.trim() ? v.trim() : DEFAULT_BASE_URL)),\n});\n\nexport type OleanderOptions = z.input<typeof optionsSchema>;\n\n/** Lake query options */\nexport const queryOptionsSchema = z.object({\n save: z.boolean().default(false),\n});\n\nexport type QueryOptions = z.input<typeof queryOptionsSchema>;\n\n/** Lake query result (API response) */\nexport const lakeQueryResultSchema = z.object({\n success: z.boolean(),\n results: z\n .object({\n columns: z.array(z.string()),\n column_types: z.array(z.string()),\n rows: z.array(z.array(z.unknown())),\n })\n .optional(),\n row_count: z.number().optional(),\n execution_time: z.string().optional(),\n saved_table_name: z.string().optional(),\n error: z.string().optional(),\n details: z.string().optional(),\n query: z.string().optional(),\n});\n\nexport type LakeQueryResult = z.infer<typeof lakeQueryResultSchema>;\n\n/** API response for one page of spark scripts (S3-style) */\nexport const sparkJobListPageSchema = z.object({\n scripts: z.array(z.string()),\n continuationToken: z.string().optional(),\n});\n\nexport type SparkJobListPage = z.infer<typeof sparkJobListPageSchema>;\n\n/** Options for listSparkJobs (limit/offset pagination) */\nexport const listSparkJobsOptionsSchema = z.object({\n limit: z.number().int().positive().default(20),\n offset: z.number().int().nonnegative().default(0),\n});\n\nexport type ListSparkJobsOptions = z.input<typeof listSparkJobsOptionsSchema>;\n\n/** Result of listSparkJobs with limit/offset */\nexport const listSparkJobsResultSchema = z.object({\n scripts: z.array(z.string()),\n hasMore: z.boolean(),\n});\n\nexport type ListSparkJobsResult = z.infer<typeof listSparkJobsResultSchema>;\n\n/** Spark cluster type enum */\nexport const sparkClusterTypeSchema = z.enum([\n \"oleander\",\n \"emr-serverless\",\n \"glue\",\n]);\n\n/** Spark machine type enum */\nexport const sparkMachineTypeSchema = z.enum([\n \"spark.1.c\",\n \"spark.2.c\",\n \"spark.4.c\",\n \"spark.8.c\",\n \"spark.16.c\",\n \"spark.1.b\",\n \"spark.2.b\",\n \"spark.4.b\",\n \"spark.8.b\",\n \"spark.16.b\",\n \"spark.1.m\",\n \"spark.2.m\",\n \"spark.4.m\",\n \"spark.8.m\",\n \"spark.16.m\",\n]);\n\n/** Glue worker type enum */\nexport const glueWorkerTypeSchema = z.enum([\n \"G.1X\",\n \"G.2X\",\n \"G.4X\",\n \"G.8X\",\n \"G.025X\",\n]);\n\nexport type SparkMachineType = z.infer<typeof sparkMachineTypeSchema>;\n\n/** Spark job submit options. Optional fields have defaults. */\nexport const submitOptionsSchema = z.object({\n cluster: sparkClusterTypeSchema.default(\"oleander\"),\n namespace: z.string().min(1, \"namespace is required\"),\n name: z.string().min(1, \"name is required\"),\n args: z.array(z.string()).default([]),\n entrypoint: z.string().min(1, \"entrypoint is required\"),\n pyFiles: z.string().optional(),\n mainClass: z.string().optional(),\n sparkConf: z.array(z.string()).default([]),\n packages: z.array(z.string()).default([]),\n executionIamPolicy: z.string().optional(),\n jobTags: z.array(z.string()).default([]),\n runTags: z.array(z.string()).default([]),\n driverMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorNumbers: z.number().int().min(1).max(20).default(2),\n workerType: glueWorkerTypeSchema.optional(),\n numberOfWorkers: z.number().int().min(1).default(1),\n enableAutoScaling: z.boolean().optional(),\n timeoutMinutes: z.number().int().optional(),\n executionClass: z.string().optional(),\n});\n\nexport type SparkJobSubmitOptions = z.input<typeof submitOptionsSchema>;\n\n/** Options for submitSparkJobAndWait (submit options + optional wait tuning) */\nexport const submitSparkJobAndWaitOptionsSchema = submitOptionsSchema.extend({\n pollIntervalMs: z.number().int().positive().default(10000),\n timeoutMs: z.number().int().positive().default(600000),\n});\n\nexport type SubmitSparkJobAndWaitOptions = z.input<\n typeof submitSparkJobAndWaitOptionsSchema\n>;\n\n/** Spark job submit response */\nexport const sparkJobRunSchema = z.object({\n runId: z.string(),\n});\n\nexport type SparkJobRun = z.infer<typeof sparkJobRunSchema>;\n\n/** Run status (for polling) */\nexport const runResponseSchema = z.object({\n id: z.string(),\n state: z.string().nullable(),\n started_at: z.string().nullable().optional(),\n queued_at: z.string().nullable().optional(),\n scheduled_at: z.string().nullable().optional(),\n ended_at: z.string().nullable().optional(),\n duration: z.number().nullable().optional(),\n error: z.unknown().nullable().optional(),\n tags: z.array(\n z.object({\n key: z.string(),\n value: z.string(),\n source: z.string().nullable().optional(),\n }),\n ),\n job: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n pipeline: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n});\n\nexport type RunResponse = z.infer<typeof runResponseSchema>;\n\nexport type RunState = \"COMPLETE\" | \"FAIL\" | \"ABORT\" | string;\n","import {\n optionsSchema,\n queryOptionsSchema,\n lakeQueryResultSchema,\n sparkJobListPageSchema,\n listSparkJobsOptionsSchema,\n submitOptionsSchema,\n submitSparkJobAndWaitOptionsSchema,\n sparkJobRunSchema,\n runResponseSchema,\n apiErrorBodySchema,\n} from \"./schemas.js\";\nimport type {\n OleanderOptions,\n QueryOptions,\n LakeQueryResult,\n ListSparkJobsOptions,\n ListSparkJobsResult,\n SparkJobSubmitOptions,\n SubmitSparkJobAndWaitOptions,\n SparkJobRun,\n RunResponse,\n RunState,\n} from \"./schemas.js\";\n\nfunction getHeaders(apiKey: string): Record<string, string> {\n return {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nfunction parseErrorBody(body: unknown, status: number): string {\n const parsed = apiErrorBodySchema.safeParse(body);\n if (parsed.success) {\n const { error, details } = parsed.data;\n return error || details || `HTTP ${status}`;\n }\n return `HTTP ${status}`;\n}\n\n/**\n * oleander API. Mirrors the CLI for query, list spark jobs, and launch spark jobs.\n */\nexport class Oleander {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(options: OleanderOptions = {}) {\n const parsed = optionsSchema.safeParse(options);\n if (!parsed.success) {\n const first =\n parsed.error.flatten().formErrors[0] ?? parsed.error.message;\n throw new Error(first);\n }\n const fromOptions = parsed.data.apiKey?.trim();\n const fromEnv =\n typeof process !== \"undefined\" && process.env?.OLEANDER_API_KEY;\n const apiKey = fromOptions ?? fromEnv ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"Oleander requires a non-empty apiKey (or set OLEANDER_API_KEY)\",\n );\n }\n this.apiKey = apiKey;\n this.baseUrl = parsed.data.baseUrl.trim().replace(/\\/$/, \"\");\n }\n\n /**\n * Execute a lake query (mirrors `oleander query`).\n */\n async query(\n sql: string,\n options: QueryOptions = {},\n ): Promise<LakeQueryResult> {\n const query = typeof sql === \"string\" ? sql.trim() : \"\";\n if (!query) {\n throw new Error(\"Query is required\");\n }\n const opts = queryOptionsSchema.parse(options);\n\n const res = await fetch(`${this.baseUrl}/api/v1/warehouse/query`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n query,\n autoSaveByHash: opts.save,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n\n const result = lakeQueryResultSchema.parse(raw);\n if (!result.success && result.error) {\n throw new Error(result.details || result.error);\n }\n return result;\n }\n\n /**\n * List spark jobs (mirrors `oleander spark jobs list`).\n * Uses limit/offset pagination; pages through the API internally.\n */\n async listSparkJobs(\n options: ListSparkJobsOptions = {},\n ): Promise<ListSparkJobsResult> {\n const opts = listSparkJobsOptionsSchema.parse(options);\n const { limit, offset } = opts;\n\n const allScripts: string[] = [];\n let continuationToken: string | undefined;\n\n while (true) {\n const params = continuationToken\n ? `?${new URLSearchParams({ continuationToken }).toString()}`\n : \"\";\n const res = await fetch(`${this.baseUrl}/api/v1/spark/scripts${params}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n const page = sparkJobListPageSchema.parse(raw);\n allScripts.push(...page.scripts);\n continuationToken = page.continuationToken;\n if (!continuationToken || allScripts.length >= offset + limit) {\n break;\n }\n }\n\n const scripts = allScripts.slice(offset, offset + limit);\n const hasMore = !!continuationToken || allScripts.length > offset + limit;\n return { scripts, hasMore };\n }\n\n /**\n * Submit a spark job (mirrors `oleander spark jobs submit`).\n * Returns the run ID; use getRun() or submitSparkJobAndWait() to poll status.\n */\n async submitSparkJob(options: SparkJobSubmitOptions): Promise<SparkJobRun> {\n const opts = submitOptionsSchema.parse(options);\n\n const buildGlueArguments = (args: string[]): Record<string, string> => {\n const result: Record<string, string> = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const value = args[i + 1];\n if (value === undefined) {\n throw new Error(`Missing value for argument: ${key}`);\n }\n result[key] = value;\n }\n return result;\n };\n\n let properties: any;\n if (opts.cluster === \"oleander\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n driverMachineType: opts.driverMachineType,\n executorMachineType: opts.executorMachineType,\n executorNumbers: opts.executorNumbers,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n };\n } else if (opts.cluster === \"emr-serverless\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n pyFiles: opts.pyFiles,\n mainClass: opts.mainClass,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n executionIamPolicy: opts.executionIamPolicy,\n };\n } else if (opts.cluster === \"glue\") {\n properties = {\n jobName: opts.entrypoint,\n entrypointArguments: buildGlueArguments(opts.args),\n sparkConf: opts.sparkConf,\n workerType: opts.workerType,\n numberOfWorkers: opts.numberOfWorkers,\n enableAutoScaling: opts.enableAutoScaling,\n timeoutMinutes: opts.timeoutMinutes,\n executionClass: opts.executionClass,\n executionRoleSessionPolicy: opts.executionIamPolicy,\n };\n }\n\n const res = await fetch(`${this.baseUrl}/api/v2/spark/jobs`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n cluster: opts.cluster,\n namespace: opts.namespace.trim(),\n name: opts.name.trim(),\n jobTags: opts.jobTags,\n runTags: opts.runTags,\n properties: properties,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return sparkJobRunSchema.parse(raw);\n }\n\n /**\n * Get run status (used for polling after submit).\n */\n async getRun(runId: string): Promise<RunResponse> {\n if (!runId || typeof runId !== \"string\" || !runId.trim()) {\n throw new Error(\"runId is required\");\n }\n const res = await fetch(`${this.baseUrl}/api/v2/runs/${runId}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return runResponseSchema.parse(raw);\n }\n\n /**\n * Submit a spark job and wait until the run reaches a terminal state (COMPLETE, FAIL, ABORT).\n */\n async submitSparkJobAndWait(\n options: SubmitSparkJobAndWaitOptions,\n ): Promise<{ runId: string; state: RunState; run: RunResponse }> {\n const opts = submitSparkJobAndWaitOptionsSchema.parse(options);\n const { pollIntervalMs, timeoutMs, ...submitOpts } = opts;\n const { runId } = await this.submitSparkJob(submitOpts);\n const started = Date.now();\n\n while (Date.now() - started < timeoutMs) {\n const run = await this.getRun(runId);\n const state = run.state ?? \"\";\n if (state === \"COMPLETE\" || state === \"FAIL\" || state === \"ABORT\") {\n return { runId, state, run };\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n const run = await this.getRun(runId);\n throw new Error(\n `Timeout waiting for run ${runId} (state: ${run.state ?? \"unknown\"})`,\n );\n }\n}\n"],"mappings":"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","names":["run"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/schemas.ts","../src/client.ts"],"sourcesContent":["export { Oleander } from \"./client.js\";\nexport type { OleanderOptions } from \"./schemas.js\";\nexport type {\n QueryOptions,\n LakeQueryResult,\n ApiErrorBody,\n SparkJobListPage,\n ListSparkJobsOptions,\n ListSparkJobsResult,\n SparkMachineType,\n SparkJobSubmitOptions,\n SubmitSparkJobAndWaitOptions,\n SparkJobRun,\n RunResponse,\n RunState,\n} from \"./schemas.js\";\nexport {\n optionsSchema,\n queryOptionsSchema,\n lakeQueryResultSchema,\n sparkJobListPageSchema,\n listSparkJobsOptionsSchema,\n listSparkJobsResultSchema,\n sparkMachineTypeSchema,\n submitOptionsSchema,\n submitSparkJobAndWaitOptionsSchema,\n sparkJobRunSchema,\n runResponseSchema,\n apiErrorBodySchema,\n} from \"./schemas.js\";\n","import { z } from \"zod\";\n\n/** API error response body */\nexport const apiErrorBodySchema = z.object({\n error: z.string().optional(),\n details: z.string().optional(),\n});\n\nexport type ApiErrorBody = z.infer<typeof apiErrorBodySchema>;\n\nconst DEFAULT_BASE_URL = \"https://oleander.dev\";\n\n/** Constructor options. apiKey can be omitted if OLEANDER_API_KEY env is set. */\nexport const optionsSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z\n .string()\n .default(DEFAULT_BASE_URL)\n .transform((v) => (v.trim() ? v.trim() : DEFAULT_BASE_URL)),\n});\n\nexport type OleanderOptions = z.input<typeof optionsSchema>;\n\n/** Lake query options */\nexport const queryOptionsSchema = z.object({\n save: z.boolean().default(false),\n});\n\nexport type QueryOptions = z.input<typeof queryOptionsSchema>;\n\n/** Lake query result (API response) */\nexport const lakeQueryResultSchema = z.object({\n success: z.boolean(),\n results: z\n .object({\n columns: z.array(z.string()),\n column_types: z.array(z.string()),\n rows: z.array(z.array(z.unknown())),\n })\n .optional(),\n row_count: z.number().optional(),\n execution_time: z.string().optional(),\n saved_table_name: z.string().optional(),\n error: z.string().optional(),\n details: z.string().optional(),\n query: z.string().optional(),\n});\n\nexport type LakeQueryResult = z.infer<typeof lakeQueryResultSchema>;\n\nexport const getSparkClusterOptionsSchema = z.object({\n name: z.string(),\n});\n\nexport type GetSparkClusterOptions = z.input<\n typeof getSparkClusterOptionsSchema\n>;\n\nexport const sparkClusterTypeSchema = z.enum([\n \"oleander\",\n \"emr-serverless\",\n \"glue\",\n]);\n\nexport const getSparkClusterResultSchema = z.object({\n name: z.string(),\n type: sparkClusterTypeSchema,\n properties: z.any(),\n});\n\nexport type SparkCluster = z.infer<typeof getSparkClusterResultSchema>;\n\n/** API response for one page of spark scripts (S3-style) */\nexport const sparkJobListPageSchema = z.object({\n scripts: z.array(z.string()),\n continuationToken: z.string().optional(),\n});\n\nexport type SparkJobListPage = z.infer<typeof sparkJobListPageSchema>;\n\n/** Options for listSparkJobs (limit/offset pagination) */\nexport const listSparkJobsOptionsSchema = z.object({\n limit: z.number().int().positive().default(20),\n offset: z.number().int().nonnegative().default(0),\n});\n\nexport type ListSparkJobsOptions = z.input<typeof listSparkJobsOptionsSchema>;\n\n/** Result of listSparkJobs with limit/offset */\nexport const listSparkJobsResultSchema = z.object({\n scripts: z.array(z.string()),\n hasMore: z.boolean(),\n});\n\nexport type ListSparkJobsResult = z.infer<typeof listSparkJobsResultSchema>;\n\n/** Spark machine type enum */\nexport const sparkMachineTypeSchema = z.enum([\n \"spark.1.c\",\n \"spark.2.c\",\n \"spark.4.c\",\n \"spark.8.c\",\n \"spark.16.c\",\n \"spark.1.b\",\n \"spark.2.b\",\n \"spark.4.b\",\n \"spark.8.b\",\n \"spark.16.b\",\n \"spark.1.m\",\n \"spark.2.m\",\n \"spark.4.m\",\n \"spark.8.m\",\n \"spark.16.m\",\n]);\n\n/** Glue worker type enum */\nexport const glueWorkerTypeSchema = z.enum([\n \"G.1X\",\n \"G.2X\",\n \"G.4X\",\n \"G.8X\",\n \"G.025X\",\n]);\n\nexport type SparkMachineType = z.infer<typeof sparkMachineTypeSchema>;\n\n/** Spark job submit options. Optional fields have defaults. */\nexport const submitOptionsSchema = z.object({\n cluster: z.string().default(\"oleander\"),\n namespace: z.string().min(1, \"namespace is required\"),\n name: z.string().min(1, \"name is required\"),\n args: z.array(z.string()).default([]),\n entrypoint: z.string().min(1, \"entrypoint is required\"),\n pyFiles: z.string().optional(),\n mainClass: z.string().optional(),\n sparkConf: z.array(z.string()).default([]),\n packages: z.array(z.string()).default([]),\n executionIamPolicy: z.string().optional(),\n jobTags: z.array(z.string()).default([]),\n runTags: z.array(z.string()).default([]),\n driverMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorNumbers: z.number().int().min(1).max(20).default(2),\n workerType: glueWorkerTypeSchema.optional(),\n numberOfWorkers: z.number().int().min(1).default(1),\n enableAutoScaling: z.boolean().optional(),\n timeoutMinutes: z.number().int().optional(),\n executionClass: z.string().optional(),\n});\n\nexport type SparkJobSubmitOptions = z.input<typeof submitOptionsSchema>;\n\n/** Options for submitSparkJobAndWait (submit options + optional wait tuning) */\nexport const submitSparkJobAndWaitOptionsSchema = submitOptionsSchema.extend({\n pollIntervalMs: z.number().int().positive().default(10000),\n timeoutMs: z.number().int().positive().default(600000),\n});\n\nexport type SubmitSparkJobAndWaitOptions = z.input<\n typeof submitSparkJobAndWaitOptionsSchema\n>;\n\n/** Spark job submit response */\nexport const sparkJobRunSchema = z.object({\n runId: z.string(),\n});\n\nexport type SparkJobRun = z.infer<typeof sparkJobRunSchema>;\n\n/** Run status (for polling) */\nexport const runResponseSchema = z.object({\n id: z.string(),\n state: z.string().nullable(),\n started_at: z.string().nullable().optional(),\n queued_at: z.string().nullable().optional(),\n scheduled_at: z.string().nullable().optional(),\n ended_at: z.string().nullable().optional(),\n duration: z.number().nullable().optional(),\n error: z.unknown().nullable().optional(),\n tags: z.array(\n z.object({\n key: z.string(),\n value: z.string(),\n source: z.string().nullable().optional(),\n }),\n ),\n job: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n pipeline: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n});\n\nexport type RunResponse = z.infer<typeof runResponseSchema>;\n\nexport type RunState = \"COMPLETE\" | \"FAIL\" | \"ABORT\" | string;\n","import {\n optionsSchema,\n queryOptionsSchema,\n lakeQueryResultSchema,\n sparkJobListPageSchema,\n listSparkJobsOptionsSchema,\n submitOptionsSchema,\n submitSparkJobAndWaitOptionsSchema,\n sparkJobRunSchema,\n runResponseSchema,\n apiErrorBodySchema,\n GetSparkClusterOptions,\n SparkCluster,\n getSparkClusterOptionsSchema,\n getSparkClusterResultSchema,\n} from \"./schemas.js\";\nimport type {\n OleanderOptions,\n QueryOptions,\n LakeQueryResult,\n ListSparkJobsOptions,\n ListSparkJobsResult,\n SparkJobSubmitOptions,\n SubmitSparkJobAndWaitOptions,\n SparkJobRun,\n RunResponse,\n RunState,\n} from \"./schemas.js\";\n\nfunction getHeaders(apiKey: string): Record<string, string> {\n return {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nfunction parseErrorBody(body: unknown, status: number): string {\n const parsed = apiErrorBodySchema.safeParse(body);\n if (parsed.success) {\n const { error, details } = parsed.data;\n return error || details || `HTTP ${status}`;\n }\n return `HTTP ${status}`;\n}\n\nfunction buildGlueArguments(args: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const value = args[i + 1];\n if (value === undefined) {\n throw new Error(`Missing value for argument: ${key}`);\n }\n result[key] = value;\n }\n return result;\n}\n\n/**\n * oleander API. Mirrors the CLI for query, list spark jobs, and launch spark jobs.\n */\nexport class Oleander {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(options: OleanderOptions = {}) {\n const parsed = optionsSchema.safeParse(options);\n if (!parsed.success) {\n const first =\n parsed.error.flatten().formErrors[0] ?? parsed.error.message;\n throw new Error(first);\n }\n const fromOptions = parsed.data.apiKey?.trim();\n const fromEnv =\n typeof process !== \"undefined\" && process.env?.OLEANDER_API_KEY;\n const apiKey = fromOptions ?? fromEnv ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"Oleander requires a non-empty apiKey (or set OLEANDER_API_KEY)\",\n );\n }\n this.apiKey = apiKey;\n this.baseUrl = parsed.data.baseUrl.trim().replace(/\\/$/, \"\");\n }\n\n /**\n * Execute a lake query (mirrors `oleander query`).\n */\n async query(\n sql: string,\n options: QueryOptions = {},\n ): Promise<LakeQueryResult> {\n const query = typeof sql === \"string\" ? sql.trim() : \"\";\n if (!query) {\n throw new Error(\"Query is required\");\n }\n const opts = queryOptionsSchema.parse(options);\n\n const res = await fetch(`${this.baseUrl}/api/v1/warehouse/query`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n query,\n autoSaveByHash: opts.save,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n\n const result = lakeQueryResultSchema.parse(raw);\n if (!result.success && result.error) {\n throw new Error(result.details || result.error);\n }\n return result;\n }\n\n /**\n * Get spark cluster information\n */\n async getSparkCluster(\n options: GetSparkClusterOptions,\n ): Promise<SparkCluster> {\n const opts = getSparkClusterOptionsSchema.parse(options);\n\n if (opts.name === \"oleander\") {\n return {\n name: \"oleander\",\n type: \"oleander\",\n properties: {},\n };\n }\n\n const res = await fetch(\n `${this.baseUrl}/api/v2/spark/clusters/${opts.name}`,\n {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n },\n );\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return getSparkClusterResultSchema.parse(raw);\n }\n\n /**\n * List spark jobs (mirrors `oleander spark jobs list`).\n * Uses limit/offset pagination; pages through the API internally.\n */\n async listSparkJobs(\n options: ListSparkJobsOptions = {},\n ): Promise<ListSparkJobsResult> {\n const opts = listSparkJobsOptionsSchema.parse(options);\n const { limit, offset } = opts;\n\n const allScripts: string[] = [];\n let continuationToken: string | undefined;\n\n while (true) {\n const params = continuationToken\n ? `?${new URLSearchParams({ continuationToken }).toString()}`\n : \"\";\n const res = await fetch(`${this.baseUrl}/api/v1/spark/scripts${params}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n const page = sparkJobListPageSchema.parse(raw);\n allScripts.push(...page.scripts);\n continuationToken = page.continuationToken;\n if (!continuationToken || allScripts.length >= offset + limit) {\n break;\n }\n }\n\n const scripts = allScripts.slice(offset, offset + limit);\n const hasMore = !!continuationToken || allScripts.length > offset + limit;\n return { scripts, hasMore };\n }\n\n /**\n * Submit a spark job (mirrors `oleander spark jobs submit`).\n * Returns the run ID; use getRun() or submitSparkJobAndWait() to poll status.\n */\n async submitSparkJob(options: SparkJobSubmitOptions): Promise<SparkJobRun> {\n const opts = submitOptionsSchema.parse(options);\n const cluster = await this.getSparkCluster({ name: opts.cluster });\n\n let properties: any;\n if (cluster.type === \"oleander\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n driverMachineType: opts.driverMachineType,\n executorMachineType: opts.executorMachineType,\n executorNumbers: opts.executorNumbers,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n };\n } else if (cluster.type === \"emr-serverless\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n pyFiles: opts.pyFiles,\n mainClass: opts.mainClass,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n executionIamPolicy: opts.executionIamPolicy,\n };\n } else if (cluster.type === \"glue\") {\n properties = {\n jobName: opts.entrypoint,\n entrypointArguments: buildGlueArguments(opts.args),\n sparkConf: opts.sparkConf,\n workerType: opts.workerType,\n numberOfWorkers: opts.numberOfWorkers,\n enableAutoScaling: opts.enableAutoScaling,\n timeoutMinutes: opts.timeoutMinutes,\n executionClass: opts.executionClass,\n executionRoleSessionPolicy: opts.executionIamPolicy,\n };\n }\n\n const res = await fetch(`${this.baseUrl}/api/v2/spark/jobs`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n cluster: opts.cluster,\n namespace: opts.namespace.trim(),\n name: opts.name.trim(),\n jobTags: opts.jobTags,\n runTags: opts.runTags,\n properties: properties,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return sparkJobRunSchema.parse(raw);\n }\n\n /**\n * Get run status (used for polling after submit).\n */\n async getRun(runId: string): Promise<RunResponse> {\n if (!runId || typeof runId !== \"string\" || !runId.trim()) {\n throw new Error(\"runId is required\");\n }\n const res = await fetch(`${this.baseUrl}/api/v2/runs/${runId}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return runResponseSchema.parse(raw);\n }\n\n /**\n * Submit a spark job and wait until the run reaches a terminal state (COMPLETE, FAIL, ABORT).\n */\n async submitSparkJobAndWait(\n options: SubmitSparkJobAndWaitOptions,\n ): Promise<{ runId: string; state: RunState; run: RunResponse }> {\n const opts = submitSparkJobAndWaitOptionsSchema.parse(options);\n const { pollIntervalMs, timeoutMs, ...submitOpts } = opts;\n const { runId } = await this.submitSparkJob(submitOpts);\n const started = Date.now();\n\n while (Date.now() - started < timeoutMs) {\n const run = await this.getRun(runId);\n const state = run.state ?? \"\";\n if (state === \"COMPLETE\" || state === \"FAIL\" || state === \"ABORT\") {\n return { runId, state, run };\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n const run = await this.getRun(runId);\n throw new Error(\n `Timeout waiting for run ${runId} (state: ${run.state ?? \"unknown\"})`,\n );\n }\n}\n"],"mappings":"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","names":["run"]}
package/dist/index.d.cts CHANGED
@@ -83,6 +83,28 @@ declare const lakeQueryResultSchema: z.ZodObject<{
83
83
  query?: string | undefined;
84
84
  }>;
85
85
  type LakeQueryResult = z.infer<typeof lakeQueryResultSchema>;
86
+ declare const getSparkClusterOptionsSchema: z.ZodObject<{
87
+ name: z.ZodString;
88
+ }, "strip", z.ZodTypeAny, {
89
+ name: string;
90
+ }, {
91
+ name: string;
92
+ }>;
93
+ type GetSparkClusterOptions = z.input<typeof getSparkClusterOptionsSchema>;
94
+ declare const getSparkClusterResultSchema: z.ZodObject<{
95
+ name: z.ZodString;
96
+ type: z.ZodEnum<["oleander", "emr-serverless", "glue"]>;
97
+ properties: z.ZodAny;
98
+ }, "strip", z.ZodTypeAny, {
99
+ type: "oleander" | "emr-serverless" | "glue";
100
+ name: string;
101
+ properties?: any;
102
+ }, {
103
+ type: "oleander" | "emr-serverless" | "glue";
104
+ name: string;
105
+ properties?: any;
106
+ }>;
107
+ type SparkCluster = z.infer<typeof getSparkClusterResultSchema>;
86
108
  /** API response for one page of spark scripts (S3-style) */
87
109
  declare const sparkJobListPageSchema: z.ZodObject<{
88
110
  scripts: z.ZodArray<z.ZodString, "many">;
@@ -124,7 +146,7 @@ declare const sparkMachineTypeSchema: z.ZodEnum<["spark.1.c", "spark.2.c", "spar
124
146
  type SparkMachineType = z.infer<typeof sparkMachineTypeSchema>;
125
147
  /** Spark job submit options. Optional fields have defaults. */
126
148
  declare const submitOptionsSchema: z.ZodObject<{
127
- cluster: z.ZodDefault<z.ZodEnum<["oleander", "emr-serverless", "glue"]>>;
149
+ cluster: z.ZodDefault<z.ZodString>;
128
150
  namespace: z.ZodString;
129
151
  name: z.ZodString;
130
152
  args: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -145,9 +167,9 @@ declare const submitOptionsSchema: z.ZodObject<{
145
167
  timeoutMinutes: z.ZodOptional<z.ZodNumber>;
146
168
  executionClass: z.ZodOptional<z.ZodString>;
147
169
  }, "strip", z.ZodTypeAny, {
148
- cluster: "oleander" | "emr-serverless" | "glue";
149
- namespace: string;
150
170
  name: string;
171
+ cluster: string;
172
+ namespace: string;
151
173
  args: string[];
152
174
  entrypoint: string;
153
175
  sparkConf: string[];
@@ -166,10 +188,10 @@ declare const submitOptionsSchema: z.ZodObject<{
166
188
  timeoutMinutes?: number | undefined;
167
189
  executionClass?: string | undefined;
168
190
  }, {
169
- namespace: string;
170
191
  name: string;
192
+ namespace: string;
171
193
  entrypoint: string;
172
- cluster?: "oleander" | "emr-serverless" | "glue" | undefined;
194
+ cluster?: string | undefined;
173
195
  args?: string[] | undefined;
174
196
  pyFiles?: string | undefined;
175
197
  mainClass?: string | undefined;
@@ -190,7 +212,7 @@ declare const submitOptionsSchema: z.ZodObject<{
190
212
  type SparkJobSubmitOptions = z.input<typeof submitOptionsSchema>;
191
213
  /** Options for submitSparkJobAndWait (submit options + optional wait tuning) */
192
214
  declare const submitSparkJobAndWaitOptionsSchema: z.ZodObject<{
193
- cluster: z.ZodDefault<z.ZodEnum<["oleander", "emr-serverless", "glue"]>>;
215
+ cluster: z.ZodDefault<z.ZodString>;
194
216
  namespace: z.ZodString;
195
217
  name: z.ZodString;
196
218
  args: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -214,9 +236,9 @@ declare const submitSparkJobAndWaitOptionsSchema: z.ZodObject<{
214
236
  pollIntervalMs: z.ZodDefault<z.ZodNumber>;
215
237
  timeoutMs: z.ZodDefault<z.ZodNumber>;
216
238
  }, "strip", z.ZodTypeAny, {
217
- cluster: "oleander" | "emr-serverless" | "glue";
218
- namespace: string;
219
239
  name: string;
240
+ cluster: string;
241
+ namespace: string;
220
242
  args: string[];
221
243
  entrypoint: string;
222
244
  sparkConf: string[];
@@ -237,10 +259,10 @@ declare const submitSparkJobAndWaitOptionsSchema: z.ZodObject<{
237
259
  timeoutMinutes?: number | undefined;
238
260
  executionClass?: string | undefined;
239
261
  }, {
240
- namespace: string;
241
262
  name: string;
263
+ namespace: string;
242
264
  entrypoint: string;
243
- cluster?: "oleander" | "emr-serverless" | "glue" | undefined;
265
+ cluster?: string | undefined;
244
266
  args?: string[] | undefined;
245
267
  pyFiles?: string | undefined;
246
268
  mainClass?: string | undefined;
@@ -298,12 +320,12 @@ declare const runResponseSchema: z.ZodObject<{
298
320
  name: z.ZodString;
299
321
  namespace: z.ZodString;
300
322
  }, "strip", z.ZodTypeAny, {
301
- namespace: string;
302
323
  name: string;
324
+ namespace: string;
303
325
  id: string;
304
326
  }, {
305
- namespace: string;
306
327
  name: string;
328
+ namespace: string;
307
329
  id: string;
308
330
  }>;
309
331
  pipeline: z.ZodObject<{
@@ -311,12 +333,12 @@ declare const runResponseSchema: z.ZodObject<{
311
333
  name: z.ZodString;
312
334
  namespace: z.ZodString;
313
335
  }, "strip", z.ZodTypeAny, {
314
- namespace: string;
315
336
  name: string;
337
+ namespace: string;
316
338
  id: string;
317
339
  }, {
318
- namespace: string;
319
340
  name: string;
341
+ namespace: string;
320
342
  id: string;
321
343
  }>;
322
344
  }, "strip", z.ZodTypeAny, {
@@ -328,13 +350,13 @@ declare const runResponseSchema: z.ZodObject<{
328
350
  source?: string | null | undefined;
329
351
  }[];
330
352
  job: {
331
- namespace: string;
332
353
  name: string;
354
+ namespace: string;
333
355
  id: string;
334
356
  };
335
357
  pipeline: {
336
- namespace: string;
337
358
  name: string;
359
+ namespace: string;
338
360
  id: string;
339
361
  };
340
362
  error?: unknown;
@@ -352,13 +374,13 @@ declare const runResponseSchema: z.ZodObject<{
352
374
  source?: string | null | undefined;
353
375
  }[];
354
376
  job: {
355
- namespace: string;
356
377
  name: string;
378
+ namespace: string;
357
379
  id: string;
358
380
  };
359
381
  pipeline: {
360
- namespace: string;
361
382
  name: string;
383
+ namespace: string;
362
384
  id: string;
363
385
  };
364
386
  error?: unknown;
@@ -382,6 +404,10 @@ declare class Oleander {
382
404
  * Execute a lake query (mirrors `oleander query`).
383
405
  */
384
406
  query(sql: string, options?: QueryOptions): Promise<LakeQueryResult>;
407
+ /**
408
+ * Get spark cluster information
409
+ */
410
+ getSparkCluster(options: GetSparkClusterOptions): Promise<SparkCluster>;
385
411
  /**
386
412
  * List spark jobs (mirrors `oleander spark jobs list`).
387
413
  * Uses limit/offset pagination; pages through the API internally.
package/dist/index.d.ts CHANGED
@@ -83,6 +83,28 @@ declare const lakeQueryResultSchema: z.ZodObject<{
83
83
  query?: string | undefined;
84
84
  }>;
85
85
  type LakeQueryResult = z.infer<typeof lakeQueryResultSchema>;
86
+ declare const getSparkClusterOptionsSchema: z.ZodObject<{
87
+ name: z.ZodString;
88
+ }, "strip", z.ZodTypeAny, {
89
+ name: string;
90
+ }, {
91
+ name: string;
92
+ }>;
93
+ type GetSparkClusterOptions = z.input<typeof getSparkClusterOptionsSchema>;
94
+ declare const getSparkClusterResultSchema: z.ZodObject<{
95
+ name: z.ZodString;
96
+ type: z.ZodEnum<["oleander", "emr-serverless", "glue"]>;
97
+ properties: z.ZodAny;
98
+ }, "strip", z.ZodTypeAny, {
99
+ type: "oleander" | "emr-serverless" | "glue";
100
+ name: string;
101
+ properties?: any;
102
+ }, {
103
+ type: "oleander" | "emr-serverless" | "glue";
104
+ name: string;
105
+ properties?: any;
106
+ }>;
107
+ type SparkCluster = z.infer<typeof getSparkClusterResultSchema>;
86
108
  /** API response for one page of spark scripts (S3-style) */
87
109
  declare const sparkJobListPageSchema: z.ZodObject<{
88
110
  scripts: z.ZodArray<z.ZodString, "many">;
@@ -124,7 +146,7 @@ declare const sparkMachineTypeSchema: z.ZodEnum<["spark.1.c", "spark.2.c", "spar
124
146
  type SparkMachineType = z.infer<typeof sparkMachineTypeSchema>;
125
147
  /** Spark job submit options. Optional fields have defaults. */
126
148
  declare const submitOptionsSchema: z.ZodObject<{
127
- cluster: z.ZodDefault<z.ZodEnum<["oleander", "emr-serverless", "glue"]>>;
149
+ cluster: z.ZodDefault<z.ZodString>;
128
150
  namespace: z.ZodString;
129
151
  name: z.ZodString;
130
152
  args: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -145,9 +167,9 @@ declare const submitOptionsSchema: z.ZodObject<{
145
167
  timeoutMinutes: z.ZodOptional<z.ZodNumber>;
146
168
  executionClass: z.ZodOptional<z.ZodString>;
147
169
  }, "strip", z.ZodTypeAny, {
148
- cluster: "oleander" | "emr-serverless" | "glue";
149
- namespace: string;
150
170
  name: string;
171
+ cluster: string;
172
+ namespace: string;
151
173
  args: string[];
152
174
  entrypoint: string;
153
175
  sparkConf: string[];
@@ -166,10 +188,10 @@ declare const submitOptionsSchema: z.ZodObject<{
166
188
  timeoutMinutes?: number | undefined;
167
189
  executionClass?: string | undefined;
168
190
  }, {
169
- namespace: string;
170
191
  name: string;
192
+ namespace: string;
171
193
  entrypoint: string;
172
- cluster?: "oleander" | "emr-serverless" | "glue" | undefined;
194
+ cluster?: string | undefined;
173
195
  args?: string[] | undefined;
174
196
  pyFiles?: string | undefined;
175
197
  mainClass?: string | undefined;
@@ -190,7 +212,7 @@ declare const submitOptionsSchema: z.ZodObject<{
190
212
  type SparkJobSubmitOptions = z.input<typeof submitOptionsSchema>;
191
213
  /** Options for submitSparkJobAndWait (submit options + optional wait tuning) */
192
214
  declare const submitSparkJobAndWaitOptionsSchema: z.ZodObject<{
193
- cluster: z.ZodDefault<z.ZodEnum<["oleander", "emr-serverless", "glue"]>>;
215
+ cluster: z.ZodDefault<z.ZodString>;
194
216
  namespace: z.ZodString;
195
217
  name: z.ZodString;
196
218
  args: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -214,9 +236,9 @@ declare const submitSparkJobAndWaitOptionsSchema: z.ZodObject<{
214
236
  pollIntervalMs: z.ZodDefault<z.ZodNumber>;
215
237
  timeoutMs: z.ZodDefault<z.ZodNumber>;
216
238
  }, "strip", z.ZodTypeAny, {
217
- cluster: "oleander" | "emr-serverless" | "glue";
218
- namespace: string;
219
239
  name: string;
240
+ cluster: string;
241
+ namespace: string;
220
242
  args: string[];
221
243
  entrypoint: string;
222
244
  sparkConf: string[];
@@ -237,10 +259,10 @@ declare const submitSparkJobAndWaitOptionsSchema: z.ZodObject<{
237
259
  timeoutMinutes?: number | undefined;
238
260
  executionClass?: string | undefined;
239
261
  }, {
240
- namespace: string;
241
262
  name: string;
263
+ namespace: string;
242
264
  entrypoint: string;
243
- cluster?: "oleander" | "emr-serverless" | "glue" | undefined;
265
+ cluster?: string | undefined;
244
266
  args?: string[] | undefined;
245
267
  pyFiles?: string | undefined;
246
268
  mainClass?: string | undefined;
@@ -298,12 +320,12 @@ declare const runResponseSchema: z.ZodObject<{
298
320
  name: z.ZodString;
299
321
  namespace: z.ZodString;
300
322
  }, "strip", z.ZodTypeAny, {
301
- namespace: string;
302
323
  name: string;
324
+ namespace: string;
303
325
  id: string;
304
326
  }, {
305
- namespace: string;
306
327
  name: string;
328
+ namespace: string;
307
329
  id: string;
308
330
  }>;
309
331
  pipeline: z.ZodObject<{
@@ -311,12 +333,12 @@ declare const runResponseSchema: z.ZodObject<{
311
333
  name: z.ZodString;
312
334
  namespace: z.ZodString;
313
335
  }, "strip", z.ZodTypeAny, {
314
- namespace: string;
315
336
  name: string;
337
+ namespace: string;
316
338
  id: string;
317
339
  }, {
318
- namespace: string;
319
340
  name: string;
341
+ namespace: string;
320
342
  id: string;
321
343
  }>;
322
344
  }, "strip", z.ZodTypeAny, {
@@ -328,13 +350,13 @@ declare const runResponseSchema: z.ZodObject<{
328
350
  source?: string | null | undefined;
329
351
  }[];
330
352
  job: {
331
- namespace: string;
332
353
  name: string;
354
+ namespace: string;
333
355
  id: string;
334
356
  };
335
357
  pipeline: {
336
- namespace: string;
337
358
  name: string;
359
+ namespace: string;
338
360
  id: string;
339
361
  };
340
362
  error?: unknown;
@@ -352,13 +374,13 @@ declare const runResponseSchema: z.ZodObject<{
352
374
  source?: string | null | undefined;
353
375
  }[];
354
376
  job: {
355
- namespace: string;
356
377
  name: string;
378
+ namespace: string;
357
379
  id: string;
358
380
  };
359
381
  pipeline: {
360
- namespace: string;
361
382
  name: string;
383
+ namespace: string;
362
384
  id: string;
363
385
  };
364
386
  error?: unknown;
@@ -382,6 +404,10 @@ declare class Oleander {
382
404
  * Execute a lake query (mirrors `oleander query`).
383
405
  */
384
406
  query(sql: string, options?: QueryOptions): Promise<LakeQueryResult>;
407
+ /**
408
+ * Get spark cluster information
409
+ */
410
+ getSparkCluster(options: GetSparkClusterOptions): Promise<SparkCluster>;
385
411
  /**
386
412
  * List spark jobs (mirrors `oleander spark jobs list`).
387
413
  * Uses limit/offset pagination; pages through the API internally.
package/dist/index.js CHANGED
@@ -26,6 +26,19 @@ var lakeQueryResultSchema = z.object({
26
26
  details: z.string().optional(),
27
27
  query: z.string().optional()
28
28
  });
29
+ var getSparkClusterOptionsSchema = z.object({
30
+ name: z.string()
31
+ });
32
+ var sparkClusterTypeSchema = z.enum([
33
+ "oleander",
34
+ "emr-serverless",
35
+ "glue"
36
+ ]);
37
+ var getSparkClusterResultSchema = z.object({
38
+ name: z.string(),
39
+ type: sparkClusterTypeSchema,
40
+ properties: z.any()
41
+ });
29
42
  var sparkJobListPageSchema = z.object({
30
43
  scripts: z.array(z.string()),
31
44
  continuationToken: z.string().optional()
@@ -38,11 +51,6 @@ var listSparkJobsResultSchema = z.object({
38
51
  scripts: z.array(z.string()),
39
52
  hasMore: z.boolean()
40
53
  });
41
- var sparkClusterTypeSchema = z.enum([
42
- "oleander",
43
- "emr-serverless",
44
- "glue"
45
- ]);
46
54
  var sparkMachineTypeSchema = z.enum([
47
55
  "spark.1.c",
48
56
  "spark.2.c",
@@ -68,7 +76,7 @@ var glueWorkerTypeSchema = z.enum([
68
76
  "G.025X"
69
77
  ]);
70
78
  var submitOptionsSchema = z.object({
71
- cluster: sparkClusterTypeSchema.default("oleander"),
79
+ cluster: z.string().default("oleander"),
72
80
  namespace: z.string().min(1, "namespace is required"),
73
81
  name: z.string().min(1, "name is required"),
74
82
  args: z.array(z.string()).default([]),
@@ -139,6 +147,18 @@ function parseErrorBody(body, status) {
139
147
  }
140
148
  return `HTTP ${status}`;
141
149
  }
150
+ function buildGlueArguments(args) {
151
+ const result = {};
152
+ for (let i = 0; i < args.length; i += 2) {
153
+ const key = args[i];
154
+ const value = args[i + 1];
155
+ if (value === void 0) {
156
+ throw new Error(`Missing value for argument: ${key}`);
157
+ }
158
+ result[key] = value;
159
+ }
160
+ return result;
161
+ }
142
162
  var Oleander = class {
143
163
  constructor(options = {}) {
144
164
  const parsed = optionsSchema.safeParse(options);
@@ -184,6 +204,31 @@ var Oleander = class {
184
204
  }
185
205
  return result;
186
206
  }
207
+ /**
208
+ * Get spark cluster information
209
+ */
210
+ async getSparkCluster(options) {
211
+ const opts = getSparkClusterOptionsSchema.parse(options);
212
+ if (opts.name === "oleander") {
213
+ return {
214
+ name: "oleander",
215
+ type: "oleander",
216
+ properties: {}
217
+ };
218
+ }
219
+ const res = await fetch(
220
+ `${this.baseUrl}/api/v2/spark/clusters/${opts.name}`,
221
+ {
222
+ method: "GET",
223
+ headers: { Authorization: `Bearer ${this.apiKey}` }
224
+ }
225
+ );
226
+ const raw = await res.json().catch(() => ({}));
227
+ if (!res.ok) {
228
+ throw new Error(parseErrorBody(raw, res.status));
229
+ }
230
+ return getSparkClusterResultSchema.parse(raw);
231
+ }
187
232
  /**
188
233
  * List spark jobs (mirrors `oleander spark jobs list`).
189
234
  * Uses limit/offset pagination; pages through the API internally.
@@ -220,20 +265,9 @@ var Oleander = class {
220
265
  */
221
266
  async submitSparkJob(options) {
222
267
  const opts = submitOptionsSchema.parse(options);
223
- const buildGlueArguments = (args) => {
224
- const result = {};
225
- for (let i = 0; i < args.length; i += 2) {
226
- const key = args[i];
227
- const value = args[i + 1];
228
- if (value === void 0) {
229
- throw new Error(`Missing value for argument: ${key}`);
230
- }
231
- result[key] = value;
232
- }
233
- return result;
234
- };
268
+ const cluster = await this.getSparkCluster({ name: opts.cluster });
235
269
  let properties;
236
- if (opts.cluster === "oleander") {
270
+ if (cluster.type === "oleander") {
237
271
  properties = {
238
272
  entrypoint: opts.entrypoint,
239
273
  entrypointArguments: opts.args,
@@ -243,7 +277,7 @@ var Oleander = class {
243
277
  sparkConf: opts.sparkConf,
244
278
  packages: opts.packages
245
279
  };
246
- } else if (opts.cluster === "emr-serverless") {
280
+ } else if (cluster.type === "emr-serverless") {
247
281
  properties = {
248
282
  entrypoint: opts.entrypoint,
249
283
  entrypointArguments: opts.args,
@@ -253,7 +287,7 @@ var Oleander = class {
253
287
  packages: opts.packages,
254
288
  executionIamPolicy: opts.executionIamPolicy
255
289
  };
256
- } else if (opts.cluster === "glue") {
290
+ } else if (cluster.type === "glue") {
257
291
  properties = {
258
292
  jobName: opts.entrypoint,
259
293
  entrypointArguments: buildGlueArguments(opts.args),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schemas.ts","../src/client.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/** API error response body */\nexport const apiErrorBodySchema = z.object({\n error: z.string().optional(),\n details: z.string().optional(),\n});\n\nexport type ApiErrorBody = z.infer<typeof apiErrorBodySchema>;\n\nconst DEFAULT_BASE_URL = \"https://oleander.dev\";\n\n/** Constructor options. apiKey can be omitted if OLEANDER_API_KEY env is set. */\nexport const optionsSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z\n .string()\n .default(DEFAULT_BASE_URL)\n .transform((v) => (v.trim() ? v.trim() : DEFAULT_BASE_URL)),\n});\n\nexport type OleanderOptions = z.input<typeof optionsSchema>;\n\n/** Lake query options */\nexport const queryOptionsSchema = z.object({\n save: z.boolean().default(false),\n});\n\nexport type QueryOptions = z.input<typeof queryOptionsSchema>;\n\n/** Lake query result (API response) */\nexport const lakeQueryResultSchema = z.object({\n success: z.boolean(),\n results: z\n .object({\n columns: z.array(z.string()),\n column_types: z.array(z.string()),\n rows: z.array(z.array(z.unknown())),\n })\n .optional(),\n row_count: z.number().optional(),\n execution_time: z.string().optional(),\n saved_table_name: z.string().optional(),\n error: z.string().optional(),\n details: z.string().optional(),\n query: z.string().optional(),\n});\n\nexport type LakeQueryResult = z.infer<typeof lakeQueryResultSchema>;\n\n/** API response for one page of spark scripts (S3-style) */\nexport const sparkJobListPageSchema = z.object({\n scripts: z.array(z.string()),\n continuationToken: z.string().optional(),\n});\n\nexport type SparkJobListPage = z.infer<typeof sparkJobListPageSchema>;\n\n/** Options for listSparkJobs (limit/offset pagination) */\nexport const listSparkJobsOptionsSchema = z.object({\n limit: z.number().int().positive().default(20),\n offset: z.number().int().nonnegative().default(0),\n});\n\nexport type ListSparkJobsOptions = z.input<typeof listSparkJobsOptionsSchema>;\n\n/** Result of listSparkJobs with limit/offset */\nexport const listSparkJobsResultSchema = z.object({\n scripts: z.array(z.string()),\n hasMore: z.boolean(),\n});\n\nexport type ListSparkJobsResult = z.infer<typeof listSparkJobsResultSchema>;\n\n/** Spark cluster type enum */\nexport const sparkClusterTypeSchema = z.enum([\n \"oleander\",\n \"emr-serverless\",\n \"glue\",\n]);\n\n/** Spark machine type enum */\nexport const sparkMachineTypeSchema = z.enum([\n \"spark.1.c\",\n \"spark.2.c\",\n \"spark.4.c\",\n \"spark.8.c\",\n \"spark.16.c\",\n \"spark.1.b\",\n \"spark.2.b\",\n \"spark.4.b\",\n \"spark.8.b\",\n \"spark.16.b\",\n \"spark.1.m\",\n \"spark.2.m\",\n \"spark.4.m\",\n \"spark.8.m\",\n \"spark.16.m\",\n]);\n\n/** Glue worker type enum */\nexport const glueWorkerTypeSchema = z.enum([\n \"G.1X\",\n \"G.2X\",\n \"G.4X\",\n \"G.8X\",\n \"G.025X\",\n]);\n\nexport type SparkMachineType = z.infer<typeof sparkMachineTypeSchema>;\n\n/** Spark job submit options. Optional fields have defaults. */\nexport const submitOptionsSchema = z.object({\n cluster: sparkClusterTypeSchema.default(\"oleander\"),\n namespace: z.string().min(1, \"namespace is required\"),\n name: z.string().min(1, \"name is required\"),\n args: z.array(z.string()).default([]),\n entrypoint: z.string().min(1, \"entrypoint is required\"),\n pyFiles: z.string().optional(),\n mainClass: z.string().optional(),\n sparkConf: z.array(z.string()).default([]),\n packages: z.array(z.string()).default([]),\n executionIamPolicy: z.string().optional(),\n jobTags: z.array(z.string()).default([]),\n runTags: z.array(z.string()).default([]),\n driverMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorNumbers: z.number().int().min(1).max(20).default(2),\n workerType: glueWorkerTypeSchema.optional(),\n numberOfWorkers: z.number().int().min(1).default(1),\n enableAutoScaling: z.boolean().optional(),\n timeoutMinutes: z.number().int().optional(),\n executionClass: z.string().optional(),\n});\n\nexport type SparkJobSubmitOptions = z.input<typeof submitOptionsSchema>;\n\n/** Options for submitSparkJobAndWait (submit options + optional wait tuning) */\nexport const submitSparkJobAndWaitOptionsSchema = submitOptionsSchema.extend({\n pollIntervalMs: z.number().int().positive().default(10000),\n timeoutMs: z.number().int().positive().default(600000),\n});\n\nexport type SubmitSparkJobAndWaitOptions = z.input<\n typeof submitSparkJobAndWaitOptionsSchema\n>;\n\n/** Spark job submit response */\nexport const sparkJobRunSchema = z.object({\n runId: z.string(),\n});\n\nexport type SparkJobRun = z.infer<typeof sparkJobRunSchema>;\n\n/** Run status (for polling) */\nexport const runResponseSchema = z.object({\n id: z.string(),\n state: z.string().nullable(),\n started_at: z.string().nullable().optional(),\n queued_at: z.string().nullable().optional(),\n scheduled_at: z.string().nullable().optional(),\n ended_at: z.string().nullable().optional(),\n duration: z.number().nullable().optional(),\n error: z.unknown().nullable().optional(),\n tags: z.array(\n z.object({\n key: z.string(),\n value: z.string(),\n source: z.string().nullable().optional(),\n }),\n ),\n job: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n pipeline: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n});\n\nexport type RunResponse = z.infer<typeof runResponseSchema>;\n\nexport type RunState = \"COMPLETE\" | \"FAIL\" | \"ABORT\" | string;\n","import {\n optionsSchema,\n queryOptionsSchema,\n lakeQueryResultSchema,\n sparkJobListPageSchema,\n listSparkJobsOptionsSchema,\n submitOptionsSchema,\n submitSparkJobAndWaitOptionsSchema,\n sparkJobRunSchema,\n runResponseSchema,\n apiErrorBodySchema,\n} from \"./schemas.js\";\nimport type {\n OleanderOptions,\n QueryOptions,\n LakeQueryResult,\n ListSparkJobsOptions,\n ListSparkJobsResult,\n SparkJobSubmitOptions,\n SubmitSparkJobAndWaitOptions,\n SparkJobRun,\n RunResponse,\n RunState,\n} from \"./schemas.js\";\n\nfunction getHeaders(apiKey: string): Record<string, string> {\n return {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nfunction parseErrorBody(body: unknown, status: number): string {\n const parsed = apiErrorBodySchema.safeParse(body);\n if (parsed.success) {\n const { error, details } = parsed.data;\n return error || details || `HTTP ${status}`;\n }\n return `HTTP ${status}`;\n}\n\n/**\n * oleander API. Mirrors the CLI for query, list spark jobs, and launch spark jobs.\n */\nexport class Oleander {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(options: OleanderOptions = {}) {\n const parsed = optionsSchema.safeParse(options);\n if (!parsed.success) {\n const first =\n parsed.error.flatten().formErrors[0] ?? parsed.error.message;\n throw new Error(first);\n }\n const fromOptions = parsed.data.apiKey?.trim();\n const fromEnv =\n typeof process !== \"undefined\" && process.env?.OLEANDER_API_KEY;\n const apiKey = fromOptions ?? fromEnv ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"Oleander requires a non-empty apiKey (or set OLEANDER_API_KEY)\",\n );\n }\n this.apiKey = apiKey;\n this.baseUrl = parsed.data.baseUrl.trim().replace(/\\/$/, \"\");\n }\n\n /**\n * Execute a lake query (mirrors `oleander query`).\n */\n async query(\n sql: string,\n options: QueryOptions = {},\n ): Promise<LakeQueryResult> {\n const query = typeof sql === \"string\" ? sql.trim() : \"\";\n if (!query) {\n throw new Error(\"Query is required\");\n }\n const opts = queryOptionsSchema.parse(options);\n\n const res = await fetch(`${this.baseUrl}/api/v1/warehouse/query`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n query,\n autoSaveByHash: opts.save,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n\n const result = lakeQueryResultSchema.parse(raw);\n if (!result.success && result.error) {\n throw new Error(result.details || result.error);\n }\n return result;\n }\n\n /**\n * List spark jobs (mirrors `oleander spark jobs list`).\n * Uses limit/offset pagination; pages through the API internally.\n */\n async listSparkJobs(\n options: ListSparkJobsOptions = {},\n ): Promise<ListSparkJobsResult> {\n const opts = listSparkJobsOptionsSchema.parse(options);\n const { limit, offset } = opts;\n\n const allScripts: string[] = [];\n let continuationToken: string | undefined;\n\n while (true) {\n const params = continuationToken\n ? `?${new URLSearchParams({ continuationToken }).toString()}`\n : \"\";\n const res = await fetch(`${this.baseUrl}/api/v1/spark/scripts${params}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n const page = sparkJobListPageSchema.parse(raw);\n allScripts.push(...page.scripts);\n continuationToken = page.continuationToken;\n if (!continuationToken || allScripts.length >= offset + limit) {\n break;\n }\n }\n\n const scripts = allScripts.slice(offset, offset + limit);\n const hasMore = !!continuationToken || allScripts.length > offset + limit;\n return { scripts, hasMore };\n }\n\n /**\n * Submit a spark job (mirrors `oleander spark jobs submit`).\n * Returns the run ID; use getRun() or submitSparkJobAndWait() to poll status.\n */\n async submitSparkJob(options: SparkJobSubmitOptions): Promise<SparkJobRun> {\n const opts = submitOptionsSchema.parse(options);\n\n const buildGlueArguments = (args: string[]): Record<string, string> => {\n const result: Record<string, string> = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const value = args[i + 1];\n if (value === undefined) {\n throw new Error(`Missing value for argument: ${key}`);\n }\n result[key] = value;\n }\n return result;\n };\n\n let properties: any;\n if (opts.cluster === \"oleander\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n driverMachineType: opts.driverMachineType,\n executorMachineType: opts.executorMachineType,\n executorNumbers: opts.executorNumbers,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n };\n } else if (opts.cluster === \"emr-serverless\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n pyFiles: opts.pyFiles,\n mainClass: opts.mainClass,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n executionIamPolicy: opts.executionIamPolicy,\n };\n } else if (opts.cluster === \"glue\") {\n properties = {\n jobName: opts.entrypoint,\n entrypointArguments: buildGlueArguments(opts.args),\n sparkConf: opts.sparkConf,\n workerType: opts.workerType,\n numberOfWorkers: opts.numberOfWorkers,\n enableAutoScaling: opts.enableAutoScaling,\n timeoutMinutes: opts.timeoutMinutes,\n executionClass: opts.executionClass,\n executionRoleSessionPolicy: opts.executionIamPolicy,\n };\n }\n\n const res = await fetch(`${this.baseUrl}/api/v2/spark/jobs`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n cluster: opts.cluster,\n namespace: opts.namespace.trim(),\n name: opts.name.trim(),\n jobTags: opts.jobTags,\n runTags: opts.runTags,\n properties: properties,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return sparkJobRunSchema.parse(raw);\n }\n\n /**\n * Get run status (used for polling after submit).\n */\n async getRun(runId: string): Promise<RunResponse> {\n if (!runId || typeof runId !== \"string\" || !runId.trim()) {\n throw new Error(\"runId is required\");\n }\n const res = await fetch(`${this.baseUrl}/api/v2/runs/${runId}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return runResponseSchema.parse(raw);\n }\n\n /**\n * Submit a spark job and wait until the run reaches a terminal state (COMPLETE, FAIL, ABORT).\n */\n async submitSparkJobAndWait(\n options: SubmitSparkJobAndWaitOptions,\n ): Promise<{ runId: string; state: RunState; run: RunResponse }> {\n const opts = submitSparkJobAndWaitOptionsSchema.parse(options);\n const { pollIntervalMs, timeoutMs, ...submitOpts } = opts;\n const { runId } = await this.submitSparkJob(submitOpts);\n const started = Date.now();\n\n while (Date.now() - started < timeoutMs) {\n const run = await this.getRun(runId);\n const state = run.state ?? \"\";\n if (state === \"COMPLETE\" || state === \"FAIL\" || state === \"ABORT\") {\n return { runId, state, run };\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n const run = await this.getRun(runId);\n throw new Error(\n `Timeout waiting for run ${runId} (state: ${run.state ?? \"unknown\"})`,\n );\n }\n}\n"],"mappings":"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","names":["run"]}
1
+ {"version":3,"sources":["../src/schemas.ts","../src/client.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/** API error response body */\nexport const apiErrorBodySchema = z.object({\n error: z.string().optional(),\n details: z.string().optional(),\n});\n\nexport type ApiErrorBody = z.infer<typeof apiErrorBodySchema>;\n\nconst DEFAULT_BASE_URL = \"https://oleander.dev\";\n\n/** Constructor options. apiKey can be omitted if OLEANDER_API_KEY env is set. */\nexport const optionsSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z\n .string()\n .default(DEFAULT_BASE_URL)\n .transform((v) => (v.trim() ? v.trim() : DEFAULT_BASE_URL)),\n});\n\nexport type OleanderOptions = z.input<typeof optionsSchema>;\n\n/** Lake query options */\nexport const queryOptionsSchema = z.object({\n save: z.boolean().default(false),\n});\n\nexport type QueryOptions = z.input<typeof queryOptionsSchema>;\n\n/** Lake query result (API response) */\nexport const lakeQueryResultSchema = z.object({\n success: z.boolean(),\n results: z\n .object({\n columns: z.array(z.string()),\n column_types: z.array(z.string()),\n rows: z.array(z.array(z.unknown())),\n })\n .optional(),\n row_count: z.number().optional(),\n execution_time: z.string().optional(),\n saved_table_name: z.string().optional(),\n error: z.string().optional(),\n details: z.string().optional(),\n query: z.string().optional(),\n});\n\nexport type LakeQueryResult = z.infer<typeof lakeQueryResultSchema>;\n\nexport const getSparkClusterOptionsSchema = z.object({\n name: z.string(),\n});\n\nexport type GetSparkClusterOptions = z.input<\n typeof getSparkClusterOptionsSchema\n>;\n\nexport const sparkClusterTypeSchema = z.enum([\n \"oleander\",\n \"emr-serverless\",\n \"glue\",\n]);\n\nexport const getSparkClusterResultSchema = z.object({\n name: z.string(),\n type: sparkClusterTypeSchema,\n properties: z.any(),\n});\n\nexport type SparkCluster = z.infer<typeof getSparkClusterResultSchema>;\n\n/** API response for one page of spark scripts (S3-style) */\nexport const sparkJobListPageSchema = z.object({\n scripts: z.array(z.string()),\n continuationToken: z.string().optional(),\n});\n\nexport type SparkJobListPage = z.infer<typeof sparkJobListPageSchema>;\n\n/** Options for listSparkJobs (limit/offset pagination) */\nexport const listSparkJobsOptionsSchema = z.object({\n limit: z.number().int().positive().default(20),\n offset: z.number().int().nonnegative().default(0),\n});\n\nexport type ListSparkJobsOptions = z.input<typeof listSparkJobsOptionsSchema>;\n\n/** Result of listSparkJobs with limit/offset */\nexport const listSparkJobsResultSchema = z.object({\n scripts: z.array(z.string()),\n hasMore: z.boolean(),\n});\n\nexport type ListSparkJobsResult = z.infer<typeof listSparkJobsResultSchema>;\n\n/** Spark machine type enum */\nexport const sparkMachineTypeSchema = z.enum([\n \"spark.1.c\",\n \"spark.2.c\",\n \"spark.4.c\",\n \"spark.8.c\",\n \"spark.16.c\",\n \"spark.1.b\",\n \"spark.2.b\",\n \"spark.4.b\",\n \"spark.8.b\",\n \"spark.16.b\",\n \"spark.1.m\",\n \"spark.2.m\",\n \"spark.4.m\",\n \"spark.8.m\",\n \"spark.16.m\",\n]);\n\n/** Glue worker type enum */\nexport const glueWorkerTypeSchema = z.enum([\n \"G.1X\",\n \"G.2X\",\n \"G.4X\",\n \"G.8X\",\n \"G.025X\",\n]);\n\nexport type SparkMachineType = z.infer<typeof sparkMachineTypeSchema>;\n\n/** Spark job submit options. Optional fields have defaults. */\nexport const submitOptionsSchema = z.object({\n cluster: z.string().default(\"oleander\"),\n namespace: z.string().min(1, \"namespace is required\"),\n name: z.string().min(1, \"name is required\"),\n args: z.array(z.string()).default([]),\n entrypoint: z.string().min(1, \"entrypoint is required\"),\n pyFiles: z.string().optional(),\n mainClass: z.string().optional(),\n sparkConf: z.array(z.string()).default([]),\n packages: z.array(z.string()).default([]),\n executionIamPolicy: z.string().optional(),\n jobTags: z.array(z.string()).default([]),\n runTags: z.array(z.string()).default([]),\n driverMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorMachineType: sparkMachineTypeSchema.default(\"spark.1.b\"),\n executorNumbers: z.number().int().min(1).max(20).default(2),\n workerType: glueWorkerTypeSchema.optional(),\n numberOfWorkers: z.number().int().min(1).default(1),\n enableAutoScaling: z.boolean().optional(),\n timeoutMinutes: z.number().int().optional(),\n executionClass: z.string().optional(),\n});\n\nexport type SparkJobSubmitOptions = z.input<typeof submitOptionsSchema>;\n\n/** Options for submitSparkJobAndWait (submit options + optional wait tuning) */\nexport const submitSparkJobAndWaitOptionsSchema = submitOptionsSchema.extend({\n pollIntervalMs: z.number().int().positive().default(10000),\n timeoutMs: z.number().int().positive().default(600000),\n});\n\nexport type SubmitSparkJobAndWaitOptions = z.input<\n typeof submitSparkJobAndWaitOptionsSchema\n>;\n\n/** Spark job submit response */\nexport const sparkJobRunSchema = z.object({\n runId: z.string(),\n});\n\nexport type SparkJobRun = z.infer<typeof sparkJobRunSchema>;\n\n/** Run status (for polling) */\nexport const runResponseSchema = z.object({\n id: z.string(),\n state: z.string().nullable(),\n started_at: z.string().nullable().optional(),\n queued_at: z.string().nullable().optional(),\n scheduled_at: z.string().nullable().optional(),\n ended_at: z.string().nullable().optional(),\n duration: z.number().nullable().optional(),\n error: z.unknown().nullable().optional(),\n tags: z.array(\n z.object({\n key: z.string(),\n value: z.string(),\n source: z.string().nullable().optional(),\n }),\n ),\n job: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n pipeline: z.object({\n id: z.string(),\n name: z.string(),\n namespace: z.string(),\n }),\n});\n\nexport type RunResponse = z.infer<typeof runResponseSchema>;\n\nexport type RunState = \"COMPLETE\" | \"FAIL\" | \"ABORT\" | string;\n","import {\n optionsSchema,\n queryOptionsSchema,\n lakeQueryResultSchema,\n sparkJobListPageSchema,\n listSparkJobsOptionsSchema,\n submitOptionsSchema,\n submitSparkJobAndWaitOptionsSchema,\n sparkJobRunSchema,\n runResponseSchema,\n apiErrorBodySchema,\n GetSparkClusterOptions,\n SparkCluster,\n getSparkClusterOptionsSchema,\n getSparkClusterResultSchema,\n} from \"./schemas.js\";\nimport type {\n OleanderOptions,\n QueryOptions,\n LakeQueryResult,\n ListSparkJobsOptions,\n ListSparkJobsResult,\n SparkJobSubmitOptions,\n SubmitSparkJobAndWaitOptions,\n SparkJobRun,\n RunResponse,\n RunState,\n} from \"./schemas.js\";\n\nfunction getHeaders(apiKey: string): Record<string, string> {\n return {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nfunction parseErrorBody(body: unknown, status: number): string {\n const parsed = apiErrorBodySchema.safeParse(body);\n if (parsed.success) {\n const { error, details } = parsed.data;\n return error || details || `HTTP ${status}`;\n }\n return `HTTP ${status}`;\n}\n\nfunction buildGlueArguments(args: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n for (let i = 0; i < args.length; i += 2) {\n const key = args[i];\n const value = args[i + 1];\n if (value === undefined) {\n throw new Error(`Missing value for argument: ${key}`);\n }\n result[key] = value;\n }\n return result;\n}\n\n/**\n * oleander API. Mirrors the CLI for query, list spark jobs, and launch spark jobs.\n */\nexport class Oleander {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n\n constructor(options: OleanderOptions = {}) {\n const parsed = optionsSchema.safeParse(options);\n if (!parsed.success) {\n const first =\n parsed.error.flatten().formErrors[0] ?? parsed.error.message;\n throw new Error(first);\n }\n const fromOptions = parsed.data.apiKey?.trim();\n const fromEnv =\n typeof process !== \"undefined\" && process.env?.OLEANDER_API_KEY;\n const apiKey = fromOptions ?? fromEnv ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"Oleander requires a non-empty apiKey (or set OLEANDER_API_KEY)\",\n );\n }\n this.apiKey = apiKey;\n this.baseUrl = parsed.data.baseUrl.trim().replace(/\\/$/, \"\");\n }\n\n /**\n * Execute a lake query (mirrors `oleander query`).\n */\n async query(\n sql: string,\n options: QueryOptions = {},\n ): Promise<LakeQueryResult> {\n const query = typeof sql === \"string\" ? sql.trim() : \"\";\n if (!query) {\n throw new Error(\"Query is required\");\n }\n const opts = queryOptionsSchema.parse(options);\n\n const res = await fetch(`${this.baseUrl}/api/v1/warehouse/query`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n query,\n autoSaveByHash: opts.save,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n\n const result = lakeQueryResultSchema.parse(raw);\n if (!result.success && result.error) {\n throw new Error(result.details || result.error);\n }\n return result;\n }\n\n /**\n * Get spark cluster information\n */\n async getSparkCluster(\n options: GetSparkClusterOptions,\n ): Promise<SparkCluster> {\n const opts = getSparkClusterOptionsSchema.parse(options);\n\n if (opts.name === \"oleander\") {\n return {\n name: \"oleander\",\n type: \"oleander\",\n properties: {},\n };\n }\n\n const res = await fetch(\n `${this.baseUrl}/api/v2/spark/clusters/${opts.name}`,\n {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n },\n );\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return getSparkClusterResultSchema.parse(raw);\n }\n\n /**\n * List spark jobs (mirrors `oleander spark jobs list`).\n * Uses limit/offset pagination; pages through the API internally.\n */\n async listSparkJobs(\n options: ListSparkJobsOptions = {},\n ): Promise<ListSparkJobsResult> {\n const opts = listSparkJobsOptionsSchema.parse(options);\n const { limit, offset } = opts;\n\n const allScripts: string[] = [];\n let continuationToken: string | undefined;\n\n while (true) {\n const params = continuationToken\n ? `?${new URLSearchParams({ continuationToken }).toString()}`\n : \"\";\n const res = await fetch(`${this.baseUrl}/api/v1/spark/scripts${params}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n const page = sparkJobListPageSchema.parse(raw);\n allScripts.push(...page.scripts);\n continuationToken = page.continuationToken;\n if (!continuationToken || allScripts.length >= offset + limit) {\n break;\n }\n }\n\n const scripts = allScripts.slice(offset, offset + limit);\n const hasMore = !!continuationToken || allScripts.length > offset + limit;\n return { scripts, hasMore };\n }\n\n /**\n * Submit a spark job (mirrors `oleander spark jobs submit`).\n * Returns the run ID; use getRun() or submitSparkJobAndWait() to poll status.\n */\n async submitSparkJob(options: SparkJobSubmitOptions): Promise<SparkJobRun> {\n const opts = submitOptionsSchema.parse(options);\n const cluster = await this.getSparkCluster({ name: opts.cluster });\n\n let properties: any;\n if (cluster.type === \"oleander\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n driverMachineType: opts.driverMachineType,\n executorMachineType: opts.executorMachineType,\n executorNumbers: opts.executorNumbers,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n };\n } else if (cluster.type === \"emr-serverless\") {\n properties = {\n entrypoint: opts.entrypoint,\n entrypointArguments: opts.args,\n pyFiles: opts.pyFiles,\n mainClass: opts.mainClass,\n sparkConf: opts.sparkConf,\n packages: opts.packages,\n executionIamPolicy: opts.executionIamPolicy,\n };\n } else if (cluster.type === \"glue\") {\n properties = {\n jobName: opts.entrypoint,\n entrypointArguments: buildGlueArguments(opts.args),\n sparkConf: opts.sparkConf,\n workerType: opts.workerType,\n numberOfWorkers: opts.numberOfWorkers,\n enableAutoScaling: opts.enableAutoScaling,\n timeoutMinutes: opts.timeoutMinutes,\n executionClass: opts.executionClass,\n executionRoleSessionPolicy: opts.executionIamPolicy,\n };\n }\n\n const res = await fetch(`${this.baseUrl}/api/v2/spark/jobs`, {\n method: \"POST\",\n headers: getHeaders(this.apiKey),\n body: JSON.stringify({\n cluster: opts.cluster,\n namespace: opts.namespace.trim(),\n name: opts.name.trim(),\n jobTags: opts.jobTags,\n runTags: opts.runTags,\n properties: properties,\n }),\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return sparkJobRunSchema.parse(raw);\n }\n\n /**\n * Get run status (used for polling after submit).\n */\n async getRun(runId: string): Promise<RunResponse> {\n if (!runId || typeof runId !== \"string\" || !runId.trim()) {\n throw new Error(\"runId is required\");\n }\n const res = await fetch(`${this.baseUrl}/api/v2/runs/${runId}`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n });\n\n const raw = await res.json().catch(() => ({}));\n if (!res.ok) {\n throw new Error(parseErrorBody(raw, res.status));\n }\n return runResponseSchema.parse(raw);\n }\n\n /**\n * Submit a spark job and wait until the run reaches a terminal state (COMPLETE, FAIL, ABORT).\n */\n async submitSparkJobAndWait(\n options: SubmitSparkJobAndWaitOptions,\n ): Promise<{ runId: string; state: RunState; run: RunResponse }> {\n const opts = submitSparkJobAndWaitOptionsSchema.parse(options);\n const { pollIntervalMs, timeoutMs, ...submitOpts } = opts;\n const { runId } = await this.submitSparkJob(submitOpts);\n const started = Date.now();\n\n while (Date.now() - started < timeoutMs) {\n const run = await this.getRun(runId);\n const state = run.state ?? \"\";\n if (state === \"COMPLETE\" || state === \"FAIL\" || state === \"ABORT\") {\n return { runId, state, run };\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n const run = await this.getRun(runId);\n throw new Error(\n `Timeout waiting for run ${runId} (state: ${run.state ?? \"unknown\"})`,\n );\n }\n}\n"],"mappings":"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","names":["run"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oleanderhq/sdk",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "TypeScript SDK for oleander: query lake, list and launch Spark jobs",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",