@proofkit/fmodata
Version:
FileMaker OData API client
180 lines (179 loc) • 5.67 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import { formatBatchRequestFromNative, parseBatchResponse } from "./batch-request.js";
function parsedToResponse(parsed) {
const headers = new Headers(parsed.headers);
if (parsed.body === null || parsed.body === void 0) {
return new Response(null, {
status: parsed.status,
statusText: parsed.statusText,
headers
});
}
const bodyString = typeof parsed.body === "string" ? parsed.body : JSON.stringify(parsed.body);
let status = parsed.status;
if (status === 204 && bodyString && bodyString.trim() !== "") {
status = 200;
}
return new Response(status === 204 ? null : bodyString, {
status,
statusText: parsed.statusText,
headers
});
}
class BatchBuilder {
constructor(builders, databaseName, context) {
__publicField(this, "builders");
__publicField(this, "originalBuilders");
this.databaseName = databaseName;
this.context = context;
this.builders = [...builders];
this.originalBuilders = builders;
}
/**
* Add a request to the batch dynamically.
* This allows building up batch operations programmatically.
*
* @param builder - An executable builder to add to the batch
* @returns This BatchBuilder for method chaining
* @example
* ```ts
* const batch = db.batch([]);
* batch.addRequest(db.from('contacts').list());
* batch.addRequest(db.from('users').list());
* const result = await batch.execute();
* ```
*/
addRequest(builder) {
this.builders.push(builder);
return this;
}
/**
* Get the request configuration for this batch operation.
* This is used internally by the execution system.
*/
getRequestConfig() {
return {
method: "POST",
url: `/${this.databaseName}/$batch`,
body: void 0
// Body is constructed in execute()
};
}
toRequest(baseUrl) {
const fullUrl = `${baseUrl}/${this.databaseName}/$batch`;
return new Request(fullUrl, {
method: "POST",
headers: {
"Content-Type": "multipart/mixed",
"OData-Version": "4.0"
}
});
}
async processResponse(response, options) {
return {
data: void 0,
error: {
name: "NotImplementedError",
message: "Batch operations handle response processing internally",
timestamp: /* @__PURE__ */ new Date()
}
};
}
/**
* Execute the batch operation.
*
* @param options - Optional fetch options and batch-specific options (includes beforeRequest hook)
* @returns A tuple of results matching the input builders
*/
async execute(options) {
var _a, _b;
const baseUrl = (_b = (_a = this.context)._getBaseUrl) == null ? void 0 : _b.call(_a);
if (!baseUrl) {
return {
data: void 0,
error: {
name: "ConfigurationError",
message: "Base URL not available - execution context must implement _getBaseUrl()",
timestamp: /* @__PURE__ */ new Date()
}
};
}
try {
const requests = this.builders.map(
(builder) => builder.toRequest(baseUrl)
);
const { body, boundary } = await formatBatchRequestFromNative(
requests,
baseUrl
);
const response = await this.context._makeRequest(
`/${this.databaseName}/$batch`,
{
...options,
method: "POST",
headers: {
...options == null ? void 0 : options.headers,
"Content-Type": `multipart/mixed; boundary=${boundary}`,
"OData-Version": "4.0"
},
body
}
);
if (response.error) {
return { data: void 0, error: response.error };
}
const firstLine = response.data.split("\r\n")[0] || response.data.split("\n")[0] || "";
const actualBoundary = firstLine.startsWith("--") ? firstLine.substring(2) : boundary;
const contentTypeHeader = `multipart/mixed; boundary=${actualBoundary}`;
const parsedResponses = parseBatchResponse(
response.data,
contentTypeHeader
);
if (parsedResponses.length !== this.builders.length) {
return {
data: void 0,
error: {
name: "BatchError",
message: `Expected ${this.builders.length} responses but got ${parsedResponses.length}`,
timestamp: /* @__PURE__ */ new Date()
}
};
}
const processedResults = [];
for (let i = 0; i < this.originalBuilders.length; i++) {
const builder = this.originalBuilders[i];
const parsed = parsedResponses[i];
if (!builder || !parsed) {
processedResults.push(void 0);
continue;
}
const nativeResponse = parsedToResponse(parsed);
const result = await builder.processResponse(nativeResponse, options);
if (result.error) {
processedResults.push(void 0);
} else {
processedResults.push(result.data);
}
}
return {
data: processedResults,
error: void 0
};
} catch (err) {
return {
data: void 0,
error: {
name: "BatchError",
message: err instanceof Error ? err.message : "Unknown error",
timestamp: /* @__PURE__ */ new Date()
}
};
}
}
}
export {
BatchBuilder
};
//# sourceMappingURL=batch-builder.js.map