rimecms 0.29.0 → 0.30.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 (215) hide show
  1. package/dist/adapter-sqlite/area.server.js +8 -8
  2. package/dist/adapter-sqlite/generate-schema/column.server.d.ts +13 -0
  3. package/dist/adapter-sqlite/generate-schema/column.server.js +77 -0
  4. package/dist/adapter-sqlite/generate-schema/index.server.js +7 -12
  5. package/dist/adapter-sqlite/generate-schema/root.server.js +35 -39
  6. package/dist/adapter-sqlite/generate-schema/templates.server.d.ts +12 -0
  7. package/dist/adapter-sqlite/generate-schema/templates.server.js +19 -0
  8. package/dist/adapter-sqlite/index.server.d.ts +1 -2
  9. package/dist/adapter-sqlite/index.server.js +0 -2
  10. package/dist/adapter-sqlite/relations.server.js +6 -1
  11. package/dist/adapter-sqlite/util.server.d.ts +1 -6
  12. package/dist/adapter-sqlite/util.server.js +6 -0
  13. package/dist/adapter-sqlite/where.server.js +17 -16
  14. package/dist/adapter-sqlite/with.server.js +9 -9
  15. package/dist/core/collections/auth/fields.d.ts +2 -182
  16. package/dist/core/collections/config/augment-auth.server.js +1 -1
  17. package/dist/core/collections/config/augment-nested.server.js +1 -1
  18. package/dist/core/collections/config/augment-upload.js +2 -2
  19. package/dist/core/collections/config/augment-upload.server.js +4 -1
  20. package/dist/core/collections/operations/duplicate.js +30 -11
  21. package/dist/core/collections/operations/updateById.js +6 -5
  22. package/dist/core/collections/rest/duplicate.server.js +7 -3
  23. package/dist/core/collections/upload/disk/delete.server.d.ts +1 -1
  24. package/dist/core/collections/upload/disk/delete.server.js +48 -1
  25. package/dist/core/collections/upload/hooks/clean-up-files.server.js +2 -2
  26. package/dist/core/collections/upload/hooks/extract-path.server.d.ts +1 -1
  27. package/dist/core/collections/upload/hooks/extract-path.server.js +1 -1
  28. package/dist/core/collections/upload/hooks/process-file-upload.server.js +3 -3
  29. package/dist/core/config/server/validate.server.js +50 -30
  30. package/dist/core/config/shared/find-thumbnail.js +12 -12
  31. package/dist/core/config/shared/find-title.js +13 -13
  32. package/dist/core/config/shared/upload-directories.js +1 -1
  33. package/dist/core/constant.server.d.ts +1 -0
  34. package/dist/core/constant.server.js +2 -0
  35. package/dist/core/dev/cache/index.server.js +9 -9
  36. package/dist/core/dev/cli/build/index.js +2 -2
  37. package/dist/core/dev/cli/clear/index.server.js +2 -1
  38. package/dist/core/dev/cli/generate/index.server.js +3 -2
  39. package/dist/core/dev/cli/init/index.server.js +1 -1
  40. package/dist/core/dev/generate/routes/index.server.js +2 -2
  41. package/dist/core/dev/generate/types/index.server.js +17 -17
  42. package/dist/core/dev/vite/index.server.js +21 -5
  43. package/dist/core/fields/builders/boolean-builder.d.ts +3 -1
  44. package/dist/core/fields/builders/boolean-builder.js +3 -0
  45. package/dist/core/fields/builders/field-builder.d.ts +35 -2
  46. package/dist/core/fields/builders/field-builder.js +33 -2
  47. package/dist/core/fields/builders/form-field-builder.d.ts +71 -12
  48. package/dist/core/fields/builders/form-field-builder.js +96 -6
  49. package/dist/core/fields/builders/select-builder.d.ts +4 -1
  50. package/dist/core/fields/builders/select-builder.js +3 -0
  51. package/dist/core/fields/util.d.ts +8 -16
  52. package/dist/core/fields/util.js +49 -83
  53. package/dist/core/handlers/routes.server.js +16 -3
  54. package/dist/core/naming.d.ts +34 -0
  55. package/dist/core/naming.js +39 -0
  56. package/dist/core/operations/blocks/diff.server.js +1 -1
  57. package/dist/core/operations/blocks/extract.server.js +1 -1
  58. package/dist/core/operations/configMap/buildTreeMap.d.ts +3 -2
  59. package/dist/core/operations/configMap/buildTreeMap.js +1 -1
  60. package/dist/core/operations/configMap/index.d.ts +2 -1
  61. package/dist/core/operations/configMap/index.js +13 -13
  62. package/dist/core/operations/configMap/types.d.ts +2 -2
  63. package/dist/core/operations/hooks/before-read/process-document-fields.server.js +14 -17
  64. package/dist/core/operations/hooks/before-upsert/data-config-map.server.js +1 -1
  65. package/dist/core/operations/hooks/before-upsert/original-config-map.server.js +1 -1
  66. package/dist/core/operations/hooks/before-upsert/set-default-values.server.d.ts +2 -4
  67. package/dist/core/operations/hooks/before-upsert/set-default-values.server.js +10 -15
  68. package/dist/core/operations/hooks/before-upsert/validate-fields.server.js +49 -31
  69. package/dist/core/operations/relations/extract.server.js +5 -5
  70. package/dist/core/operations/shared/fallback-data-from-original.js +2 -2
  71. package/dist/core/operations/tree/diff.server.js +1 -1
  72. package/dist/core/operations/tree/extract.server.js +1 -1
  73. package/dist/core/plugins/cache/cache.server.js +3 -3
  74. package/dist/fields/blocks/component/AddBlockButton.svelte +7 -7
  75. package/dist/fields/blocks/component/AddBlockButton.svelte.d.ts +2 -2
  76. package/dist/fields/blocks/component/Blocks.svelte +6 -7
  77. package/dist/fields/blocks/component/props.d.ts +2 -2
  78. package/dist/fields/blocks/index.d.ts +1 -1
  79. package/dist/fields/blocks/index.js +3 -3
  80. package/dist/fields/blocks/index.server.js +1 -1
  81. package/dist/fields/checkbox/component/Checkbox.svelte +2 -2
  82. package/dist/fields/checkbox/component/props.d.ts +2 -2
  83. package/dist/fields/checkbox/index.server.d.ts +1 -2
  84. package/dist/fields/checkbox/index.server.js +1 -10
  85. package/dist/fields/combobox/component/ComboBox.svelte +3 -3
  86. package/dist/fields/combobox/component/props.d.ts +2 -2
  87. package/dist/fields/combobox/index.server.d.ts +1 -2
  88. package/dist/fields/combobox/index.server.js +2 -11
  89. package/dist/fields/component/index.d.ts +1 -1
  90. package/dist/fields/date/component/Date.svelte +4 -4
  91. package/dist/fields/date/component/Date.svelte.d.ts +2 -2
  92. package/dist/fields/date/index.d.ts +3 -1
  93. package/dist/fields/date/index.js +3 -0
  94. package/dist/fields/date/index.server.d.ts +1 -2
  95. package/dist/fields/date/index.server.js +1 -10
  96. package/dist/fields/email/component/Email.svelte +5 -6
  97. package/dist/fields/email/component/props.d.ts +2 -3
  98. package/dist/fields/email/index.d.ts +3 -2
  99. package/dist/fields/email/index.js +4 -1
  100. package/dist/fields/email/index.server.d.ts +0 -3
  101. package/dist/fields/email/index.server.js +0 -9
  102. package/dist/fields/group/component/Group.svelte +9 -15
  103. package/dist/fields/group/component/Group.svelte.d.ts +2 -2
  104. package/dist/fields/group/index.d.ts +4 -2
  105. package/dist/fields/group/index.server.js +2 -2
  106. package/dist/fields/index.server.d.ts +1 -4
  107. package/dist/fields/index.server.js +17 -13
  108. package/dist/fields/link/component/Link.svelte +5 -5
  109. package/dist/fields/link/component/props.d.ts +2 -2
  110. package/dist/fields/link/index.d.ts +4 -1
  111. package/dist/fields/link/index.js +9 -10
  112. package/dist/fields/link/runtime.d.ts +2 -0
  113. package/dist/fields/link/runtime.js +1 -0
  114. package/dist/fields/link/{index.server.d.ts → runtime.server.d.ts} +1 -2
  115. package/dist/fields/link/{index.server.js → runtime.server.js} +2 -11
  116. package/dist/fields/number/component/Number.svelte +6 -6
  117. package/dist/fields/number/component/props.d.ts +2 -2
  118. package/dist/fields/number/index.d.ts +4 -10
  119. package/dist/fields/number/index.js +3 -4
  120. package/dist/fields/number/index.server.d.ts +1 -2
  121. package/dist/fields/number/index.server.js +1 -10
  122. package/dist/fields/radio/component/Radio.svelte +6 -7
  123. package/dist/fields/radio/component/props.d.ts +2 -2
  124. package/dist/fields/radio/index.server.d.ts +1 -2
  125. package/dist/fields/radio/index.server.js +2 -11
  126. package/dist/fields/relation/component/Relation.svelte +18 -14
  127. package/dist/fields/relation/component/Relation.svelte.d.ts +2 -2
  128. package/dist/fields/relation/index.d.ts +7 -4
  129. package/dist/fields/relation/index.js +8 -47
  130. package/dist/fields/relation/runtime.d.ts +5 -0
  131. package/dist/fields/relation/runtime.js +4 -0
  132. package/dist/fields/relation/runtime.server.d.ts +8 -0
  133. package/dist/fields/relation/runtime.server.js +49 -0
  134. package/dist/fields/rich-text/component/RichText.svelte +5 -5
  135. package/dist/fields/rich-text/component/props.d.ts +2 -2
  136. package/dist/fields/rich-text/core/features/fields/fields.svelte +2 -2
  137. package/dist/fields/rich-text/index.d.ts +2 -0
  138. package/dist/fields/rich-text/index.js +3 -0
  139. package/dist/fields/rich-text/index.server.d.ts +1 -2
  140. package/dist/fields/rich-text/index.server.js +1 -10
  141. package/dist/fields/select/component/Select.svelte +16 -16
  142. package/dist/fields/select/component/props.d.ts +2 -2
  143. package/dist/fields/select/index.d.ts +2 -0
  144. package/dist/fields/select/index.js +3 -0
  145. package/dist/fields/select/index.server.d.ts +1 -2
  146. package/dist/fields/select/index.server.js +2 -17
  147. package/dist/fields/slug/component/Slug.svelte +14 -10
  148. package/dist/fields/slug/component/Slug.svelte.d.ts +2 -2
  149. package/dist/fields/slug/index.d.ts +5 -2
  150. package/dist/fields/slug/index.js +3 -0
  151. package/dist/fields/slug/index.server.d.ts +1 -2
  152. package/dist/fields/slug/index.server.js +1 -10
  153. package/dist/fields/tabs/component/Tabs.svelte +15 -15
  154. package/dist/fields/tabs/component/Tabs.svelte.d.ts +2 -2
  155. package/dist/fields/tabs/index.d.ts +4 -16
  156. package/dist/fields/tabs/index.js +1 -8
  157. package/dist/fields/tabs/index.server.js +3 -3
  158. package/dist/fields/text/component/Text.svelte +5 -5
  159. package/dist/fields/text/component/props.d.ts +2 -3
  160. package/dist/fields/text/index.d.ts +4 -10
  161. package/dist/fields/text/index.js +3 -4
  162. package/dist/fields/text/index.server.d.ts +1 -2
  163. package/dist/fields/text/index.server.js +1 -10
  164. package/dist/fields/textarea/component/TextArea.svelte +3 -3
  165. package/dist/fields/textarea/component/props.d.ts +2 -2
  166. package/dist/fields/textarea/index.d.ts +4 -1
  167. package/dist/fields/textarea/index.js +3 -0
  168. package/dist/fields/textarea/index.server.d.ts +1 -2
  169. package/dist/fields/textarea/index.server.js +1 -10
  170. package/dist/fields/time/component/Time.svelte +5 -5
  171. package/dist/fields/time/component/Time.svelte.d.ts +1 -1
  172. package/dist/fields/time/component/props.d.ts +2 -2
  173. package/dist/fields/time/index.d.ts +2 -0
  174. package/dist/fields/time/index.js +3 -0
  175. package/dist/fields/time/index.server.d.ts +1 -2
  176. package/dist/fields/time/index.server.js +1 -10
  177. package/dist/fields/toggle/component/Toggle.svelte +3 -3
  178. package/dist/fields/toggle/component/Toggle.svelte.d.ts +1 -1
  179. package/dist/fields/toggle/component/props.d.ts +2 -2
  180. package/dist/fields/toggle/index.d.ts +2 -1
  181. package/dist/fields/toggle/index.server.d.ts +1 -2
  182. package/dist/fields/toggle/index.server.js +1 -10
  183. package/dist/fields/tree/component/AddItemButton.svelte +1 -2
  184. package/dist/fields/tree/component/Tree.svelte +6 -6
  185. package/dist/fields/tree/component/TreeBlock.svelte +5 -12
  186. package/dist/fields/tree/component/props.d.ts +3 -3
  187. package/dist/fields/tree/index.d.ts +3 -1
  188. package/dist/fields/tree/index.js +2 -2
  189. package/dist/fields/types.d.ts +11 -5
  190. package/dist/panel/components/fields/FieldsPreview.svelte +4 -5
  191. package/dist/panel/components/fields/Hint.svelte +5 -4
  192. package/dist/panel/components/fields/Hint.svelte.d.ts +3 -2
  193. package/dist/panel/components/fields/Label.svelte +6 -11
  194. package/dist/panel/components/fields/Label.svelte.d.ts +3 -2
  195. package/dist/panel/components/fields/LabelFor.svelte +4 -4
  196. package/dist/panel/components/fields/LabelFor.svelte.d.ts +2 -1
  197. package/dist/panel/components/fields/RenderFields.svelte +11 -16
  198. package/dist/panel/components/fields/{root.svelte.d.ts → fieldset.svelte.d.ts} +1 -1
  199. package/dist/panel/components/fields/{root.svelte.js → fieldset.svelte.js} +1 -1
  200. package/dist/panel/components/fields/index.d.ts +5 -5
  201. package/dist/panel/components/fields/index.js +2 -2
  202. package/dist/panel/components/sections/document/AuthFooter.svelte +2 -7
  203. package/dist/panel/components/sections/live/LiveEditPanel.svelte +2 -2
  204. package/dist/panel/context/collection.svelte.js +9 -9
  205. package/dist/panel/context/documentForm.svelte.d.ts +8 -21
  206. package/dist/panel/context/documentForm.svelte.js +45 -52
  207. package/dist/panel/context/form.svelte.d.ts +4 -3
  208. package/dist/panel/context/form.svelte.js +14 -16
  209. package/dist/panel/pages/auth/fields.d.ts +4 -4
  210. package/dist/panel/pages/auth/fields.js +6 -22
  211. package/dist/panel/pages/auth/reset-password/ResetPassword.svelte +3 -10
  212. package/dist/util/doc.js +15 -17
  213. package/package.json +3 -2
  214. package/dist/fields/relation/index.server.d.ts +0 -4
  215. package/dist/fields/relation/index.server.js +0 -13
