rankrunners-cms 0.0.33 → 0.0.35
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/package.json +3 -3
- package/src/api/client/form-fills.ts +79 -0
- package/src/api/client/index.ts +3 -0
- package/src/api/types/form-fills.ts +71 -0
- package/src/api/types/index.ts +1 -0
- package/test/test.ts +25 -0
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rankrunners-cms",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.35",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@puckeditor/core": "^0.21.1",
|
|
7
|
-
"@tanstack/react-router": "^1.166.
|
|
8
|
-
"@tanstack/router-core": "^1.166.
|
|
7
|
+
"@tanstack/react-router": "^1.166.7",
|
|
8
|
+
"@tanstack/router-core": "^1.166.7",
|
|
9
9
|
"lucide-react": "^0.577.0",
|
|
10
10
|
"next": "^16.1.6",
|
|
11
11
|
"react": "^19.2.4",
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safeParse,
|
|
3
|
+
type BaseIssue,
|
|
4
|
+
type BaseSchema,
|
|
5
|
+
type InferInput,
|
|
6
|
+
} from "valibot";
|
|
7
|
+
import { CMS_BASE_URL, SITE_ID } from "../constants";
|
|
8
|
+
import type { FormFillSubmissionDTO } from "../types/form-fills";
|
|
9
|
+
import { SendFormFillResult } from "../types/form-fills";
|
|
10
|
+
|
|
11
|
+
export type SendFormFillArgs<
|
|
12
|
+
A,
|
|
13
|
+
B,
|
|
14
|
+
C extends BaseIssue<unknown>,
|
|
15
|
+
T extends BaseSchema<A, B, C>,
|
|
16
|
+
> = {
|
|
17
|
+
type: string;
|
|
18
|
+
schema: T;
|
|
19
|
+
fieldNames: Record<string, string>;
|
|
20
|
+
data: InferInput<T>;
|
|
21
|
+
captchaToken: string;
|
|
22
|
+
test?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const sendFormFill = async <
|
|
26
|
+
A,
|
|
27
|
+
B,
|
|
28
|
+
C extends BaseIssue<unknown>,
|
|
29
|
+
T extends BaseSchema<A, B, C>,
|
|
30
|
+
>(
|
|
31
|
+
args: SendFormFillArgs<A, B, C, T>,
|
|
32
|
+
): Promise<SendFormFillResult> => {
|
|
33
|
+
const formToSend = safeParse(args.schema, args.data);
|
|
34
|
+
|
|
35
|
+
if (!formToSend.success) {
|
|
36
|
+
console.error("Form fill validation failed:", formToSend.issues);
|
|
37
|
+
return SendFormFillResult.ValidationError;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const data: FormFillSubmissionDTO = {
|
|
41
|
+
siteId: SITE_ID,
|
|
42
|
+
type: args.type,
|
|
43
|
+
data: args.data as Record<string, string>,
|
|
44
|
+
schema: {
|
|
45
|
+
schema: JSON.stringify(args.schema),
|
|
46
|
+
fields: args.fieldNames,
|
|
47
|
+
},
|
|
48
|
+
captchaToken: args.captchaToken,
|
|
49
|
+
test: args.test,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const response = await fetch(`${CMS_BASE_URL}/form-fills/public`, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: {
|
|
56
|
+
"Content-Type": "application/json",
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify(data),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (response.ok) {
|
|
62
|
+
return SendFormFillResult.Success;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.error("Form fill submission failed with status:", response.status);
|
|
66
|
+
return SendFormFillResult.UnknownError;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error("Error sending form fill:", error);
|
|
69
|
+
if (error instanceof Error) {
|
|
70
|
+
if (error.message.includes("validation")) {
|
|
71
|
+
return SendFormFillResult.ValidationError;
|
|
72
|
+
}
|
|
73
|
+
if (error.message.includes("captcha")) {
|
|
74
|
+
return SendFormFillResult.CaptchaError;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return SendFormFillResult.UnknownError;
|
|
78
|
+
}
|
|
79
|
+
};
|
package/src/api/client/index.ts
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
object,
|
|
3
|
+
record,
|
|
4
|
+
string,
|
|
5
|
+
pipe,
|
|
6
|
+
nonEmpty,
|
|
7
|
+
boolean,
|
|
8
|
+
optional,
|
|
9
|
+
type InferOutput,
|
|
10
|
+
type InferInput,
|
|
11
|
+
} from "valibot";
|
|
12
|
+
import { IdSchema } from "./common";
|
|
13
|
+
|
|
14
|
+
// Schema field definition - describes a single field in the form
|
|
15
|
+
export const FormFillSchemaDataSchema = object({
|
|
16
|
+
schema: string(), // Serialized validation rule (fromValibot / toValibot - rankrunners-cms/src/lib/valibot)
|
|
17
|
+
fields: record(
|
|
18
|
+
string(), // Field key
|
|
19
|
+
pipe(string(), nonEmpty("Field label is required")), // Field label
|
|
20
|
+
),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type FormFillSchemaDataDTO = InferOutput<
|
|
24
|
+
typeof FormFillSchemaDataSchema
|
|
25
|
+
>;
|
|
26
|
+
|
|
27
|
+
// Form Fill Data Structure - simple key-value record
|
|
28
|
+
export const FormFillDataSchema = record(
|
|
29
|
+
string(), // Field key
|
|
30
|
+
pipe(string(), nonEmpty("Field value is required")), // Field value
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export type FormFillDataDTO = InferOutput<typeof FormFillDataSchema>;
|
|
34
|
+
|
|
35
|
+
// API Schemas
|
|
36
|
+
|
|
37
|
+
// 1. Submission (Public API)
|
|
38
|
+
export const FormFillSubmissionSchema = object({
|
|
39
|
+
siteId: IdSchema, // Site ID must be passed in the body for public submission
|
|
40
|
+
type: pipe(string(), nonEmpty("Form type is required")),
|
|
41
|
+
data: FormFillDataSchema,
|
|
42
|
+
schema: FormFillSchemaDataSchema,
|
|
43
|
+
captchaToken: pipe(string(), nonEmpty("Captcha token is required")),
|
|
44
|
+
test: optional(boolean()),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export type FormFillSubmissionDTO = InferInput<typeof FormFillSubmissionSchema>;
|
|
48
|
+
|
|
49
|
+
export enum SendFormFillResult {
|
|
50
|
+
Success = "success",
|
|
51
|
+
ValidationError = "validation_error",
|
|
52
|
+
CaptchaError = "captcha_error",
|
|
53
|
+
InvalidResponse = "invalid_response",
|
|
54
|
+
UnknownError = "unknown_error",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const formFillResultToMessage = (result: SendFormFillResult): string => {
|
|
58
|
+
switch (result) {
|
|
59
|
+
case SendFormFillResult.Success:
|
|
60
|
+
return "Form submitted successfully!";
|
|
61
|
+
case SendFormFillResult.ValidationError:
|
|
62
|
+
return "There was a validation error with your submission. Please check your input and try again.";
|
|
63
|
+
case SendFormFillResult.CaptchaError:
|
|
64
|
+
return "Captcha verification failed. Please complete the captcha and try again.";
|
|
65
|
+
case SendFormFillResult.InvalidResponse:
|
|
66
|
+
return "An internal error occurred while submitting the form. Please call us instead!";
|
|
67
|
+
case SendFormFillResult.UnknownError:
|
|
68
|
+
default:
|
|
69
|
+
return "An unknown error occurred while submitting the form. Please try again later, or try calling us!";
|
|
70
|
+
}
|
|
71
|
+
};
|
package/src/api/types/index.ts
CHANGED
package/test/test.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { serializeSigned } from "hono/utils/cookie";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
import { fromValibot, toValibot } from "rankrunners-cms/src/libs/valibot-serialize";
|
|
4
|
+
|
|
5
|
+
export const TestSchema = v.object({
|
|
6
|
+
username: v.string(),
|
|
7
|
+
fullname: v.string(),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const serializedSchema = fromValibot(TestSchema);
|
|
11
|
+
const deserializedValidator = toValibot(serializedSchema);
|
|
12
|
+
|
|
13
|
+
let data: string;
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
data = JSON.stringify(v.parse(deserializedValidator, {
|
|
17
|
+
username: "testuser",
|
|
18
|
+
fullname: "Test User"
|
|
19
|
+
}));
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error("Validation failed:", error);
|
|
22
|
+
data = "Validation failed";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log("Deserialized and validated data:", data);
|