@fragno-dev/forms 0.0.3 → 0.1.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/README.md +159 -25
- package/dist/browser/client/react.d.ts +143 -94
- package/dist/browser/client/react.d.ts.map +1 -1
- package/dist/browser/client/react.js +105 -13
- package/dist/browser/client/react.js.map +1 -1
- package/dist/browser/client/solid.d.ts +143 -94
- package/dist/browser/client/solid.d.ts.map +1 -1
- package/dist/browser/client/solid.js +25 -11
- package/dist/browser/client/solid.js.map +1 -1
- package/dist/browser/client/svelte.d.ts +143 -94
- package/dist/browser/client/svelte.d.ts.map +1 -1
- package/dist/browser/client/svelte.js +11 -3
- package/dist/browser/client/svelte.js.map +1 -1
- package/dist/browser/client/vanilla.d.ts +142 -93
- package/dist/browser/client/vanilla.d.ts.map +1 -1
- package/dist/browser/client/vanilla.js +21 -1
- package/dist/browser/client/vanilla.js.map +1 -1
- package/dist/browser/client/vue.d.ts +73 -24
- package/dist/browser/client/vue.d.ts.map +1 -1
- package/dist/browser/client/vue.js +23 -1
- package/dist/browser/client/vue.js.map +1 -1
- package/dist/browser/index.d.ts +700 -301
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/{src-DbMX_NY6.js → src-BNcd9ogF.js} +556 -348
- package/dist/browser/src-BNcd9ogF.js.map +1 -0
- package/dist/node/index.d.ts +546 -147
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +133 -103
- package/dist/node/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +31 -52
- package/dist/browser/src-DbMX_NY6.js.map +0 -1
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["form: T","response: T","input: NewForm","id: string","slug: string","input: UpdateForm","schema: Schema","data: Record<string, unknown>","schema","formId: string","formVersion: number","data: ValidatedData","metadata?: { ip?: string | null; userAgent?: string | null }","sort: SubmissionSortOptions","headers: Headers","sf: StaticForm","config: FormsConfig","options: FragnoPublicConfigWithDatabase","fragnoConfig: FragnoPublicClientConfig"],"sources":["../../src/schema.ts","../../src/definition.ts","../../src/models.ts","../../src/routes.ts","../../src/index.ts"],"sourcesContent":["import { column, idColumn, schema } from \"@fragno-dev/db/schema\";\n\nexport const formsSchema = schema((s) => {\n return s\n .addTable(\"form\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"title\", column(\"string\"))\n .addColumn(\"description\", column(\"string\").nullable())\n .addColumn(\"slug\", column(\"string\"))\n .addColumn(\n \"status\",\n column(\"string\").defaultTo(() => \"draft\"),\n )\n .addColumn(\"dataSchema\", column(\"json\"))\n .addColumn(\"uiSchema\", column(\"json\"))\n .addColumn(\n \"version\",\n column(\"integer\").defaultTo(() => 1),\n )\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_form_status\", [\"status\"])\n .createIndex(\"idx_form_slug\", [\"slug\"], { unique: true });\n })\n .addTable(\"response\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"formId\", column(\"string\"))\n .addColumn(\"formVersion\", column(\"integer\"))\n .addColumn(\"data\", column(\"json\"))\n .addColumn(\n \"submittedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"userAgent\", column(\"string\").nullable())\n .addColumn(\"ip\", column(\"string\").nullable())\n .createIndex(\"idx_response_form\", [\"formId\"])\n .createIndex(\"idx_response_submitted_at\", [\"submittedAt\"]);\n });\n});\n","import { defineFragment } from \"@fragno-dev/core\";\nimport { withDatabase } from \"@fragno-dev/db\";\nimport { formsSchema } from \"./schema\";\nimport type { FormsConfig } from \".\";\nimport type { JSONSchema, NewForm, UpdateForm, FormStatus, UIElementSchema } from \"./models\";\nimport { Validator, type Schema } from \"@cfworker/json-schema\";\n\nexport type ValidatedData<T = Record<string, unknown>> = T;\nexport type ValidationResult =\n | { success: true; data: ValidatedData }\n | {\n success: false;\n error: { message: string; errors: Array<{ path: string; message: string }> };\n };\n\n// External to this fragment\nconst asExternalForm = <\n T extends { id: { externalId: string }; status: string; dataSchema: unknown; uiSchema: unknown },\n>(\n form: T,\n) => ({\n ...form,\n id: form.id.externalId,\n status: form.status as FormStatus,\n dataSchema: form.dataSchema as JSONSchema,\n uiSchema: form.uiSchema as UIElementSchema,\n});\n\nconst asExternalResponse = <\n T extends {\n id: { externalId: string };\n formId: string | null;\n data: unknown;\n ip: string | null;\n userAgent: string | null;\n },\n>(\n response: T,\n) => ({\n ...response,\n id: response.id.externalId,\n data: response.data as Record<string, unknown>,\n});\n\nexport interface SubmissionSortOptions {\n field: \"submittedAt\";\n order: \"asc\" | \"desc\";\n}\n\nexport const formsFragmentDef = defineFragment<FormsConfig>(\"forms\")\n .extend(withDatabase(formsSchema))\n .withDependencies(({ db }) => ({ db }))\n .providesBaseService(({ deps }) => {\n return {\n createForm: async (input: NewForm) => {\n return (await deps.db.create(\"form\", input)).externalId;\n },\n\n getForm: async (id: string) => {\n const form = await deps.db.findFirst(\"form\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", id)),\n );\n return form ? asExternalForm(form) : null;\n },\n\n getFormBySlug: async (slug: string) => {\n const form = await deps.db.findFirst(\"form\", (b) =>\n b.whereIndex(\"idx_form_slug\", (eb) => eb(\"slug\", \"=\", slug)),\n );\n return form ? asExternalForm(form) : null;\n },\n\n updateForm: async (id: string, input: UpdateForm) => {\n const uow = deps.db\n .createUnitOfWork()\n .find(\"form\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", id)));\n\n const [currentForms] = await uow.executeRetrieve();\n\n if (currentForms.length === 0) {\n return { success: false };\n }\n // TODO: length > 1 ?\n\n const currentForm = currentForms[0];\n\n // Only increment version if changing data schema\n const newVersion = input.dataSchema ? currentForm.version + 1 : currentForm.version;\n\n uow.update(\"form\", currentForm.id, (b) => {\n b.set({ ...input, version: newVersion, updatedAt: new Date() }).check();\n });\n return uow.executeMutations();\n },\n\n listForms: async () => {\n const forms = await deps.db.find(\"form\", (b) => b.whereIndex(\"primary\"));\n return forms.map(asExternalForm);\n },\n\n deleteForm: async (id: string) => {\n await deps.db.delete(\"form\", id);\n },\n\n validateData: (schema: Schema, data: Record<string, unknown>): ValidationResult => {\n const validator = new Validator(schema);\n const result = validator.validate(data);\n\n if (result.valid) {\n return { success: true, data: data as ValidatedData };\n }\n console.error(\"ERROR\", JSON.stringify(result.errors));\n return {\n success: false,\n // TODO: better error type for validation errors?\n // see: https://jsonforms.io/docs/validation/#external-validation-errors\n error: {\n message: \"Validation failed\",\n errors: result.errors.map((e) => ({\n path: e.instanceLocation || \"\",\n message: e.error ?? \"Invalid value\",\n })),\n },\n };\n },\n\n createResponse: async (\n formId: string,\n formVersion: number,\n data: ValidatedData,\n metadata?: { ip?: string | null; userAgent?: string | null },\n ) => {\n return (\n await deps.db.create(\"response\", {\n formId,\n formVersion,\n data,\n ip: metadata?.ip ?? null,\n userAgent: metadata?.userAgent ?? null,\n })\n ).externalId;\n },\n\n getResponse: async (id: string) => {\n const response = await deps.db.findFirst(\"response\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", id)),\n );\n return response ? asExternalResponse(response) : null;\n },\n\n listResponses: async (\n formId: string,\n sort: SubmissionSortOptions = { field: \"submittedAt\", order: \"desc\" },\n ) => {\n const responses = await deps.db.find(\"response\", (b) =>\n b\n .whereIndex(\"idx_response_form\", (eb) => eb(\"formId\", \"=\", formId))\n .orderByIndex(\"idx_response_submitted_at\", sort.order),\n );\n return responses.map(asExternalResponse);\n },\n\n deleteResponse: async (id: string) => {\n return await deps.db.delete(\"response\", id);\n },\n };\n })\n .build();\n","import { z } from \"zod\";\n\nexport const JSONSchemaSchema = z.record(z.string(), z.unknown());\nexport const UISchemaElementSchema = z.record(z.string(), z.unknown());\n\nexport const FormStatusSchema = z.enum([\"draft\", \"open\", \"closed\", \"static\"]);\n\nexport const FormSchema = z.object({\n id: z.string(),\n title: z.string(),\n description: z.string().nullable(),\n slug: z.string(),\n status: FormStatusSchema,\n dataSchema: JSONSchemaSchema,\n uiSchema: UISchemaElementSchema,\n version: z.number(),\n createdAt: z.date(),\n updatedAt: z.date(),\n});\n\nexport const NewFormSchema = FormSchema.omit({\n id: true,\n createdAt: true,\n updatedAt: true,\n version: true,\n});\n\nexport const UpdateFormSchema = NewFormSchema.partial();\n\nexport const ResponseMetadataSchema = z.object({\n ip: z.union([z.ipv4(), z.ipv6()]).nullable(),\n userAgent: z.string().max(4096).nullable(),\n});\n\nexport const ResponseSchema = z.object({\n id: z.string(),\n formId: z.string().nullable().describe(\"Form ID (static form ID or database form external ID)\"),\n formVersion: z.number(),\n data: z.record(z.string(), z.unknown()),\n submittedAt: z.date(),\n ip: z.string().max(45).nullable(),\n userAgent: z.string().max(512).nullable(),\n});\n\nexport const NewResponseSchema = ResponseSchema.omit({\n id: true,\n submittedAt: true,\n formId: true,\n formVersion: true,\n ip: true,\n userAgent: true,\n}).extend({\n securityToken: z.string().optional(),\n});\n\nexport type NewForm = z.infer<typeof NewFormSchema>;\nexport type UpdateForm = z.infer<typeof UpdateFormSchema>;\nexport type Form = z.infer<typeof FormSchema>;\nexport type NewResponse = z.infer<typeof NewResponseSchema>;\nexport type Response = z.infer<typeof ResponseSchema>;\nexport type ResponseMetadata = z.infer<typeof ResponseMetadataSchema>;\nexport type FormStatus = z.infer<typeof FormStatusSchema>;\nexport type JSONSchema = z.infer<typeof JSONSchemaSchema>;\nexport type UIElementSchema = z.infer<typeof UISchemaElementSchema>;\n","import { defineRoutes } from \"@fragno-dev/core\";\nimport type { Schema } from \"@cfworker/json-schema\";\nimport { z } from \"zod\";\nimport { formsFragmentDef } from \"./definition\";\nimport {\n FormSchema,\n NewFormSchema,\n NewResponseSchema,\n ResponseMetadataSchema,\n ResponseSchema,\n UpdateFormSchema,\n} from \"./models\";\nimport type { Form } from \"./models\";\nimport type { StaticForm } from \".\";\n\n/** Extract and validate request metadata from headers (untrusted input) */\nfunction extractRequestMetadata(headers: Headers) {\n const rawUserAgent = headers.get(\"User-Agent\");\n const rawIp =\n headers.get(\"CF-Connecting-IP\") ||\n headers.get(\"X-Forwarded-For\")?.split(\",\")[0].trim() ||\n headers.get(\"X-Real-IP\") ||\n null;\n const result = ResponseMetadataSchema.safeParse({\n ip: rawIp,\n userAgent: rawUserAgent,\n });\n\n // Return validated data or null values if validation fails\n return result.success ? result.data : { ip: null, userAgent: null };\n}\n\nconst staticAsRegularForm = (sf: StaticForm): Form => ({\n id: sf.id,\n title: sf.title,\n description: sf.description,\n slug: sf.slug,\n status: \"static\",\n dataSchema: sf.dataSchema,\n uiSchema: sf.uiSchema as unknown as Form[\"uiSchema\"],\n version: sf.version,\n createdAt: new Date(),\n updatedAt: new Date(),\n});\n\n// Public routes\nexport const publicRoutes = defineRoutes(formsFragmentDef).create(\n ({ services, defineRoute, config }) => {\n return [\n defineRoute({\n method: \"GET\",\n path: \"/:slug\",\n outputSchema: FormSchema,\n errorCodes: [\"NOT_FOUND\"] as const,\n handler: async ({ pathParams }, { json, error }) => {\n // Check static forms first\n const staticForm = config.staticForms?.find((f) => f.slug === pathParams.slug);\n if (staticForm) {\n return json(staticAsRegularForm(staticForm));\n }\n\n const form = await services.getFormBySlug(pathParams.slug);\n if (!form) {\n return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n }\n\n return json(form);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/:slug/submit\",\n inputSchema: NewResponseSchema,\n outputSchema: z.string(),\n errorCodes: [\"NOT_FOUND\", \"VALIDATION_ERROR\", \"FORM_NOT_OPEN\"] as const,\n handler: async ({ input, pathParams, headers }, { json, error }) => {\n const { data } = await input.valid();\n\n // Check static forms first\n const staticFormConfig = config.staticForms?.find((f) => f.slug === pathParams.slug);\n const form = staticFormConfig\n ? staticAsRegularForm(staticFormConfig)\n : await services.getFormBySlug(pathParams.slug);\n\n if (!form) {\n return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n }\n\n // Static forms and open forms accept submissions\n if (form.status !== \"open\" && form.status !== \"static\") {\n return error(\n { message: \"Form is not open, has status \" + form.status, code: \"FORM_NOT_OPEN\" },\n 400,\n );\n }\n\n // Form validation\n const result = services.validateData(form.dataSchema as Schema, data);\n\n if (!result.success) {\n const message = result.error.errors.map((e) => e.message).join(\" \");\n return error({ message, code: \"VALIDATION_ERROR\" }, 400);\n }\n\n // Extract and validate request metadata from headers\n const metadata = extractRequestMetadata(headers);\n\n const responseId = await services.createResponse(\n form.id,\n form.version,\n result.data,\n metadata,\n );\n\n if (config.onResponseSubmitted) {\n await config.onResponseSubmitted({\n id: responseId,\n formId: form.id,\n formVersion: form.version,\n data,\n submittedAt: new Date(),\n ip: metadata?.ip,\n userAgent: metadata?.userAgent,\n });\n }\n\n return json(responseId);\n },\n }),\n ];\n },\n);\n\n// Admin routes\nexport const adminRoutes = defineRoutes(formsFragmentDef).create(\n ({ services, defineRoute, config }) => {\n return [\n defineRoute({\n method: \"GET\",\n path: \"/admin/forms\",\n outputSchema: z.array(FormSchema),\n handler: async (_ctx, { json }) => {\n const dbForms = await services.listForms();\n const staticForms = (config.staticForms ?? []).map(staticAsRegularForm);\n return json([...staticForms, ...dbForms]);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/admin/forms\",\n inputSchema: NewFormSchema,\n outputSchema: z.string(),\n errorCodes: [\"CREATE_FAILED\"] as const,\n handler: async ({ input }, { json }) => {\n const data = await input.valid();\n const formId = await services.createForm(data);\n if (config.onFormCreated) {\n await config.onFormCreated({ ...data, id: formId });\n }\n return json(formId);\n },\n }),\n\n defineRoute({\n method: \"PUT\",\n path: \"/admin/forms/:id\",\n inputSchema: UpdateFormSchema,\n errorCodes: [\"NOT_FOUND\", \"STATIC_FORM_READ_ONLY\"] as const,\n handler: async ({ input, pathParams }, { json, error }) => {\n const isStatic = config.staticForms?.some((f) => f.id === pathParams.id);\n if (isStatic) {\n return error(\n { message: \"Static forms cannot be modified\", code: \"STATIC_FORM_READ_ONLY\" },\n 403,\n );\n }\n const data = await input.valid();\n const { success } = await services.updateForm(pathParams.id, data);\n if (!success) {\n return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n }\n return json(success);\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/admin/forms/:id\",\n errorCodes: [\"NOT_FOUND\", \"STATIC_FORM_READ_ONLY\"] as const,\n handler: async ({ pathParams }, { json, error }) => {\n const isStatic = config.staticForms?.some((f) => f.id === pathParams.id);\n if (isStatic) {\n return error(\n { message: \"Static forms cannot be deleted\", code: \"STATIC_FORM_READ_ONLY\" },\n 403,\n );\n }\n await services.deleteForm(pathParams.id);\n // TODO: 404 when form not found\n // if (!deleted) {\n // return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n // }\n return json(true);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/admin/forms/:id/submissions\",\n queryParameters: [\"sortOrder\"] as const,\n outputSchema: z.array(ResponseSchema),\n handler: async ({ pathParams, query }, { json }) => {\n const sortOrder = query.get(\"sortOrder\") === \"asc\" ? \"asc\" : \"desc\";\n const responses = await services.listResponses(pathParams.id, {\n field: \"submittedAt\",\n order: sortOrder,\n });\n return json(responses);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/admin/submissions/:id\",\n outputSchema: ResponseSchema,\n errorCodes: [\"NOT_FOUND\"] as const,\n handler: async ({ pathParams }, { json, error }) => {\n const response = await services.getResponse(pathParams.id);\n if (!response) {\n return error({ message: \"Submission not found\", code: \"NOT_FOUND\" }, 404);\n }\n return json(response);\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/admin/submissions/:id\",\n errorCodes: [\"NOT_FOUND\"] as const,\n handler: async ({ pathParams }, { json }) => {\n await services.deleteResponse(pathParams.id);\n // TODO: 404 when response not found\n // if (!deleted) {\n // return error({ message: \"Submission not found\", code: \"NOT_FOUND\" }, 404);\n // }\n return json(true);\n },\n }),\n ];\n },\n);\n","import { createClientBuilder } from \"@fragno-dev/core/client\";\nimport type { FragnoPublicClientConfig } from \"@fragno-dev/core/client\";\nimport type { FragnoPublicConfigWithDatabase } from \"@fragno-dev/db\";\nimport { instantiate } from \"@fragno-dev/core\";\nimport { publicRoutes, adminRoutes } from \"./routes\";\nimport { formsFragmentDef } from \"./definition\";\nimport type { Form, JSONSchema, Response } from \"./models\";\nimport type { UISchemaElement } from \"@jsonforms/core\";\n\n// Forms that exist in code, but submissions are stored in the DB\n// Static forms always have status: \"static\" and accept submissions\nexport interface StaticForm {\n id: string;\n title: string;\n description: string | null;\n slug: string;\n dataSchema: JSONSchema;\n uiSchema: UISchemaElement;\n version: number;\n}\n\nexport interface FormsConfig {\n onFormCreated?: (form: Omit<Form, \"version\" | \"createdAt\" | \"updatedAt\">) => Promise<void>;\n onResponseSubmitted?: (response: Response) => Promise<void>;\n staticForms?: StaticForm[];\n}\n\nexport const routes = [publicRoutes, adminRoutes] as const;\n\nexport function createFormsFragment(\n config: FormsConfig = {},\n options: FragnoPublicConfigWithDatabase,\n) {\n return instantiate(formsFragmentDef)\n .withConfig(config)\n .withRoutes(routes)\n .withOptions(options)\n .build();\n}\n\nexport function createFormsClients(fragnoConfig: FragnoPublicClientConfig) {\n const b = createClientBuilder(formsFragmentDef, fragnoConfig, routes);\n\n return {\n // Public\n useForm: b.createHook(\"/:slug\"),\n useSubmitForm: b.createMutator(\"POST\", \"/:slug/submit\"),\n\n // Admin - Forms\n useForms: b.createHook(\"/admin/forms\"),\n useCreateForm: b.createMutator(\"POST\", \"/admin/forms\"),\n useUpdateForm: b.createMutator(\"PUT\", \"/admin/forms/:id\"),\n useDeleteForm: b.createMutator(\"DELETE\", \"/admin/forms/:id\"),\n\n // Admin - Submissions\n useSubmissions: b.createHook(\"/admin/forms/:id/submissions\"),\n useSubmission: b.createHook(\"/admin/submissions/:id\"),\n useDeleteSubmission: b.createMutator(\"DELETE\", \"/admin/submissions/:id\"),\n };\n}\n\nexport { formsFragmentDef } from \"./definition\";\nexport type { SubmissionSortOptions } from \"./definition\";\nexport type { FragnoRouteConfig } from \"@fragno-dev/core\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["form: T","response: T","input: NewForm","id: string","slug: string","input: UpdateForm","schema: JSONSchema","data: Record<string, unknown>","schema","formId: string","formVersion: number","data: ValidatedData","metadata?: { ip?: string | null; userAgent?: string | null }","sort: SubmissionSortOptions","headers: Headers","sf: StaticForm","result","config: FormsConfig","options: FragnoPublicConfigWithDatabase","fragnoConfig: FragnoPublicClientConfig"],"sources":["../../src/schema.ts","../../src/definition.ts","../../src/models.ts","../../src/routes.ts","../../src/index.ts"],"sourcesContent":["import { column, idColumn, schema } from \"@fragno-dev/db/schema\";\n\nexport const formsSchema = schema(\"forms\", (s) => {\n return s\n .addTable(\"form\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"title\", column(\"string\"))\n .addColumn(\"description\", column(\"string\").nullable())\n .addColumn(\"slug\", column(\"string\"))\n .addColumn(\n \"status\",\n column(\"string\").defaultTo(() => \"draft\"),\n )\n .addColumn(\"dataSchema\", column(\"json\"))\n .addColumn(\"uiSchema\", column(\"json\").nullable())\n .addColumn(\n \"version\",\n column(\"integer\").defaultTo(() => 1),\n )\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_form_status\", [\"status\"])\n .createIndex(\"idx_form_slug\", [\"slug\"], { unique: true });\n })\n .addTable(\"response\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"formId\", column(\"string\"))\n .addColumn(\"formVersion\", column(\"integer\"))\n .addColumn(\"data\", column(\"json\"))\n .addColumn(\n \"submittedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"userAgent\", column(\"string\").nullable())\n .addColumn(\"ip\", column(\"string\").nullable())\n .createIndex(\"idx_response_form\", [\"formId\"])\n .createIndex(\"idx_response_submitted_at\", [\"submittedAt\"]);\n });\n});\n","import { z } from \"zod\";\n\nimport { defineFragment } from \"@fragno-dev/core\";\nimport { withDatabase } from \"@fragno-dev/db\";\n\nimport type { FormsConfig } from \".\";\nimport type { JSONSchema, NewForm, UpdateForm, FormStatus, UIElementSchema } from \"./models\";\nimport { formsSchema } from \"./schema\";\n\nexport type ValidatedData<T = Record<string, unknown>> = T;\nexport type ValidationResult =\n | { success: true; data: ValidatedData }\n | {\n success: false;\n error: { message: string; errors: Array<{ instancePath: string; message: string }> };\n };\n\n// External to this fragment\nconst asExternalForm = <\n T extends { id: { externalId: string }; status: string; dataSchema: unknown; uiSchema: unknown },\n>(\n form: T,\n) => ({\n ...form,\n id: form.id.externalId,\n status: form.status as FormStatus,\n dataSchema: form.dataSchema as JSONSchema,\n uiSchema: form.uiSchema as UIElementSchema,\n});\n\nconst asExternalResponse = <\n T extends {\n id: { externalId: string };\n formId: string | null;\n data: unknown;\n ip: string | null;\n userAgent: string | null;\n },\n>(\n response: T,\n) => ({\n ...response,\n id: response.id.externalId,\n data: response.data as Record<string, unknown>,\n});\n\nexport interface SubmissionSortOptions {\n field: \"submittedAt\";\n order: \"asc\" | \"desc\";\n}\n\nexport const formsFragmentDef = defineFragment<FormsConfig>(\"forms\")\n .extend(withDatabase(formsSchema))\n .providesBaseService(({ defineService }) =>\n defineService({\n createForm: function (input: NewForm) {\n return this.serviceTx(formsSchema)\n .mutate(({ uow }) => uow.create(\"form\", input))\n .transform(({ mutateResult }) => mutateResult.externalId)\n .build();\n },\n\n getForm: function (id: string) {\n return this.serviceTx(formsSchema)\n .retrieve((uow) =>\n uow.findFirst(\"form\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", id))),\n )\n .transformRetrieve(([form]) => (form ? asExternalForm(form) : null))\n .build();\n },\n\n getFormBySlug: function (slug: string) {\n return this.serviceTx(formsSchema)\n .retrieve((uow) =>\n uow.findFirst(\"form\", (b) =>\n b.whereIndex(\"idx_form_slug\", (eb) => eb(\"slug\", \"=\", slug)),\n ),\n )\n .transformRetrieve(([form]) => (form ? asExternalForm(form) : null))\n .build();\n },\n\n updateForm: function (id: string, input: UpdateForm) {\n return this.serviceTx(formsSchema)\n .retrieve((uow) =>\n uow.find(\"form\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", id))),\n )\n .mutate(({ uow, retrieveResult: [currentForms] }) => {\n if (currentForms.length === 0) {\n return { success: false };\n }\n // TODO: length > 1 ?\n\n const currentForm = currentForms[0];\n\n // Only increment version if changing data schema\n const newVersion = input.dataSchema ? currentForm.version + 1 : currentForm.version;\n\n uow.update(\"form\", currentForm.id, (b) => {\n b.set({ ...input, version: newVersion, updatedAt: new Date() }).check();\n });\n\n return { success: true };\n })\n .build();\n },\n\n listForms: function () {\n return this.serviceTx(formsSchema)\n .retrieve((uow) => uow.find(\"form\", (b) => b.whereIndex(\"primary\")))\n .transformRetrieve(([forms]) => forms.map(asExternalForm))\n .build();\n },\n\n deleteForm: function (id: string) {\n return this.serviceTx(formsSchema)\n .mutate(({ uow }) => uow.delete(\"form\", id))\n .build();\n },\n\n validateData: (schema: JSONSchema, data: Record<string, unknown>): ValidationResult => {\n const zodSchema = z.fromJSONSchema(schema);\n const result = zodSchema.safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data as ValidatedData };\n }\n return {\n success: false,\n\n error: {\n message: \"Validation failed\",\n errors: result.error.issues.map((e) => ({\n instancePath: \"/\" + e.path.join(\"/\"),\n message: e.message,\n })),\n },\n };\n },\n\n createResponse: function (\n formId: string,\n formVersion: number,\n data: ValidatedData,\n metadata?: { ip?: string | null; userAgent?: string | null },\n ) {\n return this.serviceTx(formsSchema)\n .mutate(({ uow }) =>\n uow.create(\"response\", {\n formId,\n formVersion,\n data,\n ip: metadata?.ip ?? null,\n userAgent: metadata?.userAgent ?? null,\n }),\n )\n .transform(({ mutateResult }) => mutateResult.externalId)\n .build();\n },\n\n getResponse: function (id: string) {\n return this.serviceTx(formsSchema)\n .retrieve((uow) =>\n uow.findFirst(\"response\", (b) => b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", id))),\n )\n .transformRetrieve(([response]) => (response ? asExternalResponse(response) : null))\n .build();\n },\n\n listResponses: function (\n formId: string,\n sort: SubmissionSortOptions = { field: \"submittedAt\", order: \"desc\" },\n ) {\n return this.serviceTx(formsSchema)\n .retrieve((uow) =>\n uow.find(\"response\", (b) =>\n b\n .whereIndex(\"idx_response_form\", (eb) => eb(\"formId\", \"=\", formId))\n .orderByIndex(\"idx_response_submitted_at\", sort.order),\n ),\n )\n .transformRetrieve(([responses]) => responses.map(asExternalResponse))\n .build();\n },\n\n deleteResponse: function (id: string) {\n return this.serviceTx(formsSchema)\n .mutate(({ uow }) => uow.delete(\"response\", id))\n .build();\n },\n }),\n )\n .build();\n","import { z } from \"zod\";\n\nexport const JSONSchemaSchema = z.record(z.string(), z.unknown());\nexport const UISchemaElementSchema = z.record(z.string(), z.unknown());\n\nexport const FormStatusSchema = z.enum([\"draft\", \"open\", \"closed\", \"static\"]);\n\nexport const FormSchema = z.object({\n id: z.string(),\n title: z.string(),\n description: z.string().nullable().optional(),\n slug: z.string().min(1).max(255).toLowerCase().trim(),\n status: FormStatusSchema,\n dataSchema: JSONSchemaSchema,\n uiSchema: UISchemaElementSchema.optional(),\n version: z.number(),\n createdAt: z.date(),\n updatedAt: z.date(),\n});\n\nexport const NewFormSchema = FormSchema.omit({\n id: true,\n createdAt: true,\n updatedAt: true,\n version: true,\n});\n\nexport const UpdateFormSchema = NewFormSchema.partial();\n\nexport const ResponseMetadataSchema = z.object({\n ip: z.union([z.ipv4(), z.ipv6()]).nullable(),\n userAgent: z.string().max(4096).nullable(),\n});\n\nexport const FormResponseSchema = z.object({\n id: z.string(),\n formId: z.string().nullable().describe(\"Form ID (static form ID or database form external ID)\"),\n formVersion: z.number(),\n data: z.record(z.string(), z.unknown()),\n submittedAt: z.date(),\n ip: z.string().max(45).nullable(),\n userAgent: z.string().max(512).nullable(),\n});\n\nexport const NewFormResponseSchema = FormResponseSchema.omit({\n id: true,\n submittedAt: true,\n formId: true,\n formVersion: true,\n ip: true,\n userAgent: true,\n}).extend({\n securityToken: z.string().optional(),\n});\n\nexport type NewForm = z.infer<typeof NewFormSchema>;\nexport type UpdateForm = z.infer<typeof UpdateFormSchema>;\nexport type Form = z.infer<typeof FormSchema>;\nexport type NewFormResponse = z.infer<typeof NewFormResponseSchema>;\nexport type FormResponse = z.infer<typeof FormResponseSchema>;\nexport type FormResponseMetadata = z.infer<typeof ResponseMetadataSchema>;\nexport type FormStatus = z.infer<typeof FormStatusSchema>;\nexport type JSONSchema = z.infer<typeof JSONSchemaSchema>;\nexport type UIElementSchema = z.infer<typeof UISchemaElementSchema>;\n","import { z } from \"zod\";\n\nimport { defineRoutes } from \"@fragno-dev/core\";\n\nimport type { StaticForm } from \".\";\nimport { formsFragmentDef } from \"./definition\";\nimport {\n FormSchema,\n NewFormSchema,\n NewFormResponseSchema,\n ResponseMetadataSchema,\n FormResponseSchema,\n UpdateFormSchema,\n} from \"./models\";\nimport type { Form } from \"./models\";\n\n/** Extract and validate request metadata from headers (untrusted input) */\nfunction extractRequestMetadata(headers: Headers) {\n const rawUserAgent = headers.get(\"User-Agent\");\n const rawIp =\n headers.get(\"CF-Connecting-IP\") ||\n headers.get(\"X-Forwarded-For\")?.split(\",\")[0].trim() ||\n headers.get(\"X-Real-IP\") ||\n null;\n const result = ResponseMetadataSchema.safeParse({\n ip: rawIp,\n userAgent: rawUserAgent,\n });\n\n // Return validated data or null values if validation fails\n return result.success ? result.data : { ip: null, userAgent: null };\n}\n\nconst staticAsRegularForm = (sf: StaticForm): Form => ({\n id: sf.id,\n title: sf.title,\n description: sf.description,\n slug: sf.slug,\n status: \"static\",\n dataSchema: sf.dataSchema,\n uiSchema: sf.uiSchema as unknown as Form[\"uiSchema\"],\n version: sf.version,\n createdAt: new Date(),\n updatedAt: new Date(),\n});\n\n// Public routes\nexport const publicRoutes = defineRoutes(formsFragmentDef).create(\n ({ services, defineRoute, config }) => {\n return [\n defineRoute({\n method: \"GET\",\n path: \"/:slug\",\n outputSchema: FormSchema,\n errorCodes: [\"NOT_FOUND\"] as const,\n handler: async function ({ pathParams }, { json, error }) {\n // Check static forms first\n const staticForm = config.staticForms?.find((f) => f.slug === pathParams.slug);\n if (staticForm) {\n return json(staticAsRegularForm(staticForm));\n }\n\n const form = await this.handlerTx()\n .withServiceCalls(() => [services.getFormBySlug(pathParams.slug)] as const)\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n if (!form) {\n return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n }\n\n return json(form);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/:slug/submit\",\n inputSchema: NewFormResponseSchema,\n outputSchema: z.string(),\n errorCodes: [\"NOT_FOUND\", \"VALIDATION_ERROR\", \"FORM_NOT_OPEN\"] as const,\n handler: async function ({ input, pathParams, headers }, { json, error }) {\n const { data } = await input.valid();\n\n // Check static forms first\n const staticFormConfig = config.staticForms?.find((f) => f.slug === pathParams.slug);\n const form = staticFormConfig\n ? staticAsRegularForm(staticFormConfig)\n : await this.handlerTx()\n .withServiceCalls(() => [services.getFormBySlug(pathParams.slug)] as const)\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (!form) {\n return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n }\n\n // Static forms and open forms accept submissions\n if (form.status !== \"open\" && form.status !== \"static\") {\n return error(\n { message: \"Form is not open, has status \" + form.status, code: \"FORM_NOT_OPEN\" },\n 400,\n );\n }\n\n // Form validation\n const result = services.validateData(form.dataSchema, data);\n\n if (!result.success) {\n const message = result.error.errors.map((e) => e.message).join(\" \");\n return error({ message, code: \"VALIDATION_ERROR\" }, 400);\n }\n\n // Extract and validate request metadata from headers\n const metadata = extractRequestMetadata(headers);\n\n const responseId = await this.handlerTx()\n .withServiceCalls(\n () =>\n [services.createResponse(form.id, form.version, result.data, metadata)] as const,\n )\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n\n if (config.onResponseSubmitted) {\n await config.onResponseSubmitted({\n id: responseId,\n formId: form.id,\n formVersion: form.version,\n data,\n submittedAt: new Date(),\n ip: metadata?.ip,\n userAgent: metadata?.userAgent,\n });\n }\n\n return json(responseId);\n },\n }),\n ];\n },\n);\n\n// Admin routes\nexport const adminRoutes = defineRoutes(formsFragmentDef).create(\n ({ services, defineRoute, config }) => {\n return [\n defineRoute({\n method: \"GET\",\n path: \"/admin/forms\",\n outputSchema: z.array(FormSchema),\n handler: async function (_ctx, { json }) {\n const dbForms = await this.handlerTx()\n .withServiceCalls(() => [services.listForms()] as const)\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n const staticForms = (config.staticForms ?? []).map(staticAsRegularForm);\n return json([...staticForms, ...dbForms]);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/admin/forms/:id\",\n outputSchema: FormSchema,\n errorCodes: [\"NOT_FOUND\"] as const,\n handler: async function ({ pathParams }, { json, error }) {\n // Check static forms first\n const staticForm = config.staticForms?.find((f) => f.id === pathParams.id);\n if (staticForm) {\n return json(staticAsRegularForm(staticForm));\n }\n\n const form = await this.handlerTx()\n .withServiceCalls(() => [services.getForm(pathParams.id)] as const)\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n if (!form) {\n return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n }\n\n return json(form);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/admin/forms\",\n inputSchema: NewFormSchema,\n outputSchema: z.string(),\n errorCodes: [\"CREATE_FAILED\", \"INVALID_JSON_SCHEMA\"] as const,\n handler: async function ({ input }, { json, error }) {\n const data = await input.valid();\n\n // Validate that dataSchema is valid JSON Schema\n try {\n z.fromJSONSchema(data.dataSchema);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"Invalid JSON Schema\";\n return error({ message, code: \"INVALID_JSON_SCHEMA\" }, 400);\n }\n\n const formId = await this.handlerTx()\n .withServiceCalls(() => [services.createForm(data)] as const)\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n if (config.onFormCreated) {\n await config.onFormCreated({ ...data, id: formId });\n }\n return json(formId);\n },\n }),\n\n defineRoute({\n method: \"PUT\",\n path: \"/admin/forms/:id\",\n inputSchema: UpdateFormSchema,\n errorCodes: [\"NOT_FOUND\", \"STATIC_FORM_READ_ONLY\", \"INVALID_JSON_SCHEMA\"] as const,\n handler: async function ({ input, pathParams }, { json, error }) {\n const isStatic = config.staticForms?.some((f) => f.id === pathParams.id);\n if (isStatic) {\n return error(\n { message: \"Static forms cannot be modified\", code: \"STATIC_FORM_READ_ONLY\" },\n 403,\n );\n }\n const data = await input.valid();\n\n // Validate that dataSchema is valid JSON Schema (if provided)\n if (data.dataSchema) {\n try {\n z.fromJSONSchema(data.dataSchema);\n } catch (e) {\n const message = e instanceof Error ? e.message : \"Invalid JSON Schema\";\n return error({ message, code: \"INVALID_JSON_SCHEMA\" }, 400);\n }\n }\n\n const { success } = await this.handlerTx()\n .withServiceCalls(() => [services.updateForm(pathParams.id, data)] as const)\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n if (!success) {\n return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n }\n return json(true);\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/admin/forms/:id\",\n errorCodes: [\"NOT_FOUND\", \"STATIC_FORM_READ_ONLY\"] as const,\n handler: async function ({ pathParams }, { json, error }) {\n const isStatic = config.staticForms?.some((f) => f.id === pathParams.id);\n if (isStatic) {\n return error(\n { message: \"Static forms cannot be deleted\", code: \"STATIC_FORM_READ_ONLY\" },\n 403,\n );\n }\n await this.handlerTx()\n .withServiceCalls(() => [services.deleteForm(pathParams.id)] as const)\n .execute();\n // TODO: 404 when form not found\n // if (!deleted) {\n // return error({ message: \"Form not found\", code: \"NOT_FOUND\" }, 404);\n // }\n return json(true);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/admin/forms/:id/submissions\",\n queryParameters: [\"sortOrder\"] as const,\n outputSchema: z.array(FormResponseSchema),\n handler: async function ({ pathParams, query }, { json }) {\n const sortOrder = query.get(\"sortOrder\") === \"asc\" ? \"asc\" : \"desc\";\n const responses = await this.handlerTx()\n .withServiceCalls(\n () =>\n [\n services.listResponses(pathParams.id, {\n field: \"submittedAt\",\n order: sortOrder,\n }),\n ] as const,\n )\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n return json(responses);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/admin/submissions/:id\",\n outputSchema: FormResponseSchema,\n errorCodes: [\"NOT_FOUND\"] as const,\n handler: async function ({ pathParams }, { json, error }) {\n const response = await this.handlerTx()\n .withServiceCalls(() => [services.getResponse(pathParams.id)] as const)\n .transform(({ serviceResult: [result] }) => result)\n .execute();\n if (!response) {\n return error({ message: \"Submission not found\", code: \"NOT_FOUND\" }, 404);\n }\n return json(response);\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/admin/submissions/:id\",\n errorCodes: [\"NOT_FOUND\"] as const,\n handler: async function ({ pathParams }, { json }) {\n await this.handlerTx()\n .withServiceCalls(() => [services.deleteResponse(pathParams.id)] as const)\n .execute();\n // TODO: 404 when response not found\n // if (!deleted) {\n // return error({ message: \"Submission not found\", code: \"NOT_FOUND\" }, 404);\n // }\n return json(true);\n },\n }),\n ];\n },\n);\n","import { createClientBuilder } from \"@fragno-dev/core/client\";\nimport type { FragnoPublicClientConfig } from \"@fragno-dev/core/client\";\n\nimport { instantiate } from \"@fragno-dev/core\";\nimport type { FragnoPublicConfigWithDatabase } from \"@fragno-dev/db\";\n\nimport type { UISchemaElement } from \"@jsonforms/core\";\n\nimport { formsFragmentDef } from \"./definition\";\nimport type { Form, JSONSchema, FormResponse } from \"./models\";\nimport { publicRoutes, adminRoutes } from \"./routes\";\n\n// Forms that exist in code, but submissions are stored in the DB\n// Static forms always have status: \"static\" and accept submissions\nexport interface StaticForm {\n id: string;\n title: string;\n description?: string;\n slug: string;\n dataSchema: JSONSchema;\n uiSchema?: UISchemaElement;\n version: number;\n}\n\nexport interface FormsConfig {\n onFormCreated?: (form: Omit<Form, \"version\" | \"createdAt\" | \"updatedAt\">) => Promise<void>;\n onResponseSubmitted?: (response: FormResponse) => Promise<void>;\n staticForms?: StaticForm[];\n}\n\nexport const routes = [publicRoutes, adminRoutes] as const;\n\nexport function createFormsFragment(\n config: FormsConfig = {},\n options: FragnoPublicConfigWithDatabase,\n) {\n return instantiate(formsFragmentDef)\n .withConfig(config)\n .withRoutes(routes)\n .withOptions(options)\n .build();\n}\n\nexport function createFormsClients(fragnoConfig: FragnoPublicClientConfig) {\n const b = createClientBuilder(formsFragmentDef, fragnoConfig, routes);\n\n return {\n // Public\n useForm: b.createHook(\"/:slug\"),\n useSubmitForm: b.createMutator(\"POST\", \"/:slug/submit\"),\n\n // Admin - Forms\n useForms: b.createHook(\"/admin/forms\"),\n useFormById: b.createHook(\"/admin/forms/:id\"),\n useCreateForm: b.createMutator(\"POST\", \"/admin/forms\"),\n useUpdateForm: b.createMutator(\"PUT\", \"/admin/forms/:id\"),\n useDeleteForm: b.createMutator(\"DELETE\", \"/admin/forms/:id\"),\n\n // Admin - Submissions\n useSubmissions: b.createHook(\"/admin/forms/:id/submissions\"),\n useSubmission: b.createHook(\"/admin/submissions/:id\"),\n useDeleteSubmission: b.createMutator(\"DELETE\", \"/admin/submissions/:id\"),\n };\n}\n\nexport { formsFragmentDef } from \"./definition\";\nexport type { SubmissionSortOptions } from \"./definition\";\nexport type { FragnoRouteConfig } from \"@fragno-dev/core\";\nexport type {\n NewForm,\n UpdateForm,\n Form,\n NewFormResponse,\n FormResponse,\n FormResponseMetadata,\n FormStatus,\n} from \"./models\";\n"],"mappings":"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"}
|