@@ -23,18 +23,20 @@ const createAreaFacade = (args) => {
23
23
  if (!areaConfig) {
24
24
  throw new RimeError(RimeError.INIT, slug + ' is not an area, should never happen');
25
25
  }
26
+ // `db.query[slug]` can't be typed precisely: with a single registered area,
27
+ // AreaSlug collapses to one string literal and Drizzle infers an overly
28
+ // precise (and here incorrect) per-table shape instead of the general one.
29
+ const queryTable = db.query[slug];
26
30
  const hasVersions = !!areaConfig.versions;
27
31
  if (!hasVersions) {
28
32
  const params = {
29
33
  columns: adapterUtil.columnsParams({ table: tables[slug], select }),
30
34
  with: buildWithParam({ slug, select, locale, tables, config: areaConfig }) || undefined
31
35
  };
32
- // @ts-expect-error slug is a tableName
33
- let doc = await db.query[slug].findFirst(params);
36
+ let doc = await queryTable.findFirst(params);
34
37
  if (!doc) {
35
38
  await createArea(slug, createBlankDocument(areaConfig, getRequestEvent()), locale);
36
- // @ts-expect-error slug is a tableName
37
- doc = await db.query[slug].findFirst(params);
39
+ doc = await queryTable.findFirst(params);
38
40
  }
39
41
  if (!doc) {
40
42
  throw new Error('Database error');
@@ -43,8 +45,7 @@ const createAreaFacade = (args) => {
43
45
  }
44
46
  else {
45
47
  // First check for record presence
46
- // @ts-expect-error slug is a tableName
47
- const area = await db.query[slug].findFirst({ id: true });
48
+ const area = await queryTable.findFirst({ id: true });
48
49
  // If no area exists yet, create it
49
50
  if (!area) {
50
51
  await createArea(slug, createBlankDocument(areaConfig, getRequestEvent()), locale);
@@ -98,8 +99,7 @@ const createAreaFacade = (args) => {
98
99
  }
99
100
  };
100
101
  }
101
- // @ts-expect-error slug is a tableName
102
- const doc = await db.query[slug].findFirst(params);
102
+ const doc = await queryTable.findFirst(params);
103
103
  if (!doc) {
104
104
  throw new RimeError(RimeError.OPERATION_ERROR);
105
105
  }
@@ -0,0 +1,13 @@
1
+ import type { FormFieldBuilder } from '../../core/fields/builders/form-field-builder.js';
2
+ import type { FormField } from '../../fields/types.js';
3
+ /**
4
+ * Renders a single Drizzle column definition for any leaf FormFieldBuilder,
5
+ * driven by the field's own `dataType` (storage type) and `_references`
6
+ * (foreign key) — the adapter owns all Drizzle syntax, fields only declare
7
+ * storage semantics via `dataType`.
8
+ *
9
+ * @example
10
+ * // returns "title: text('title').notNull().default(\"\"),"
11
+ * toSchemaColumn(text('title').required())
12
+ */
13
+ export declare function toSchemaColumn(field: FormFieldBuilder<FormField>, parentPath?: string): string;
@@ -0,0 +1,77 @@
1
+ import { templateReferences, templateUniqueRequired } from './templates.server.js';
2
+ import { getSchemaColumnNames } from './util.server.js';
3
+ const COLUMN_EXPR = {
4
+ text: (snake) => `text('${snake}')`,
5
+ boolean: (snake) => `integer('${snake}', { mode: 'boolean' })`,
6
+ number: (snake) => `real('${snake}')`,
7
+ timestamp: (snake) => `integer('${snake}', { mode: 'timestamp_ms' })`,
8
+ json: (snake) => `text('${snake}', { mode: 'json' })`
9
+ };
10
+ // Single-call type guards for RESOLVE_DEFAULT below — calling
11
+ // f.get.defaultValue itself has no reason to run twice per branch.
12
+ // `ensureObject` intentionally matches `typeof v === 'object'` including
13
+ // `null` (not `v !== null`), since that's what the pre-refactor per-field
14
+ // toSchema checks did — a field with no explicit default (constructor sets
15
+ // `defaultValue = null`) will keep `null`, not fall back to `{}`. Not
16
+ // touching that here, even though it looks like a latent bug.
17
+ const ensureString = (v) => (typeof v === 'string' ? v : undefined);
18
+ const ensureNumber = (v) => (typeof v === 'number' ? v : undefined);
19
+ const ensureBoolean = (v) => (typeof v === 'boolean' ? v : undefined);
20
+ const ensureDate = (v) => (v instanceof Date ? v : undefined);
21
+ const ensureObject = (v) => typeof v === 'object' ? v : undefined;
22
+ /**
23
+ * Resolves the `.default(...)` fallback used when a field is required but has
24
+ * no usable value in `field.defaultValue` — SQLite needs a type-correct
25
+ * DEFAULT to add a NOT NULL column via drizzle-kit migration on a table with
26
+ * existing rows. Keyed by field type (not dataType) and reading
27
+ * `field.get.defaultValue` directly, exactly mirroring what each field's own
28
+ * `toSchema` did before this refactor — kept here, not on the field builders,
29
+ * since it's schema-generation-only and not part of a field's public API.
30
+ */
31
+ const RESOLVE_DEFAULT = {
32
+ text: (f) => ensureString(f.get.defaultValue) ?? '',
33
+ email: (f) => ensureString(f.get.defaultValue) ?? '',
34
+ slug: (f) => ensureString(f.get.defaultValue) ?? '',
35
+ combobox: (f) => ensureString(f.get.defaultValue) ?? '',
36
+ radio: (f) => ensureString(f.get.defaultValue) ?? '',
37
+ textarea: (f) => ensureString(f.get.defaultValue) ?? '',
38
+ time: (f) => ensureString(f.get.defaultValue) ?? '00:00',
39
+ checkbox: (f) => f.get.defaultValue ?? false,
40
+ toggle: (f) => ensureBoolean(f.get.defaultValue) ?? false,
41
+ number: (f) => ensureNumber(f.get.defaultValue) ?? 0,
42
+ date: (f) => ensureDate(f.get.defaultValue)?.getTime() ?? 0,
43
+ link: (f) => ensureObject(f.get.defaultValue) ?? {},
44
+ richText: (f) => ensureObject(f.get.defaultValue) ?? {},
45
+ relation: () => ({}),
46
+ select: (f) => {
47
+ const many = f.get.many;
48
+ const empty = many ? [] : '';
49
+ const value = f.get.defaultValue;
50
+ return typeof value === 'undefined' ? empty : value;
51
+ }
52
+ };
53
+ /**
54
+ * Renders a single Drizzle column definition for any leaf FormFieldBuilder,
55
+ * driven by the field's own `dataType` (storage type) and `_references`
56
+ * (foreign key) — the adapter owns all Drizzle syntax, fields only declare
57
+ * storage semantics via `dataType`.
58
+ *
59
+ * @example
60
+ * // returns "title: text('title').notNull().default(\"\"),"
61
+ * toSchemaColumn(text('title').required())
62
+ */
63
+ export function toSchemaColumn(field, parentPath) {
64
+ const { camel, snake } = getSchemaColumnNames({ name: field.name, parentPath });
65
+ // `unique` only exists on the field types that support it (text/email/slug);
66
+ // reading it off the generic FormField base needs a narrow cast, same as
67
+ // each field's own toSchema did today by typing against its concrete field.
68
+ const { unique, required } = field.get;
69
+ // `dataType` is implemented by every leaf field builder but isn't declared
70
+ // on the FormFieldBuilder base (see the comment there) — narrow cast here.
71
+ const dataType = field.dataType;
72
+ const columnExpr = COLUMN_EXPR[dataType](snake);
73
+ const referencesStr = field._references ? templateReferences(field._references) : '';
74
+ const defaultValue = RESOLVE_DEFAULT[field.type]?.(field);
75
+ const suffix = templateUniqueRequired({ unique, required }, defaultValue);
76
+ return `${camel}: ${columnExpr}${referencesStr}${suffix}`;
77
+ }
@@ -1,7 +1,7 @@
1
1
  import { withVersionsSuffix } from '../../core/naming.js';
2
2
  import { date } from '../../fields/date/index.js';
3
- import { getFieldPrivateModule } from '../../fields/index.server.js';
4
3
  import { toCamelCase, toCamelCasePreserveTrailingUnderscoreSuffix, toPascalCase, toSnakeCase } from '../../util/string.js';
4
+ import { toSchemaColumn } from './column.server.js';
5
5
  import { generateRelationshipDefinitions } from './relations/definition.server.js';
6
6
  import { generateJunctionTableDefinition } from './relations/junction.server.js';
7
7
  import buildRootTable from './root.server.js';
@@ -20,9 +20,6 @@ export async function generateSchemaString(config) {
20
20
  let rootTableName = collectionSlug;
21
21
  let versionsRelationsDefinitions = [];
22
22
  schema.push(templateHead(collectionSlug));
23
- // utility function to filter out fields
24
- const isRootField = (field) => '_root' in field.raw && field.raw._root;
25
- const isNotRootField = (field) => !('_root' in field.raw) || !field.raw._root;
26
23
  if (collection.versions) {
27
24
  // Collection that have versions may need some fields forced on the root table and not root_versions
28
25
  // process the root table with these fields first then, handle versions related tables creation
@@ -30,7 +27,7 @@ export async function generateSchemaString(config) {
30
27
  // base root fields for versioned tables
31
28
  const baseRootFields = [date('createdAt').hidden(), date('updatedAt').hidden()];
32
29
  // Split fields that should be used on the root table
33
- const rootFieldsFromConfig = [...collection.fields].filter(isRootField);
30
+ const rootFieldsFromConfig = [...collection.fields].filter((f) => f.get.root);
34
31
  const rootFields = [...rootFieldsFromConfig, ...baseRootFields];
35
32
  // Build the main root buildRootTable with only _root fields and created/updatedAt
36
33
  const { schema: rootCollectionSchema } = await buildRootTable({
@@ -72,7 +69,9 @@ export async function generateSchemaString(config) {
72
69
  }
73
70
  const { schema: collectionSchema, relationsDic, relationFieldsMap, relationFieldsHasLocale } = await buildRootTable({
74
71
  blocksRegister,
75
- fields: collection.versions ? collection.fields.filter(isNotRootField) : collection.fields,
72
+ fields: collection.versions
73
+ ? collection.fields.filter((f) => !f.get.root)
74
+ : collection.fields,
76
75
  rootName: rootTableName,
77
76
  locales: config.localization?.locales || [],
78
77
  hasAuth: !!collection.auth,
@@ -120,12 +119,8 @@ export async function generateSchemaString(config) {
120
119
  const manyVersionsToOneName = `rel_${rootTableName}HasOne${toPascalCase(areaSlug)}`;
121
120
  const oneToManyVersionsName = `rel_${areaSlug}HasMany${toPascalCase(rootTableName)}`;
122
121
  const baseRootFields = [date('createdAt').hidden(), date('updatedAt').hidden()];
123
- async function fieldToSchema(field) {
124
- const serverField = await getFieldPrivateModule(field);
125
- return serverField && serverField.toSchema(field);
126
- }
127
- const schemaResults = await Promise.all(baseRootFields.map(fieldToSchema));
128
- schema.push(templateTable(areaSlug, schemaResults.filter(Boolean).join(',\n')));
122
+ const schemaResults = baseRootFields.map((field) => toSchemaColumn(field));
123
+ schema.push(templateTable(areaSlug, schemaResults.join(',\n')));
129
124
  versionsRelationsDefinitions = [
130
125
  templateRelationOne({
131
126
  name: manyVersionsToOneName,
@@ -1,14 +1,13 @@
1
1
  import {} from '../../core/fields/builders/field-builder.js';
2
2
  import { FormFieldBuilder } from '../../core/fields/builders/form-field-builder.js';
3
- import { isFormField } from '../../core/fields/util.js';
4
3
  import { withLocalesSuffix } from '../../core/naming.js';
5
- import { isBlocksField } from '../../fields/blocks/index.js';
6
- import { GroupFieldBuilder, isGroupField } from '../../fields/group/index.js';
7
- import { getFieldPrivateModule } from '../../fields/index.server.js';
8
- import { isRelationField } from '../../fields/relation/index.js';
9
- import { isTabsField } from '../../fields/tabs/index.js';
4
+ import { BlocksBuilder } from '../../fields/blocks/index.js';
5
+ import { GroupFieldBuilder } from '../../fields/group/index.js';
6
+ import { RelationFieldBuilder } from '../../fields/relation/index.js';
7
+ import { TabsBuilder } from '../../fields/tabs/index.js';
10
8
  import { TreeBuilder } from '../../fields/tree/index.js';
11
9
  import { toPascalCase } from '../../util/string.js';
10
+ import { toSchemaColumn } from './column.server.js';
12
11
  import { templateHasAuth, templateLocale, templateParent, templateTable } from './templates.server.js';
13
12
  const p = toPascalCase;
14
13
  /**
@@ -22,38 +21,38 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
22
21
  const generateFieldsTemplates = async (fields, withLocalized, parentPath = '') => {
23
22
  let templates = [];
24
23
  const checkLocalized = (field) => {
25
- return ((withLocalized && field.raw.localized) ||
26
- (!withLocalized && !field.raw.localized) ||
24
+ return ((withLocalized && field.get.localized) ||
25
+ (!withLocalized && !field.get.localized) ||
27
26
  withLocalized === undefined);
28
27
  };
29
28
  for (const field of fields) {
30
29
  if (field instanceof GroupFieldBuilder) {
31
30
  const groupPath = parentPath ? `${parentPath}__${field.name}` : field.name;
32
- const groupFields = await generateFieldsTemplates(field.raw.fields, withLocalized, groupPath);
31
+ const groupFields = await generateFieldsTemplates(field.get.fields, withLocalized, groupPath);
33
32
  templates = [...templates, ...groupFields];
34
33
  }
35
- else if (isTabsField(field.raw)) {
36
- for (const tab of field.raw.tabs) {
37
- const tabPath = parentPath ? `${parentPath}__${tab.raw.name}` : tab.raw.name;
38
- const tabFields = await generateFieldsTemplates(tab.raw.fields, withLocalized, tabPath);
34
+ else if (field instanceof TabsBuilder) {
35
+ for (const tab of field.get.tabs) {
36
+ const tabPath = parentPath ? `${parentPath}__${tab.name}` : tab.name;
37
+ const tabFields = await generateFieldsTemplates(tab.get.fields, withLocalized, tabPath);
39
38
  templates = [...templates, ...tabFields];
40
39
  }
41
40
  }
42
- else if (isRelationField(field.raw)) {
43
- if (field.raw.localized) {
41
+ else if (field instanceof RelationFieldBuilder) {
42
+ if (field.get.localized) {
44
43
  relationFieldsHasLocale = true;
45
44
  }
46
45
  relationFieldsMap = {
47
46
  ...relationFieldsMap,
48
- [field.raw.name]: {
49
- to: field.raw.relationTo,
50
- localized: field.raw.localized
47
+ [field.name]: {
48
+ to: field.get.relationTo,
49
+ localized: field.get.localized
51
50
  }
52
51
  };
53
52
  }
54
- else if (isBlocksField(field.raw)) {
55
- for (const block of field.raw.blocks) {
56
- const blockTableName = `${rootName}Blocks${p(block.raw.name)}`;
53
+ else if (field instanceof BlocksBuilder) {
54
+ for (const block of field.get.blocks) {
55
+ const blockTableName = `${rootName}Blocks${p(block.name)}`;
57
56
  if (!blocksRegister.includes(blockTableName)) {
58
57
  // Add the blocks as a relation of the root collection
59
58
  relationsDic = {
@@ -63,7 +62,7 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
63
62
  // Build the child blocks table
64
63
  const { schema: blockTable, relationsDic: nestedRelationsDic, relationFieldsMap: nestedRelationFieldsDic, relationFieldsHasLocale: nestedRelationFieldsHasLocale } = await buildRootTable({
65
64
  blocksRegister,
66
- fields: block.raw.fields,
65
+ fields: block.get.fields,
67
66
  tableName: blockTableName,
68
67
  hasParent: true,
69
68
  relationsDic,
@@ -90,7 +89,7 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
90
89
  };
91
90
  const { schema: treeTable, relationsDic: nestedRelationsDic, relationFieldsMap: nestedRelationFieldsDic, relationFieldsHasLocale: nestedRelationFieldsHasLocale } = await buildRootTable({
92
91
  blocksRegister,
93
- fields: field.raw.fields,
92
+ fields: field.get.fields,
94
93
  tableName: treeTableName,
95
94
  hasParent: true,
96
95
  relationsDic,
@@ -108,10 +107,7 @@ const buildRootTable = async ({ fields: incomingFields, tableName, rootName, has
108
107
  }
109
108
  else if (field instanceof FormFieldBuilder) {
110
109
  if (checkLocalized(field)) {
111
- const serverField = await getFieldPrivateModule(field);
112
- if (serverField) {
113
- templates.push(serverField.toSchema(field, parentPath) + ',');
114
- }
110
+ templates.push(toSchemaColumn(field, parentPath) + ',');
115
111
  }
116
112
  }
117
113
  }
@@ -159,39 +155,39 @@ function hasLocalizedField(fields) {
159
155
  // Iterate through each field in the array
160
156
  for (const field of fields) {
161
157
  // Case 1: If it's a group field, check all fields within the group
162
- if (isGroupField(field.raw)) {
163
- if (hasLocalizedField(field.raw.fields)) {
158
+ if (field instanceof GroupFieldBuilder) {
159
+ if (hasLocalizedField(field.get.fields)) {
164
160
  return true;
165
161
  }
166
162
  }
167
163
  // Case 2: If it's a tabs field, check all fields within each tab
168
- else if (isTabsField(field.raw)) {
169
- for (const tab of field.raw.tabs) {
170
- if (hasLocalizedField(tab.raw.fields)) {
164
+ else if (field instanceof TabsBuilder) {
165
+ for (const tab of field.get.tabs) {
166
+ if (hasLocalizedField(tab.get.fields)) {
171
167
  return true;
172
168
  }
173
169
  }
174
170
  }
175
171
  // Case 3: If it's a blocks field, check all fields within each block
176
- else if (isBlocksField(field.raw)) {
177
- if (field.raw.localized)
172
+ else if (field instanceof BlocksBuilder) {
173
+ if (field.get.localized)
178
174
  return true;
179
- for (const block of field.raw.blocks) {
180
- if (hasLocalizedField(block.raw.fields)) {
175
+ for (const block of field.get.blocks) {
176
+ if (hasLocalizedField(block.get.fields)) {
181
177
  return true;
182
178
  }
183
179
  }
184
180
  }
185
181
  // Case 3: If it's a tree field, check all fields
186
182
  else if (field instanceof TreeBuilder) {
187
- if (field.raw.localized)
183
+ if (field.get.localized)
188
184
  return true;
189
- if (hasLocalizedField(field.raw.fields)) {
185
+ if (hasLocalizedField(field.get.fields)) {
190
186
  return true;
191
187
  }
192
188
  }
193
189
  // Case 4: For regular form fields, check if it's marked as localized
194
- else if (isFormField(field.raw) && field.raw.localized) {
190
+ else if (field instanceof FormFieldBuilder && field.get.localized) {
195
191
  return true;
196
192
  }
197
193
  }
@@ -1,3 +1,4 @@
1
+ import type { FieldReference } from '../../core/fields/builders/form-field-builder.js';
1
2
  /**
2
3
  * Generates the standard imports needed for Drizzle ORM schema definitions
3
4
  * Includes SQLite table definitions, relations, and a primary key helper function
@@ -36,6 +37,17 @@ export declare const templateLocale: () => string;
36
37
  * ```
37
38
  */
38
39
  export declare const templateParent: (parent: string) => string;
40
+ /**
41
+ * Generates a `.references(...)` suffix for a field-level foreign key,
42
+ * used by column.server.ts's toSchemaColumn for fields configured via
43
+ * FormFieldBuilder#$references(...).
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * .references(() => staff.id, { onDelete: 'cascade' })
48
+ * ```
49
+ */
50
+ export declare const templateReferences: ({ table, onDelete, onUpdate, selfReferencing }: FieldReference) => string;
39
51
  /**
40
52
  * Generates authentication-related fields for a table
41
53
  * Adds super admin flag for the panel users table
@@ -55,6 +55,25 @@ export const templateLocale = () => 'locale: text("locale"),';
55
55
  export const templateParent = (parent) => {
56
56
  return `ownerId: text("owner_id").references(() => ${parent}.id, { onDelete: 'cascade' }),`;
57
57
  };
58
+ /**
59
+ * Generates a `.references(...)` suffix for a field-level foreign key,
60
+ * used by column.server.ts's toSchemaColumn for fields configured via
61
+ * FormFieldBuilder#$references(...).
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * .references(() => staff.id, { onDelete: 'cascade' })
66
+ * ```
67
+ */
68
+ export const templateReferences = ({ table, onDelete, onUpdate, selfReferencing }) => {
69
+ const arrow = selfReferencing ? '(): any =>' : '() =>';
70
+ const opts = [
71
+ onDelete ? `onDelete: '${onDelete}'` : '',
72
+ onUpdate ? `onUpdate: '${onUpdate}'` : ''
73
+ ].filter(Boolean);
74
+ const optsStr = opts.length ? `, { ${opts.join(', ')} }` : '';
75
+ return `.references(${arrow} ${table}.id${optsStr})`;
76
+ };
58
77
  /**
59
78
  * Generates authentication-related fields for a table
60
79
  * Adds super admin flag for the panel users table
@@ -15,8 +15,6 @@ import createTreeFacade from './tree.server.js';
15
15
  import type { GenericTable } from './types.server.js';
16
16
  import { updateDocumentUrl } from './url.server.js';
17
17
  import { updateTableRecord } from './util.server.js';
18
- export * as templates from './generate-schema/templates.server.js';
19
- export * as util from './generate-schema/util.server.js';
20
18
  type Schema = GetRegisterType<'Schema'>;
21
19
  export declare function adapterSqlite(database: string): {
22
20
  createAdapter: <C extends Config>(configCtx: ConfigContext<C>) => Promise<Adapter>;
@@ -38,3 +36,4 @@ export type Adapter = {
38
36
  readonly schema: Schema;
39
37
  readonly relationFieldsMap: RelationFieldsMap;
40
38
  };
39
+ export {};
@@ -10,8 +10,6 @@ import { transformerFacade } from './transform.server.js';
10
10
  import createTreeFacade from './tree.server.js';
11
11
  import { updateDocumentUrl } from './url.server.js';
12
12
  import { updateTableRecord } from './util.server.js';
13
- export * as templates from './generate-schema/templates.server.js';
14
- export * as util from './generate-schema/util.server.js';
15
13
  export function adapterSqlite(database) {
16
14
  //
17
15
  return {
@@ -10,8 +10,13 @@ const createRelationsFacade = ({ db, tables }) => {
10
10
  const table = tables[relationTableName];
11
11
  if (!table)
12
12
  return true;
13
+ // Only some relation tables have a `locale` column at all — it's added
14
+ // only when the collection has at least one .localized() relation field
15
+ // (see getAll's identical guard below). Without this check, eq(undefined,
16
+ // locale) produces SQL with a missing column reference.
17
+ const columns = Object.keys(getTableColumns(table));
13
18
  const conditions = [eq(table.ownerId, ownerId)];
14
- if (locale) {
19
+ if (locale && columns.includes('locale')) {
15
20
  conditions.push(eq(table.locale, locale));
16
21
  }
17
22
  const existingRelations = await db
@@ -69,12 +69,7 @@ export declare function prepareSchemaData(data: any, options: {
69
69
  * 4. Adds version fields while avoiding duplicates
70
70
  * 5. Includes the versionId in the result
71
71
  */
72
- export declare function mergeRawDocumentWithVersion(doc: RawDoc, versionTableName: string, select?: string[]): {
73
- versionId: any;
74
- id: string;
75
- } | {
76
- versionId: any;
77
- };
72
+ export declare function mergeRawDocumentWithVersion(doc: RawDoc, versionTableName: string, select?: string[]): RawDoc;
78
73
  /**
79
74
  * Build the query params to get either the latest updated document
80
75
  * or the published one if version.draft is enabled and draft is true
@@ -139,6 +139,8 @@ export function mergeRawDocumentWithVersion(doc, versionTableName, select) {
139
139
  // Filter out root props as they should come from the doc,
140
140
  // plus the ownerId wich is equals to doc.id
141
141
  const versionFields = omit([...rootProps, 'ownerId'], versionData);
142
+ // `pick`/`omit` return generic Dic types, so TS can't statically confirm
143
+ // `id` survived — it always does, since we explicitly pick it above.
142
144
  return {
143
145
  ...docFields,
144
146
  ...versionFields,
@@ -146,6 +148,10 @@ export function mergeRawDocumentWithVersion(doc, versionTableName, select) {
146
148
  };
147
149
  }
148
150
  // Default case - return all fields
151
+ // `versionTableName` is a plain `string`, not a literal, so `Omit<T, string>`
152
+ // widens to `Omit<T, keyof T>` and TS loses track of every spread key
153
+ // (including `id`) — the object is correct at runtime, only its inferred
154
+ // type collapses, hence the double cast through `unknown`.
149
155
  return {
150
156
  ...omit([versionTableName], doc),
151
157
  ...omit(['id', 'ownerId', 'createdAt', 'updatedAt'], versionData),
@@ -1,8 +1,8 @@
1
1
  import { RimeError } from '../core/errors/index.js';
2
- import { getFieldConfigByPath } from '../core/fields/util.js';
2
+ import { getFieldAtPath } from '../core/fields/util.js';
3
3
  import { logger } from '../core/logger/index.server.js';
4
4
  import { hasVersionsSuffix, withLocalesSuffix } from '../core/naming.js';
5
- import { isRelationField } from '../fields/relation/index.js';
5
+ import { RelationFieldBuilder } from '../fields/relation/index.js';
6
6
  import {} from '../index.js';
7
7
  import * as drizzleORM from 'drizzle-orm';
8
8
  import { and, eq, getTableColumns, inArray, or } from 'drizzle-orm';
@@ -65,9 +65,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
65
65
  // Look for a relation field
66
66
  // Get document config
67
67
  const documentConfig = configCtx.getBySlug(slug);
68
- // Get the compiled fields for lookups
69
- const compiledFields = documentConfig.fields.map((f) => f.compile());
70
- let fieldConfig = getFieldConfigByPath(column, compiledFields);
68
+ let fieldConfig = getFieldAtPath(column, documentConfig.fields);
71
69
  // Track relation-property detection (e.g. attributes.author.name)
72
70
  let matchedPrefix = column;
73
71
  let relationPropertyPath = null;
@@ -78,7 +76,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
78
76
  const parts = column.split('.');
79
77
  for (let i = parts.length - 1; i > 0; i--) {
80
78
  const prefix = parts.slice(0, i).join('.');
81
- const candidate = getFieldConfigByPath(prefix, compiledFields);
79
+ const candidate = getFieldAtPath(prefix, documentConfig.fields);
82
80
  if (candidate) {
83
81
  fieldConfig = candidate;
84
82
  // If prefix shorter than original column, record the property suffix
@@ -92,7 +90,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
92
90
  }
93
91
  }
94
92
  // If still not found or not a relation field, log warning and return false condition
95
- if (!fieldConfig || !isRelationField(fieldConfig)) {
93
+ if (!(fieldConfig instanceof RelationFieldBuilder)) {
96
94
  const message = `the query contains the field "${column}", not found for ${documentConfig.slug} document`;
97
95
  logger.warn(message);
98
96
  // Return a condition that will always be false instead of returning false
@@ -116,7 +114,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
116
114
  // Handle relation property queries (e.g., attributes.author.name)
117
115
  // by building a subquery on the related collection
118
116
  const buildRelationPropertyCondition = () => {
119
- const relatedSlug = fieldConfig.relationTo;
117
+ const relatedSlug = fieldConfig.get.relationTo;
120
118
  const relatedTable = getTable(relatedSlug);
121
119
  // Build a where clause for the related collection using the same operator/value
122
120
  const relatedWhere = { [relationPropertyPath]: { [operator]: rawValue } };
@@ -143,7 +141,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
143
141
  const ownersWithMatching = db
144
142
  .select({ id: relsTable.ownerId })
145
143
  .from(relsTable)
146
- .where(and(inArray(relsTable[`${relatedSlug}Id`], matchingRelatedIds), eq(relsTable.path, matchedPrefix), ...(fieldConfig.localized ? [eq(relsTable.locale, locale)] : [])));
144
+ .where(and(inArray(relsTable[`${relatedSlug}Id`], matchingRelatedIds), eq(relsTable.path, matchedPrefix), ...(fieldConfig.get.localized ? [eq(relsTable.locale, locale)] : [])));
147
145
  return inArray(table.id, ownersWithMatching);
148
146
  };
149
147
  // If this is a relation property query, delegate to the relation property handler
@@ -152,19 +150,22 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
152
150
  }
153
151
  // Handle direct relation field queries (e.g., attributes.author)
154
152
  // only support a subset of operators for multi-valued relations
155
- // Unsupported operator for multi-valued relations :
156
153
  const supportedRelationManyOperators = ['equals', 'not_equals', 'in_array', 'not_in_array'];
157
154
  // Only enforce the restriction for direct relation field queries.
158
155
  // If this is a relation property query (e.g. attributes.author.name) we allow
159
156
  // any operator because those will be applied to the related collection.
160
- if (fieldConfig.many && !supportedRelationManyOperators.includes(operator)) {
157
+ if (fieldConfig.get.many && !supportedRelationManyOperators.includes(operator)) {
161
158
  const unsupportedMessage = `the operator "${operator}" is not supported for multi-valued relation field "${column}" in ${documentConfig.slug} document`;
162
159
  logger.warn(unsupportedMessage);
163
160
  // Return a condition that will always be false
164
161
  return eq(table.id, '-1');
165
162
  }
166
163
  // Build relation condition
167
- const [to, localized] = [fieldConfig.relationTo, fieldConfig.localized];
164
+ const [to, localized, many] = [
165
+ fieldConfig.get.relationTo,
166
+ fieldConfig.get.localized,
167
+ fieldConfig.get.many
168
+ ];
168
169
  const relsTableName = `${slug}Rels`;
169
170
  const relsTable = getTable(relsTableName);
170
171
  // Helpers for building common relation-owner subqueries (operate on the relations table)
@@ -197,7 +198,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
197
198
  .having(drizzleORM.gt(drizzleORM.count(relsTable.id), 0));
198
199
  // Handle multi-valued relations specially when operator is `equals` to provide
199
200
  // strict equality semantics (the relation set must equal the provided value(s)).
200
- if (fieldConfig.many && operator === 'equals') {
201
+ if (many && operator === 'equals') {
201
202
  // Accept various input forms and normalize to a unique array
202
203
  const values = normalizeValues(rawValue, value);
203
204
  // Owners with total relation count equal to values.length
@@ -208,7 +209,7 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
208
209
  }
209
210
  // For multi-valued relations, allow `in_array` to act as a subset check:
210
211
  // The provided values must contain ALL relation values of the document.
211
- if (fieldConfig.many && operator === 'in_array') {
212
+ if (many && operator === 'in_array') {
212
213
  // Accept various input forms and normalize to a unique array
213
214
  const values = normalizeValues(rawValue, value);
214
215
  // Owners that have at least one relation row not included in the provided set
@@ -220,14 +221,14 @@ export const buildWhereParam = ({ query, slug, db, locale, tables, configCtx })
220
221
  }
221
222
  // For multi-valued relations, `not_in_array` should match documents where the provided
222
223
  // set does NOT contain all of the document's relation values (inverse of `in_array`).
223
- if (fieldConfig.many && operator === 'not_in_array') {
224
+ if (many && operator === 'not_in_array') {
224
225
  // Accept various input forms and normalize to a unique array
225
226
  const values = normalizeValues(rawValue, value);
226
227
  const ownersWithNonMatching = buildOwnersWithNonMatching(values);
227
228
  return inArray(table.id, ownersWithNonMatching);
228
229
  }
229
230
  // For multi-valued relations, `not_equals` is the inverse of `equals` (exact-set inequality)
230
- if (fieldConfig.many && operator === 'not_equals') {
231
+ if (many && operator === 'not_equals') {
231
232
  // Accept various input forms and normalize to a unique array
232
233
  const values = normalizeValues(rawValue, value);
233
234
  const ownersWithTotalCount = buildOwnersWithTotalCount(values.length);
@@ -1,8 +1,8 @@
1
- import { getFieldConfigByPath } from '../core/fields/util.js';
1
+ import { getFieldAtPath } from '../core/fields/util.js';
2
2
  import { withLocalesSuffix } from '../core/naming.js';
3
- import { isBlocksFieldRaw } from '../fields/blocks/index.js';
4
- import { isRelationField } from '../fields/relation/index.js';
5
- import { isTreeFieldRaw } from '../fields/tree/index.js';
3
+ import { BlocksBuilder } from '../fields/blocks/index.js';
4
+ import { RelationFieldBuilder } from '../fields/relation/index.js';
5
+ import { TreeBuilder } from '../fields/tree/index.js';
6
6
  import { asc, eq, getTableColumns, or, SQL } from 'drizzle-orm';
7
7
  import { getBlocksTableNames, getTreeTableNames } from './generate-schema/util.server.js';
8
8
  export const buildWithParam = (args) => {
@@ -22,12 +22,12 @@ export const buildWithParam = (args) => {
22
22
  for (const path of select) {
23
23
  // Convert dot notation to double underscore notation for SQLite queries
24
24
  const sqlPath = path.replace(/\./g, '__');
25
- const fieldConfig = getFieldConfigByPath(path, documentConfig.fields.map((f) => f.compile()));
26
- if (fieldConfig && isRelationField(fieldConfig)) {
25
+ const fieldConfig = getFieldAtPath(path, documentConfig.fields);
26
+ if (fieldConfig instanceof RelationFieldBuilder) {
27
27
  // Handle relation fields
28
28
  directRelationPaths.push(path);
29
29
  }
30
- else if (fieldConfig && isBlocksFieldRaw(fieldConfig)) {
30
+ else if (fieldConfig instanceof BlocksBuilder) {
31
31
  // Handle blocks fields
32
32
  blockPaths.push(path);
33
33
  const blocksTables = getBlocksTableNames(slug, tables);
@@ -56,7 +56,7 @@ export const buildWithParam = (args) => {
56
56
  }
57
57
  }
58
58
  }
59
- else if (fieldConfig && isTreeFieldRaw(fieldConfig)) {
59
+ else if (fieldConfig instanceof TreeBuilder) {
60
60
  // Handle tree fields
61
61
  treePaths.push(path);
62
62
  const treeTables = getTreeTableNames(slug, tables);
@@ -87,7 +87,7 @@ export const buildWithParam = (args) => {
87
87
  }
88
88
  else if (fieldConfig) {
89
89
  // Handle regular fields
90
- if (fieldConfig.localized && locale) {
90
+ if (fieldConfig.get.localized && locale) {
91
91
  const localesTableName = withLocalesSuffix(slug);
92
92
  if (localesTableName in tables) {
93
93
  const tableLocales = tables[localesTableName];