@proofkit/better-auth 0.3.0 → 0.3.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/adapter.d.ts +6 -7
- package/dist/esm/adapter.js +48 -25
- package/dist/esm/adapter.js.map +1 -1
- package/dist/esm/better-auth-cli/utils/add-svelte-kit-env-modules.js +4 -12
- package/dist/esm/better-auth-cli/utils/add-svelte-kit-env-modules.js.map +1 -1
- package/dist/esm/better-auth-cli/utils/get-config.js +12 -21
- package/dist/esm/better-auth-cli/utils/get-config.js.map +1 -1
- package/dist/esm/better-auth-cli/utils/get-tsconfig-info.js +4 -11
- package/dist/esm/better-auth-cli/utils/get-tsconfig-info.js.map +1 -1
- package/dist/esm/cli/index.js +11 -25
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/migrate.d.ts +7 -3
- package/dist/esm/migrate.js +70 -50
- package/dist/esm/migrate.js.map +1 -1
- package/dist/esm/odata/index.d.ts +6 -6
- package/dist/esm/odata/index.js +18 -60
- package/dist/esm/odata/index.js.map +1 -1
- package/package.json +21 -17
- package/src/adapter.ts +62 -44
- package/src/better-auth-cli/utils/add-svelte-kit-env-modules.ts +68 -80
- package/src/better-auth-cli/utils/get-config.ts +16 -30
- package/src/better-auth-cli/utils/get-tsconfig-info.ts +12 -20
- package/src/cli/index.ts +12 -31
- package/src/index.ts +1 -0
- package/src/migrate.ts +87 -79
- package/src/odata/index.ts +29 -73
package/src/migrate.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type Metadata } from "fm-odata-client";
|
|
1
|
+
import type { DBFieldAttribute } from "better-auth/db";
|
|
3
2
|
import chalk from "chalk";
|
|
3
|
+
import type { Metadata } from "fm-odata-client";
|
|
4
4
|
import z from "zod/v4";
|
|
5
|
-
import { createRawFetch } from "./odata";
|
|
5
|
+
import type { createRawFetch } from "./odata";
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
) {
|
|
7
|
+
/** Schema type returned by better-auth's getSchema function */
|
|
8
|
+
type BetterAuthSchema = Record<string, { fields: Record<string, DBFieldAttribute>; order: number }>;
|
|
9
|
+
|
|
10
|
+
function normalizeBetterAuthFieldType(fieldType: unknown): string {
|
|
11
|
+
if (typeof fieldType === "string") {
|
|
12
|
+
return fieldType;
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(fieldType)) {
|
|
15
|
+
return fieldType.map(String).join("|");
|
|
16
|
+
}
|
|
17
|
+
return String(fieldType);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function getMetadata(fetch: ReturnType<typeof createRawFetch>["fetch"], databaseName: string) {
|
|
11
21
|
console.log("getting metadata...");
|
|
12
22
|
const result = await fetch("/$metadata", {
|
|
13
23
|
method: "GET",
|
|
@@ -31,13 +41,13 @@ export async function getMetadata(
|
|
|
31
41
|
|
|
32
42
|
export async function planMigration(
|
|
33
43
|
fetch: ReturnType<typeof createRawFetch>["fetch"],
|
|
34
|
-
betterAuthSchema:
|
|
44
|
+
betterAuthSchema: BetterAuthSchema,
|
|
35
45
|
databaseName: string,
|
|
36
46
|
): Promise<MigrationPlan> {
|
|
37
47
|
const metadata = await getMetadata(fetch, databaseName);
|
|
38
48
|
|
|
39
49
|
// Build a map from entity set name to entity type key
|
|
40
|
-
|
|
50
|
+
const entitySetToType: Record<string, string> = {};
|
|
41
51
|
if (metadata) {
|
|
42
52
|
for (const [key, value] of Object.entries(metadata)) {
|
|
43
53
|
if (value.$Kind === "EntitySet" && value.$Type) {
|
|
@@ -52,27 +62,32 @@ export async function planMigration(
|
|
|
52
62
|
? Object.entries(entitySetToType).reduce(
|
|
53
63
|
(acc, [entitySetName, entityTypeKey]) => {
|
|
54
64
|
const entityType = metadata[entityTypeKey];
|
|
55
|
-
if (!entityType)
|
|
65
|
+
if (!entityType) {
|
|
66
|
+
return acc;
|
|
67
|
+
}
|
|
56
68
|
const fields = Object.entries(entityType)
|
|
57
69
|
.filter(
|
|
58
|
-
([
|
|
59
|
-
typeof fieldValue === "object" &&
|
|
60
|
-
fieldValue !== null &&
|
|
61
|
-
"$Type" in fieldValue,
|
|
70
|
+
([_fieldKey, fieldValue]) =>
|
|
71
|
+
typeof fieldValue === "object" && fieldValue !== null && "$Type" in fieldValue,
|
|
62
72
|
)
|
|
63
|
-
.map(([fieldKey, fieldValue]) =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
.map(([fieldKey, fieldValue]) => {
|
|
74
|
+
let type = "varchar";
|
|
75
|
+
if (fieldValue.$Type === "Edm.String") {
|
|
76
|
+
type = "varchar";
|
|
77
|
+
} else if (fieldValue.$Type === "Edm.DateTimeOffset") {
|
|
78
|
+
type = "timestamp";
|
|
79
|
+
} else if (
|
|
80
|
+
fieldValue.$Type === "Edm.Decimal" ||
|
|
81
|
+
fieldValue.$Type === "Edm.Int32" ||
|
|
82
|
+
fieldValue.$Type === "Edm.Int64"
|
|
83
|
+
) {
|
|
84
|
+
type = "numeric";
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
name: fieldKey,
|
|
88
|
+
type,
|
|
89
|
+
};
|
|
90
|
+
});
|
|
76
91
|
acc[entitySetName] = fields;
|
|
77
92
|
return acc;
|
|
78
93
|
},
|
|
@@ -84,48 +99,34 @@ export async function planMigration(
|
|
|
84
99
|
.sort((a, b) => (a[1].order ?? 0) - (b[1].order ?? 0))
|
|
85
100
|
.map(([key, value]) => ({
|
|
86
101
|
...value,
|
|
87
|
-
|
|
102
|
+
modelName: key, // Use the key as modelName since getSchema uses table names as keys
|
|
88
103
|
}));
|
|
89
104
|
|
|
90
105
|
const migrationPlan: MigrationPlan = [];
|
|
91
106
|
|
|
92
107
|
for (const baTable of baTables) {
|
|
93
|
-
const fields: FmField[] = Object.entries(baTable.fields).map(
|
|
94
|
-
|
|
108
|
+
const fields: FmField[] = Object.entries(baTable.fields).map(([key, field]) => {
|
|
109
|
+
// Better Auth's FieldType can be a string literal union or arrays.
|
|
110
|
+
// Normalize it to a string so our FM mapping logic remains stable.
|
|
111
|
+
// Use .includes() for all checks to handle array types like ["boolean", "null"] → "boolean|null"
|
|
112
|
+
const t = normalizeBetterAuthFieldType(field.type);
|
|
113
|
+
let type: "varchar" | "numeric" | "timestamp" = "varchar";
|
|
114
|
+
if (t.includes("boolean") || t.includes("number")) {
|
|
115
|
+
type = "numeric";
|
|
116
|
+
} else if (t.includes("date")) {
|
|
117
|
+
type = "timestamp";
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
95
120
|
name: field.fieldName ?? key,
|
|
96
|
-
type
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
: field.type === "date"
|
|
100
|
-
? "timestamp"
|
|
101
|
-
: "varchar",
|
|
102
|
-
}),
|
|
103
|
-
);
|
|
121
|
+
type,
|
|
122
|
+
};
|
|
123
|
+
});
|
|
104
124
|
|
|
105
125
|
// get existing table or create it
|
|
106
|
-
const tableExists =
|
|
107
|
-
existingTables,
|
|
108
|
-
baTable.modelName,
|
|
109
|
-
);
|
|
126
|
+
const tableExists = baTable.modelName in existingTables;
|
|
110
127
|
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
-
tableName: baTable.modelName,
|
|
114
|
-
operation: "create",
|
|
115
|
-
fields: [
|
|
116
|
-
{
|
|
117
|
-
name: "id",
|
|
118
|
-
type: "varchar",
|
|
119
|
-
primary: true,
|
|
120
|
-
unique: true,
|
|
121
|
-
},
|
|
122
|
-
...fields,
|
|
123
|
-
],
|
|
124
|
-
});
|
|
125
|
-
} else {
|
|
126
|
-
const existingFields = (existingTables[baTable.modelName] || []).map(
|
|
127
|
-
(f) => f.name,
|
|
128
|
-
);
|
|
128
|
+
if (tableExists) {
|
|
129
|
+
const existingFields = (existingTables[baTable.modelName] || []).map((f) => f.name);
|
|
129
130
|
const existingFieldMap = (existingTables[baTable.modelName] || []).reduce(
|
|
130
131
|
(acc, f) => {
|
|
131
132
|
acc[f.name] = f.type;
|
|
@@ -134,19 +135,14 @@ export async function planMigration(
|
|
|
134
135
|
{} as Record<string, string>,
|
|
135
136
|
);
|
|
136
137
|
// Warn about type mismatches (optional, not in plan)
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
existingFields.includes(field.name) &&
|
|
140
|
-
existingFieldMap[field.name] !== field.type
|
|
141
|
-
) {
|
|
138
|
+
for (const field of fields) {
|
|
139
|
+
if (existingFields.includes(field.name) && existingFieldMap[field.name] !== field.type) {
|
|
142
140
|
console.warn(
|
|
143
141
|
`⚠️ WARNING: Field '${field.name}' in table '${baTable.modelName}' exists but has type '${existingFieldMap[field.name]}' (expected '${field.type}'). Change the field type in FileMaker to avoid potential errors.`,
|
|
144
142
|
);
|
|
145
143
|
}
|
|
146
|
-
}
|
|
147
|
-
const fieldsToAdd = fields.filter(
|
|
148
|
-
(f) => !existingFields.includes(f.name),
|
|
149
|
-
);
|
|
144
|
+
}
|
|
145
|
+
const fieldsToAdd = fields.filter((f) => !existingFields.includes(f.name));
|
|
150
146
|
if (fieldsToAdd.length > 0) {
|
|
151
147
|
migrationPlan.push({
|
|
152
148
|
tableName: baTable.modelName,
|
|
@@ -154,6 +150,20 @@ export async function planMigration(
|
|
|
154
150
|
fields: fieldsToAdd,
|
|
155
151
|
});
|
|
156
152
|
}
|
|
153
|
+
} else {
|
|
154
|
+
migrationPlan.push({
|
|
155
|
+
tableName: baTable.modelName,
|
|
156
|
+
operation: "create",
|
|
157
|
+
fields: [
|
|
158
|
+
{
|
|
159
|
+
name: "id",
|
|
160
|
+
type: "varchar",
|
|
161
|
+
primary: true,
|
|
162
|
+
unique: true,
|
|
163
|
+
},
|
|
164
|
+
...fields,
|
|
165
|
+
],
|
|
166
|
+
});
|
|
157
167
|
}
|
|
158
168
|
}
|
|
159
169
|
|
|
@@ -176,10 +186,7 @@ export async function executeMigration(
|
|
|
176
186
|
});
|
|
177
187
|
|
|
178
188
|
if (result.error) {
|
|
179
|
-
console.error(
|
|
180
|
-
`Failed to create table ${step.tableName}:`,
|
|
181
|
-
result.error,
|
|
182
|
-
);
|
|
189
|
+
console.error(`Failed to create table ${step.tableName}:`, result.error);
|
|
183
190
|
throw new Error(`Migration failed: ${result.error}`);
|
|
184
191
|
}
|
|
185
192
|
} else if (step.operation === "update") {
|
|
@@ -190,10 +197,7 @@ export async function executeMigration(
|
|
|
190
197
|
});
|
|
191
198
|
|
|
192
199
|
if (result.error) {
|
|
193
|
-
console.error(
|
|
194
|
-
`Failed to update table ${step.tableName}:`,
|
|
195
|
-
result.error,
|
|
196
|
-
);
|
|
200
|
+
console.error(`Failed to update table ${step.tableName}:`, result.error);
|
|
197
201
|
throw new Error(`Migration failed: ${result.error}`);
|
|
198
202
|
}
|
|
199
203
|
}
|
|
@@ -274,8 +278,12 @@ export function prettyPrintMigrationPlan(migrationPlan: MigrationPlan) {
|
|
|
274
278
|
if (step.fields.length) {
|
|
275
279
|
for (const field of step.fields) {
|
|
276
280
|
let fieldDesc = ` - ${field.name} (${field.type}`;
|
|
277
|
-
if (field.primary)
|
|
278
|
-
|
|
281
|
+
if (field.primary) {
|
|
282
|
+
fieldDesc += ", primary";
|
|
283
|
+
}
|
|
284
|
+
if (field.unique) {
|
|
285
|
+
fieldDesc += ", unique";
|
|
286
|
+
}
|
|
279
287
|
fieldDesc += ")";
|
|
280
288
|
console.log(fieldDesc);
|
|
281
289
|
}
|
package/src/odata/index.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: library code */
|
|
1
2
|
import { logger as betterAuthLogger } from "better-auth";
|
|
2
|
-
import { err, ok, Result } from "neverthrow";
|
|
3
|
-
import { z } from "zod/v4";
|
|
3
|
+
import { err, ok, type Result } from "neverthrow";
|
|
4
|
+
import type { z } from "zod/v4";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
interface BasicAuthCredentials {
|
|
6
7
|
username: string;
|
|
7
8
|
password: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
9
|
+
}
|
|
10
|
+
interface OttoAPIKeyAuth {
|
|
10
11
|
apiKey: string;
|
|
11
|
-
}
|
|
12
|
+
}
|
|
12
13
|
type ODataAuth = BasicAuthCredentials | OttoAPIKeyAuth;
|
|
13
14
|
|
|
14
|
-
export
|
|
15
|
+
export interface FmOdataConfig {
|
|
15
16
|
serverUrl: string;
|
|
16
17
|
auth: ODataAuth;
|
|
17
18
|
database: string;
|
|
18
19
|
logging?: true | "verbose" | "none";
|
|
19
|
-
}
|
|
20
|
+
}
|
|
20
21
|
|
|
21
22
|
export function validateUrl(input: string): Result<URL, unknown> {
|
|
22
23
|
try {
|
|
@@ -36,7 +37,7 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
36
37
|
|
|
37
38
|
let baseURL = result.value.origin;
|
|
38
39
|
if ("apiKey" in args.auth) {
|
|
39
|
-
baseURL +=
|
|
40
|
+
baseURL += "/otto";
|
|
40
41
|
}
|
|
41
42
|
baseURL += `/fmi/odata/v4/${args.database}`;
|
|
42
43
|
|
|
@@ -63,9 +64,7 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
63
64
|
// Handle different input types
|
|
64
65
|
if (typeof input === "string") {
|
|
65
66
|
// If it's already a full URL, use as-is, otherwise prepend baseURL
|
|
66
|
-
url = input.startsWith("http")
|
|
67
|
-
? input
|
|
68
|
-
: `${baseURL}${input.startsWith("/") ? input : `/${input}`}`;
|
|
67
|
+
url = input.startsWith("http") ? input : `${baseURL}${input.startsWith("/") ? input : `/${input}`}`;
|
|
69
68
|
} else if (input instanceof URL) {
|
|
70
69
|
url = input.toString();
|
|
71
70
|
} else if (input instanceof Request) {
|
|
@@ -101,10 +100,7 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
101
100
|
|
|
102
101
|
// Optional logging
|
|
103
102
|
if (args.logging === "verbose" || args.logging === true) {
|
|
104
|
-
betterAuthLogger.info(
|
|
105
|
-
"raw-fetch",
|
|
106
|
-
`${requestInit.method || "GET"} ${url}`,
|
|
107
|
-
);
|
|
103
|
+
betterAuthLogger.info("raw-fetch", `${requestInit.method || "GET"} ${url}`);
|
|
108
104
|
if (requestInit.body) {
|
|
109
105
|
betterAuthLogger.info("raw-fetch", "Request body:", requestInit.body);
|
|
110
106
|
}
|
|
@@ -114,25 +110,15 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
114
110
|
|
|
115
111
|
// Optional logging for response details
|
|
116
112
|
if (args.logging === "verbose" || args.logging === true) {
|
|
117
|
-
betterAuthLogger.info(
|
|
118
|
-
|
|
119
|
-
`Response status: ${response.status} ${response.statusText}`,
|
|
120
|
-
);
|
|
121
|
-
betterAuthLogger.info(
|
|
122
|
-
"raw-fetch",
|
|
123
|
-
`Response headers:`,
|
|
124
|
-
Object.fromEntries(response.headers.entries()),
|
|
125
|
-
);
|
|
113
|
+
betterAuthLogger.info("raw-fetch", `Response status: ${response.status} ${response.statusText}`);
|
|
114
|
+
betterAuthLogger.info("raw-fetch", "Response headers:", Object.fromEntries(response.headers.entries()));
|
|
126
115
|
}
|
|
127
116
|
|
|
128
117
|
// Check if response is ok
|
|
129
118
|
if (!response.ok) {
|
|
130
119
|
const errorText = await response.text().catch(() => "Unknown error");
|
|
131
120
|
if (args.logging === "verbose" || args.logging === true) {
|
|
132
|
-
betterAuthLogger.error(
|
|
133
|
-
"raw-fetch",
|
|
134
|
-
`HTTP Error ${response.status}: ${errorText}`,
|
|
135
|
-
);
|
|
121
|
+
betterAuthLogger.error("raw-fetch", `HTTP Error ${response.status}: ${errorText}`);
|
|
136
122
|
}
|
|
137
123
|
return {
|
|
138
124
|
error: `HTTP ${response.status}: ${errorText}`,
|
|
@@ -145,51 +131,32 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
145
131
|
const contentType = response.headers.get("content-type");
|
|
146
132
|
|
|
147
133
|
if (args.logging === "verbose" || args.logging === true) {
|
|
148
|
-
betterAuthLogger.info(
|
|
149
|
-
"raw-fetch",
|
|
150
|
-
`Response content-type: ${contentType || "none"}`,
|
|
151
|
-
);
|
|
134
|
+
betterAuthLogger.info("raw-fetch", `Response content-type: ${contentType || "none"}`);
|
|
152
135
|
}
|
|
153
136
|
|
|
154
137
|
if (contentType?.includes("application/json")) {
|
|
155
138
|
try {
|
|
156
139
|
const responseText = await response.text();
|
|
157
140
|
if (args.logging === "verbose" || args.logging === true) {
|
|
158
|
-
betterAuthLogger.info(
|
|
159
|
-
|
|
160
|
-
`Raw response text: "${responseText}"`,
|
|
161
|
-
);
|
|
162
|
-
betterAuthLogger.info(
|
|
163
|
-
"raw-fetch",
|
|
164
|
-
`Response text length: ${responseText.length}`,
|
|
165
|
-
);
|
|
141
|
+
betterAuthLogger.info("raw-fetch", `Raw response text: "${responseText}"`);
|
|
142
|
+
betterAuthLogger.info("raw-fetch", `Response text length: ${responseText.length}`);
|
|
166
143
|
}
|
|
167
144
|
|
|
168
145
|
// Handle empty responses
|
|
169
146
|
if (responseText.trim() === "") {
|
|
170
147
|
if (args.logging === "verbose" || args.logging === true) {
|
|
171
|
-
betterAuthLogger.info(
|
|
172
|
-
"raw-fetch",
|
|
173
|
-
"Empty JSON response, returning null",
|
|
174
|
-
);
|
|
148
|
+
betterAuthLogger.info("raw-fetch", "Empty JSON response, returning null");
|
|
175
149
|
}
|
|
176
150
|
responseData = null;
|
|
177
151
|
} else {
|
|
178
152
|
responseData = JSON.parse(responseText);
|
|
179
153
|
if (args.logging === "verbose" || args.logging === true) {
|
|
180
|
-
betterAuthLogger.info(
|
|
181
|
-
"raw-fetch",
|
|
182
|
-
"Successfully parsed JSON response",
|
|
183
|
-
);
|
|
154
|
+
betterAuthLogger.info("raw-fetch", "Successfully parsed JSON response");
|
|
184
155
|
}
|
|
185
156
|
}
|
|
186
157
|
} catch (parseError) {
|
|
187
158
|
if (args.logging === "verbose" || args.logging === true) {
|
|
188
|
-
betterAuthLogger.error(
|
|
189
|
-
"raw-fetch",
|
|
190
|
-
"JSON parse error:",
|
|
191
|
-
parseError,
|
|
192
|
-
);
|
|
159
|
+
betterAuthLogger.error("raw-fetch", "JSON parse error:", parseError);
|
|
193
160
|
}
|
|
194
161
|
return {
|
|
195
162
|
error: `Failed to parse JSON response: ${parseError instanceof Error ? parseError.message : "Unknown parse error"}`,
|
|
@@ -200,29 +167,20 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
200
167
|
// Handle text responses (text/plain, text/html, etc.)
|
|
201
168
|
responseData = await response.text();
|
|
202
169
|
if (args.logging === "verbose" || args.logging === true) {
|
|
203
|
-
betterAuthLogger.info(
|
|
204
|
-
"raw-fetch",
|
|
205
|
-
`Text response: "${responseData}"`,
|
|
206
|
-
);
|
|
170
|
+
betterAuthLogger.info("raw-fetch", `Text response: "${responseData}"`);
|
|
207
171
|
}
|
|
208
172
|
} else {
|
|
209
173
|
// For other content types, try to get text but don't fail if it's binary
|
|
210
174
|
try {
|
|
211
175
|
responseData = await response.text();
|
|
212
176
|
if (args.logging === "verbose" || args.logging === true) {
|
|
213
|
-
betterAuthLogger.info(
|
|
214
|
-
"raw-fetch",
|
|
215
|
-
`Unknown content-type response as text: "${responseData}"`,
|
|
216
|
-
);
|
|
177
|
+
betterAuthLogger.info("raw-fetch", `Unknown content-type response as text: "${responseData}"`);
|
|
217
178
|
}
|
|
218
179
|
} catch {
|
|
219
180
|
// If text parsing fails (e.g., binary data), return null
|
|
220
181
|
responseData = null;
|
|
221
182
|
if (args.logging === "verbose" || args.logging === true) {
|
|
222
|
-
betterAuthLogger.info(
|
|
223
|
-
"raw-fetch",
|
|
224
|
-
"Could not parse response as text, returning null",
|
|
225
|
-
);
|
|
183
|
+
betterAuthLogger.info("raw-fetch", "Could not parse response as text, returning null");
|
|
226
184
|
}
|
|
227
185
|
}
|
|
228
186
|
}
|
|
@@ -235,12 +193,11 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
235
193
|
data: validation.data,
|
|
236
194
|
response,
|
|
237
195
|
};
|
|
238
|
-
} else {
|
|
239
|
-
return {
|
|
240
|
-
error: `Validation failed: ${validation.error.message}`,
|
|
241
|
-
response,
|
|
242
|
-
};
|
|
243
196
|
}
|
|
197
|
+
return {
|
|
198
|
+
error: `Validation failed: ${validation.error.message}`,
|
|
199
|
+
response,
|
|
200
|
+
};
|
|
244
201
|
}
|
|
245
202
|
|
|
246
203
|
// Return unvalidated data
|
|
@@ -250,8 +207,7 @@ export function createRawFetch(args: FmOdataConfig) {
|
|
|
250
207
|
};
|
|
251
208
|
} catch (error) {
|
|
252
209
|
return {
|
|
253
|
-
error:
|
|
254
|
-
error instanceof Error ? error.message : "Unknown error occurred",
|
|
210
|
+
error: error instanceof Error ? error.message : "Unknown error occurred",
|
|
255
211
|
};
|
|
256
212
|
}
|
|
257
213
|
};
|