@frigear-nu/forms 0.0.8 → 0.1.0

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.
Files changed (28) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +7 -5
  3. package/dist/runtime/app/components/FormBuilderAccess.vue +6 -13
  4. package/dist/runtime/app/components/FormBuilderFieldRow.d.vue.ts +2 -2
  5. package/dist/runtime/app/components/FormBuilderFieldRow.vue.d.ts +2 -2
  6. package/dist/runtime/app/components/FormBuilderStepHeader.d.vue.ts +2 -2
  7. package/dist/runtime/app/components/FormBuilderStepHeader.vue.d.ts +2 -2
  8. package/dist/runtime/app/components/FormCreateSlideover.d.vue.ts +8 -0
  9. package/dist/runtime/app/components/FormCreateSlideover.vue +73 -0
  10. package/dist/runtime/app/components/FormCreateSlideover.vue.d.ts +8 -0
  11. package/dist/runtime/app/components/FormPreview.vue +2 -8
  12. package/dist/runtime/app/composables/index.d.ts +1 -0
  13. package/dist/runtime/app/composables/index.js +1 -0
  14. package/dist/runtime/app/composables/useFormActions.d.ts +26 -0
  15. package/dist/runtime/app/composables/useFormActions.js +103 -0
  16. package/dist/runtime/app/composables/useForms.d.ts +1 -1
  17. package/dist/runtime/app/composables/useForms.js +2 -9
  18. package/dist/runtime/app/pages/admin-form.vue +84 -82
  19. package/dist/runtime/app/pages/admin-submission.vue +60 -29
  20. package/dist/runtime/app/pages/admin-submissions.vue +81 -47
  21. package/dist/runtime/app/pages/admin.vue +152 -233
  22. package/dist/runtime/app/pages/form.vue +47 -45
  23. package/dist/runtime/i18n/lang/da.json +31 -10
  24. package/dist/runtime/i18n/lang/en.json +31 -10
  25. package/dist/runtime/menus.js +0 -11
  26. package/dist/runtime/server/db/schema.postgresql.d.ts +741 -0
  27. package/dist/runtime/server/db/schema.postgresql.js +78 -0
  28. package/package.json +17 -17
@@ -0,0 +1,78 @@
1
+ import { customType, pgTable, text, integer, jsonb, timestamp, index } from "drizzle-orm/pg-core";
2
+ export const forms = pgTable("forms", {
3
+ /** `frm_` + random id. */
4
+ id: text().primaryKey(),
5
+ slug: text().notNull().unique(),
6
+ name: text().notNull(),
7
+ /** `draft | published | archived`. Only published forms are public. */
8
+ status: text().$type().notNull().default("draft"),
9
+ definition: jsonb().$type().notNull(),
10
+ /** Bumped whenever the definition changes. */
11
+ version: integer().notNull().default(1),
12
+ createdAt: timestamp({ withTimezone: true }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
13
+ updatedAt: timestamp({ withTimezone: true }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()).$onUpdateFn(() => /* @__PURE__ */ new Date())
14
+ });
15
+ export const formSubmissions = pgTable("form_submissions", {
16
+ /** `fsb_` + random id. */
17
+ id: text().primaryKey(),
18
+ /** Forms are archived, never deleted, so submissions always keep their form. */
19
+ formId: text().notNull().references(() => forms.id),
20
+ formSlug: text().notNull(),
21
+ formVersion: integer().notNull(),
22
+ /** The definition as it was when the answers were given; renders old submissions correctly after edits. */
23
+ definitionSnapshot: jsonb().$type().notNull(),
24
+ answers: jsonb().$type().notNull(),
25
+ /** Signed-in submitter, if any. */
26
+ userId: integer(),
27
+ locale: text().notNull().default("en"),
28
+ deliveryStatus: text().$type().notNull().default("none"),
29
+ deliveryError: text(),
30
+ createdAt: timestamp({ withTimezone: true }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
31
+ }, (t) => [
32
+ index("form_submission_form_idx").on(t.formId, t.createdAt)
33
+ ]);
34
+ export const formSubmissionFiles = pgTable("form_submission_files", {
35
+ /** `fsf_` + random id. */
36
+ id: text().primaryKey(),
37
+ submissionId: text().notNull().references(() => formSubmissions.id, { onDelete: "cascade" }),
38
+ fieldKey: text().notNull(),
39
+ /** Pathname in the blob store. */
40
+ pathname: text().notNull(),
41
+ filename: text().notNull(),
42
+ contentType: text().notNull(),
43
+ size: integer().notNull()
44
+ }, (t) => [
45
+ index("form_submission_file_submission_idx").on(t.submissionId)
46
+ ]);
47
+ export const formAccessTokens = pgTable("form_access_tokens", {
48
+ /** `fat_` + random id. */
49
+ id: text().primaryKey(),
50
+ formId: text().notNull().references(() => forms.id, { onDelete: "cascade" }),
51
+ name: text().notNull(),
52
+ /** SHA-256 (hex) of the token; the token itself is shown once on creation and never stored. */
53
+ tokenHash: text().notNull().unique(),
54
+ /** First characters of the token, for display. */
55
+ prefix: text().notNull(),
56
+ createdAt: timestamp({ withTimezone: true }).notNull().$defaultFn(() => /* @__PURE__ */ new Date()),
57
+ lastUsedAt: timestamp({ withTimezone: true }),
58
+ revokedAt: timestamp({ withTimezone: true })
59
+ }, (t) => [
60
+ index("form_access_token_form_idx").on(t.formId)
61
+ ]);
62
+ export const formAccess = pgTable("form_access", {
63
+ formId: text().primaryKey().references(() => forms.id, { onDelete: "cascade" }),
64
+ /** Scrypt hash (nuxt-auth-utils `hashPassword`). */
65
+ passwordHash: text().notNull(),
66
+ updatedAt: timestamp({ withTimezone: true }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
67
+ });
68
+ export const formSecrets = pgTable("form_secrets", {
69
+ formId: text().primaryKey().references(() => forms.id, { onDelete: "cascade" }),
70
+ // Inline on purpose: the module kit copies this property (and only the imports above) into a generated schema
71
+ // template, so it cannot call a local helper. `utils/crypto.ts` registers the cipher on `globalThis`.
72
+ secrets: customType({
73
+ dataType: () => "text",
74
+ toDriver: (value) => globalThis.__frigearFormsCrypto.encrypt(value),
75
+ fromDriver: (value) => globalThis.__frigearFormsCrypto.decrypt(value)
76
+ })("secrets").notNull(),
77
+ updatedAt: timestamp({ withTimezone: true }).notNull().$defaultFn(() => /* @__PURE__ */ new Date())
78
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frigear-nu/forms",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "description": "Dynamic, database-stored forms (single page or stepped) with submissions, file uploads and email delivery for the frigear ecosystem.",
5
5
  "homepage": "https://docs.frigear.dev/modules/forms",
6
6
  "repository": {
@@ -30,15 +30,15 @@
30
30
  "playground"
31
31
  ],
32
32
  "dependencies": {
33
- "@frigear-nu/admin": "0.0.3",
34
- "@frigear-nu/module-kit": "1.0.0",
35
- "@frigear-nu/notify": "0.0.10",
36
- "@frigear-nu/ui": "0.0.8",
37
- "@frigear-nu/auth": "0.0.4",
38
- "@frigear-nu/mcp": "0.0.4",
39
- "@frigear-nu/users": "1.0.10",
33
+ "@frigear-nu/admin": "0.1.0",
34
+ "@frigear-nu/module-kit": "1.1.0",
35
+ "@frigear-nu/notify": "0.1.0",
36
+ "@frigear-nu/ui": "0.1.0",
37
+ "@frigear-nu/auth": "0.1.0",
38
+ "@frigear-nu/mcp": "0.1.0",
39
+ "@frigear-nu/users": "1.1.0",
40
40
  "@libsql/client": "^0.18.0",
41
- "@nuxt/kit": "^4.6.0",
41
+ "@nuxt/kit": "^4.6.1",
42
42
  "drizzle-kit": "^0.31.11",
43
43
  "drizzle-orm": "^0.45.3",
44
44
  "h3": "^1.15.11",
@@ -46,8 +46,8 @@
46
46
  "zod": "^4.6.5"
47
47
  },
48
48
  "peerDependencies": {
49
- "@frigear-nu/menu": "0.0.10",
50
- "@nuxt/ui": "^4.10.0",
49
+ "@frigear-nu/menu": "0.1.0",
50
+ "@nuxt/ui": "^4.11.2",
51
51
  "@nuxthub/core": "^0.10.8"
52
52
  },
53
53
  "peerDependenciesMeta": {
@@ -59,20 +59,20 @@
59
59
  }
60
60
  },
61
61
  "devDependencies": {
62
- "@frigear-nu/menu": "0.0.10",
62
+ "@frigear-nu/menu": "0.1.0",
63
63
  "@nuxt/devtools": "^3.4.2",
64
64
  "@nuxt/eslint-config": "^1.17.0",
65
65
  "@nuxt/module-builder": "^1.0.3",
66
- "@nuxt/schema": "^4.6.0",
66
+ "@nuxt/schema": "^4.6.1",
67
67
  "@nuxt/test-utils": "^4.3.2",
68
- "@nuxt/ui": "^4.11.0",
68
+ "@nuxt/ui": "^4.11.2",
69
69
  "@nuxthub/core": "^0.10.8",
70
- "@types/node": "latest",
70
+ "@types/node": "^26.6.5",
71
71
  "changelogen": "^0.6.2",
72
- "eslint": "^10.10.0",
72
+ "eslint": "^10.12.0",
73
73
  "nuxt": "^4.6.1",
74
74
  "typescript": "^6.0.3",
75
- "vitest": "^5.0.1",
75
+ "vitest": "^5.0.2",
76
76
  "vue-tsc": "^3.3.11"
77
77
  },
78
78
  "scripts": {