@rebasepro/server-postgres 0.17.3 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/LICENSE +0 -1
  2. package/README.md +31 -0
  3. package/dist/BranchService-ByLfM_Tt.js +360 -0
  4. package/dist/BranchService-ByLfM_Tt.js.map +1 -0
  5. package/dist/__vite-browser-external-BnuHet1e.js +46 -0
  6. package/dist/__vite-browser-external-BnuHet1e.js.map +1 -0
  7. package/dist/arg-Dni7MzLB.js +87 -0
  8. package/dist/arg-Dni7MzLB.js.map +1 -0
  9. package/dist/auth-users-columns-D2LBFrMH.js +116 -0
  10. package/dist/auth-users-columns-D2LBFrMH.js.map +1 -0
  11. package/dist/backup-argv.d.ts +19 -0
  12. package/dist/backup-cli-oM9WQVlV.js +408 -0
  13. package/dist/backup-cli-oM9WQVlV.js.map +1 -0
  14. package/dist/backup-service-Br3tqwsy.js +715 -0
  15. package/dist/backup-service-Br3tqwsy.js.map +1 -0
  16. package/dist/branch-argv.d.ts +28 -0
  17. package/dist/branch-prune.d.ts +77 -0
  18. package/dist/cli-collections-path.d.ts +31 -0
  19. package/dist/cli-errors-DxN4yzdH.js +657 -0
  20. package/dist/cli-errors-DxN4yzdH.js.map +1 -0
  21. package/dist/cli-errors.d.ts +123 -0
  22. package/dist/cli-flags.d.ts +101 -0
  23. package/dist/cli-helpers.d.ts +94 -10
  24. package/dist/cli-output-CNdMql-L.js +47 -0
  25. package/dist/cli-output-CNdMql-L.js.map +1 -0
  26. package/dist/cli.js +2020 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/collection-index-BHgT_TKd.js +276 -0
  29. package/dist/collection-index-BHgT_TKd.js.map +1 -0
  30. package/dist/{collections-schema-version-BMeu3cgv.js → collections-schema-version-T6cGvrDi.js} +1 -2
  31. package/dist/{collections-schema-version-BMeu3cgv.js.map → collections-schema-version-T6cGvrDi.js.map} +1 -1
  32. package/dist/{connection-GOKU3Hu5.js → databasePoolManager-Bj5FbeAs.js} +112 -40
  33. package/dist/databasePoolManager-Bj5FbeAs.js.map +1 -0
  34. package/dist/databasePoolManager.d.ts +27 -0
  35. package/dist/doctor-D7HWmGzs.js +974 -0
  36. package/dist/doctor-D7HWmGzs.js.map +1 -0
  37. package/dist/{ensure-collection-policies-UCqgv_8c.js → ensure-collection-policies-2c2NV8zX.js} +7 -27
  38. package/dist/ensure-collection-policies-2c2NV8zX.js.map +1 -0
  39. package/dist/ensure-collection-tables-D4wJzM4y.js +820 -0
  40. package/dist/ensure-collection-tables-D4wJzM4y.js.map +1 -0
  41. package/dist/ensure-tables-CIojK-Rx.js +650 -0
  42. package/dist/ensure-tables-CIojK-Rx.js.map +1 -0
  43. package/dist/generate-drizzle-schema-CwEgVyjO.js +123 -0
  44. package/dist/generate-drizzle-schema-CwEgVyjO.js.map +1 -0
  45. package/dist/generate-drizzle-schema-logic-so2Z_lyC.js +528 -0
  46. package/dist/generate-drizzle-schema-logic-so2Z_lyC.js.map +1 -0
  47. package/dist/{ensure-collection-tables-DgVixhX3.js → generate-postgres-ddl-logic-CtnpIBVv.js} +126 -984
  48. package/dist/generate-postgres-ddl-logic-CtnpIBVv.js.map +1 -0
  49. package/dist/generated-schema-staleness-DQdfJl2A.js +157 -0
  50. package/dist/generated-schema-staleness-DQdfJl2A.js.map +1 -0
  51. package/dist/index.d.ts +12 -0
  52. package/dist/index.es.js +7423 -1133
  53. package/dist/index.es.js.map +1 -1
  54. package/dist/introspect-db-logic-C6LQdTxj.js +1378 -0
  55. package/dist/introspect-db-logic-C6LQdTxj.js.map +1 -0
  56. package/dist/policy-drift-kNJ6X2Uj.js +313 -0
  57. package/dist/policy-drift-kNJ6X2Uj.js.map +1 -0
  58. package/dist/{backup-service-DCk7KhhL.js → rls-bootstrap-sql-DLDnUjtx.js} +737 -2689
  59. package/dist/rls-bootstrap-sql-DLDnUjtx.js.map +1 -0
  60. package/dist/{rls-enforcement-DvAbL9YJ.js → rls-enforcement-DeYEjYLt.js} +65 -190
  61. package/dist/rls-enforcement-DeYEjYLt.js.map +1 -0
  62. package/dist/schema/bin/generate-drizzle-schema.d.ts +1 -0
  63. package/dist/schema/bin/generate-postgres-ddl.d.ts +1 -0
  64. package/dist/schema/column-type-drift.d.ts +79 -0
  65. package/dist/schema/doctor-cli.js +129 -0
  66. package/dist/schema/doctor-cli.js.map +1 -0
  67. package/dist/schema/doctor.d.ts +42 -0
  68. package/dist/schema/ensure-collection-tables.d.ts +90 -0
  69. package/dist/schema/generate-drizzle-schema.d.ts +1 -1
  70. package/dist/schema/generate-drizzle-schema.js +24 -0
  71. package/dist/schema/generate-drizzle-schema.js.map +1 -0
  72. package/dist/schema/generate-next-step.d.ts +30 -0
  73. package/dist/schema/generate-postgres-ddl-logic.d.ts +28 -0
  74. package/dist/schema/generate-postgres-ddl.d.ts +1 -1
  75. package/dist/schema/generate-postgres-ddl.js +138 -0
  76. package/dist/schema/generate-postgres-ddl.js.map +1 -0
  77. package/dist/schema/generated-schema-staleness.d.ts +37 -0
  78. package/dist/schema/introspect-db-queries.d.ts +34 -0
  79. package/dist/schema/introspect-db.js +866 -0
  80. package/dist/schema/introspect-db.js.map +1 -0
  81. package/dist/security/rls-enforcement.d.ts +63 -2
  82. package/dist/services/BranchService.d.ts +86 -1
  83. package/dist/services/collection-helpers.d.ts +1 -1
  84. package/dist/services/realtimeService.d.ts +30 -2
  85. package/dist/services/row-pipeline.d.ts +12 -1
  86. package/dist/source-Br7L7GOI.js +410 -0
  87. package/dist/source-Br7L7GOI.js.map +1 -0
  88. package/dist/utils/pg-error-utils.d.ts +3 -1
  89. package/dist/utils/pg-numeric-number-patch.d.ts +31 -0
  90. package/dist/vector-index-DkWxm2de.js +309 -0
  91. package/dist/vector-index-DkWxm2de.js.map +1 -0
  92. package/package.json +32 -27
  93. package/dist/backup-service-DCk7KhhL.js.map +0 -1
  94. package/dist/collection-index-BRUg10H5.js +0 -5690
  95. package/dist/collection-index-BRUg10H5.js.map +0 -1
  96. package/dist/connection-GOKU3Hu5.js.map +0 -1
  97. package/dist/ensure-collection-policies-UCqgv_8c.js.map +0 -1
  98. package/dist/ensure-collection-tables-DgVixhX3.js.map +0 -1
  99. package/dist/rls-bootstrap-sql-B5C9LoJ6.js +0 -244
  100. package/dist/rls-bootstrap-sql-B5C9LoJ6.js.map +0 -1
  101. package/dist/rls-enforcement-DvAbL9YJ.js.map +0 -1
  102. package/dist/src-DiB5RP2Z.js +0 -541
  103. package/dist/src-DiB5RP2Z.js.map +0 -1
  104. package/dist/websocket-BZ4H5wUz.js +0 -8198
  105. package/dist/websocket-BZ4H5wUz.js.map +0 -1
  106. package/src/PostgresAdapter.ts +0 -91
  107. package/src/PostgresBackendDriver.ts +0 -1857
  108. package/src/PostgresBootstrapper.ts +0 -1157
  109. package/src/auth/ensure-tables.ts +0 -896
  110. package/src/auth/schema-version.ts +0 -260
  111. package/src/auth/services.ts +0 -1610
  112. package/src/backup/backup-cli.ts +0 -520
  113. package/src/backup/backup-cron.ts +0 -212
  114. package/src/backup/backup-logic.ts +0 -93
  115. package/src/backup/backup-service.ts +0 -485
  116. package/src/backup/index.ts +0 -12
  117. package/src/backup/pg-tools.ts +0 -403
  118. package/src/backup/retention.ts +0 -86
  119. package/src/cli-errors.ts +0 -265
  120. package/src/cli-helpers.ts +0 -569
  121. package/src/cli-output.ts +0 -43
  122. package/src/cli.ts +0 -1339
  123. package/src/collections/PostgresCollectionRegistry.ts +0 -108
  124. package/src/collections/buildRegistry.ts +0 -68
  125. package/src/collections/validate-relations.ts +0 -402
  126. package/src/connection.ts +0 -333
  127. package/src/data-transformer.ts +0 -845
  128. package/src/databasePoolManager.ts +0 -95
  129. package/src/history/HistoryService.ts +0 -254
  130. package/src/history/ensure-history-table.ts +0 -53
  131. package/src/index.ts +0 -19
  132. package/src/interfaces.ts +0 -60
  133. package/src/module-dir.ts +0 -7
  134. package/src/schema/atlas-argv.ts +0 -94
  135. package/src/schema/auth-schema.ts +0 -298
  136. package/src/schema/auth-users-columns.ts +0 -131
  137. package/src/schema/carved-out-migration.ts +0 -404
  138. package/src/schema/classify-change.ts +0 -436
  139. package/src/schema/collection-index.ts +0 -427
  140. package/src/schema/collections-schema-version.ts +0 -103
  141. package/src/schema/destructive-sql.ts +0 -94
  142. package/src/schema/doctor-cli.ts +0 -66
  143. package/src/schema/doctor-policy-checks.ts +0 -105
  144. package/src/schema/doctor.ts +0 -837
  145. package/src/schema/drizzle-ddl.ts +0 -33
  146. package/src/schema/dynamic-tables.test.ts +0 -302
  147. package/src/schema/dynamic-tables.ts +0 -293
  148. package/src/schema/ensure-collection-policies.ts +0 -198
  149. package/src/schema/ensure-collection-tables.test.ts +0 -518
  150. package/src/schema/ensure-collection-tables.ts +0 -1267
  151. package/src/schema/generate-drizzle-schema-logic.ts +0 -957
  152. package/src/schema/generate-drizzle-schema.ts +0 -143
  153. package/src/schema/generate-postgres-ddl-logic.ts +0 -1339
  154. package/src/schema/generate-postgres-ddl.ts +0 -180
  155. package/src/schema/generate-schema-commit.ts +0 -267
  156. package/src/schema/generated-schema-staleness.ts +0 -284
  157. package/src/schema/introspect-db-constraints.ts +0 -385
  158. package/src/schema/introspect-db-inference.ts +0 -255
  159. package/src/schema/introspect-db-logic.ts +0 -1387
  160. package/src/schema/introspect-db-naming.ts +0 -15
  161. package/src/schema/introspect-db-project.ts +0 -78
  162. package/src/schema/introspect-db-queries.ts +0 -326
  163. package/src/schema/introspect-db-structure.ts +0 -670
  164. package/src/schema/introspect-db-types.ts +0 -56
  165. package/src/schema/introspect-db.ts +0 -257
  166. package/src/schema/introspect-runtime.test.ts +0 -260
  167. package/src/schema/introspect-runtime.ts +0 -327
  168. package/src/schema/non-sql-collections.test.ts +0 -131
  169. package/src/schema/rls-bootstrap-sql.ts +0 -288
  170. package/src/schema/search-column.ts +0 -643
  171. package/src/schema/test-schema.ts +0 -11
  172. package/src/schema/vector-index.ts +0 -491
  173. package/src/security/anonymous-grants.test.ts +0 -73
  174. package/src/security/policy-drift.test.ts +0 -435
  175. package/src/security/policy-drift.ts +0 -473
  176. package/src/security/rls-enforcement.ts +0 -505
  177. package/src/services/BranchService.ts +0 -326
  178. package/src/services/FetchService.ts +0 -2115
  179. package/src/services/PersistService.ts +0 -557
  180. package/src/services/RelationService.ts +0 -978
  181. package/src/services/RelationWriteService.ts +0 -653
  182. package/src/services/cdc/CdcListener.ts +0 -103
  183. package/src/services/cdc/junction-tables.ts +0 -91
  184. package/src/services/cdc/trigger-cdc.ts +0 -173
  185. package/src/services/channel-bus/ChannelBus.ts +0 -44
  186. package/src/services/channel-bus/PostgresChannelBus.ts +0 -299
  187. package/src/services/channel-bus/index.ts +0 -114
  188. package/src/services/channel-history.ts +0 -424
  189. package/src/services/channel-presence.ts +0 -185
  190. package/src/services/collection-helpers.ts +0 -420
  191. package/src/services/dataService.ts +0 -256
  192. package/src/services/index.ts +0 -14
  193. package/src/services/junction-writes.ts +0 -295
  194. package/src/services/nested-path.ts +0 -145
  195. package/src/services/pg-notify-listener.ts +0 -151
  196. package/src/services/realtimeService.ts +0 -2545
  197. package/src/services/row-pipeline.ts +0 -240
  198. package/src/services/write-denial.ts +0 -55
  199. package/src/types.ts +0 -4
  200. package/src/utils/connection-string.ts +0 -58
  201. package/src/utils/drizzle-conditions.ts +0 -2743
  202. package/src/utils/pg-array-null-patch.ts +0 -42
  203. package/src/utils/pg-error-utils.ts +0 -391
  204. package/src/websocket.ts +0 -855
@@ -1,255 +0,0 @@
1
- import { humanize } from "./introspect-db-naming";
2
-
3
- export interface InferenceResult {
4
- propType?: string; // If the inference changes the base type
5
- extra?: string; // String to append to the property definition
6
- }
7
-
8
- const ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
9
- const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
10
- const CUID_REGEX = /^c[^\s-]{7,}$/i; // Basic CUID check
11
- const COLOR_HEX_REGEX = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
12
-
13
- export function inferPropertyFromData(
14
- columnName: string,
15
- pgDataType: string,
16
- currentPropType: string,
17
- sampleValues: unknown[],
18
- isPk: boolean,
19
- /**
20
- * False when generating for a project without `@rebasepro/cms-types`, where
21
- * `BaseProperty` declares no `admin` field and the block below would not
22
- * compile. The type-level inferences (`propType`, `url`, `storage`) are
23
- * unaffected — only the form-widget hints are dropped.
24
- */
25
- emitAdmin = true
26
- ): InferenceResult {
27
- const result: InferenceResult = {};
28
- const extraLines: string[] = [];
29
- // Collected separately and emitted as one block at the end. Pushed inline,
30
- // two admin-owned options from different branches produced two `admin: {`
31
- // blocks in one property — a duplicate key, which is also a compile error.
32
- const adminOptions: string[] = [];
33
-
34
- // Filter out null/undefined for analysis
35
- const validValues = sampleValues.filter(v => v !== null && v !== undefined && v !== "");
36
-
37
- if (validValues.length === 0) {
38
- return result; // Not enough data
39
- }
40
-
41
- const colNameLower = columnName.toLowerCase();
42
-
43
- // ── Number Analysis ──────────────────────────────────────────────────
44
- if (currentPropType === "number") {
45
- // Boolean stored as int
46
- const allZeroOrOne = validValues.every(v => v === 0 || v === 1 || v === "0" || v === "1");
47
- if (allZeroOrOne) {
48
- result.propType = "boolean";
49
- return result; // Don't do min/max if boolean
50
- }
51
-
52
- // Min / Max constraints
53
- const numValues = validValues.map(v => Number(v)).filter(v => !isNaN(v));
54
- if (numValues.length === validValues.length) {
55
- const min = Math.min(...numValues);
56
- const max = Math.max(...numValues);
57
- // Example heuristic: percentages
58
- if (min >= 0 && max <= 100 && (colNameLower.includes("percent") || colNameLower.includes("rate") || colNameLower.includes("score"))) {
59
- extraLines.push(" validation: {\n min: 0,\n max: 100\n }");
60
- } else if (min >= 0 && (colNameLower.includes("count") || colNameLower.includes("total") || colNameLower.includes("amount"))) {
61
- extraLines.push(" validation: {\n min: 0\n }");
62
- }
63
- }
64
-
65
- // No currency heuristic. `admin.currency` was never a declared option and
66
- // nothing reads it, so a column called `price` got a block of config that did
67
- // nothing — invisible because this generator emits *source text*, which no
68
- // typechecker ever saw. Reinstate it by adding `currency` to
69
- // AdminNumberOptions first, and something that renders it.
70
- }
71
-
72
- // ── JSON / JSONB Analysis ────────────────────────────────────────────
73
- if (currentPropType === "map" || pgDataType.includes("json")) {
74
- // PostGres jsonb can be object or array
75
- let allArrays = true;
76
- let allObjects = true;
77
-
78
- for (const v of validValues) {
79
- let parsed = v;
80
- if (typeof v === "string") {
81
- try { parsed = JSON.parse(v); } catch (e) { allArrays = false; allObjects = false; break; }
82
- }
83
- if (Array.isArray(parsed)) {
84
- allObjects = false;
85
- } else if (typeof parsed === "object" && parsed !== null) {
86
- allArrays = false;
87
- } else {
88
- allArrays = false;
89
- allObjects = false;
90
- }
91
- }
92
-
93
- if (allArrays && !allObjects) {
94
- result.propType = "array";
95
- // Infer inner type
96
- let allNumbers = true;
97
- let allStrings = true;
98
- for (const v of validValues) {
99
- const parsed = typeof v === "string" ? JSON.parse(v) : v;
100
- for (const item of parsed) {
101
- if (typeof item !== "number") allNumbers = false;
102
- if (typeof item !== "string") allStrings = false;
103
- }
104
- }
105
- const innerType = allNumbers ? "number" : allStrings ? "string" : "map";
106
- extraLines.push(` of: { name: "${humanize(columnName)} Item", type: "${innerType}" }`);
107
- } else {
108
- result.propType = "map";
109
-
110
- // Infer inner schema
111
- if (allObjects && validValues.length > 0) {
112
- const schema: Record<string, string> = {};
113
- for (const v of validValues) {
114
- const parsed = typeof v === "string" ? JSON.parse(v) : v;
115
- for (const [k, val] of Object.entries(parsed)) {
116
- if (val === null || val === undefined) continue;
117
- const type = typeof val;
118
- if (type === "string" || type === "number" || type === "boolean") {
119
- if (!schema[k]) schema[k] = type;
120
- else if (schema[k] !== type) schema[k] = "mixed";
121
- } else if (Array.isArray(val)) {
122
- if (!schema[k]) schema[k] = "array";
123
- else if (schema[k] !== "array") schema[k] = "mixed";
124
- } else if (type === "object") {
125
- if (!schema[k]) schema[k] = "map";
126
- else if (schema[k] !== "map") schema[k] = "mixed";
127
- }
128
- }
129
- }
130
-
131
- const keys = Object.keys(schema).filter(k => schema[k] !== "mixed");
132
- if (keys.length > 0) {
133
- const props = keys.map(k => {
134
- return `\n ${k}: { name: "${humanize(k)}", type: "${schema[k]}" }`;
135
- }).join(",");
136
- extraLines.push(` properties: {${props}\n }`);
137
- } else {
138
- extraLines.push(" keyValue: true");
139
- }
140
- } else {
141
- extraLines.push(" keyValue: true");
142
- }
143
- }
144
- }
145
-
146
- // ── String Analysis ──────────────────────────────────────────────────
147
- if (currentPropType === "string") {
148
- // Date/Time Strings
149
- if (validValues.every(v => typeof v === "string" && ISO_8601_REGEX.test(v))) {
150
- result.propType = "date";
151
- return result;
152
- }
153
-
154
- // Implicit Enums
155
- const uniqueValues = new Set(validValues);
156
- // Determine the maximum length among unique values
157
- let maxEnumLength = 0;
158
- for (const v of uniqueValues) {
159
- if (typeof v === "string" && v.length > maxEnumLength) {
160
- maxEnumLength = v.length;
161
- }
162
- }
163
-
164
- // Ensure no empty string, max length makes sense, and fewer unique values than total values (unless small total)
165
- if (uniqueValues.size > 0 && uniqueValues.size <= 5 && maxEnumLength <= 50 && validValues.length > uniqueValues.size && !uniqueValues.has("")) {
166
- const isLikelyId = isPk || colNameLower.endsWith("_id");
167
- if (!isLikelyId) {
168
- const enumEntries = Array.from(uniqueValues).map(v => `{ id: ${JSON.stringify(v)}, label: ${JSON.stringify(humanize(v as string))} }`).join(", ");
169
- extraLines.push(` enum: [${enumEntries}]`);
170
- result.extra = extraLines.length > 0 ? "\n" + extraLines.join(",\n") + "," : "";
171
- return result; // Skip other string checks if it's an enum
172
- }
173
- }
174
-
175
- // UUID / CUID Detection
176
- const allUuid = validValues.every(v => typeof v === "string" && UUID_REGEX.test(v));
177
- const allCuid = validValues.every(v => typeof v === "string" && CUID_REGEX.test(v));
178
- if (allUuid) {
179
- if (isPk) extraLines.push(" isId: \"uuid\"");
180
- } else if (allCuid) {
181
- if (isPk) extraLines.push(" isId: \"cuid\"");
182
- }
183
-
184
- // No colour heuristic. `admin.color` was never a declared option and nothing
185
- // reads it — the same dead branch `currency` was. This generator emits *source
186
- // text*, so no typechecker ever saw either. Reinstate by adding the option and
187
- // something that renders it first.
188
-
189
- // Text Lengths, Multiline & Markdown
190
- let maxLength = 0;
191
- let hasNewlines = false;
192
- let hasMarkdown = false;
193
- for (const v of validValues) {
194
- if (typeof v === "string") {
195
- if (v.length > maxLength) maxLength = v.length;
196
- if (v.includes("\n")) hasNewlines = true;
197
- if (/^#{1,6}\s+.+/m.test(v) || /\*\*.+\*\*/.test(v) || /\[.+\]\(.+\)/.test(v) || /^\s*[-*]\s+.+/m.test(v)) {
198
- hasMarkdown = true;
199
- }
200
- }
201
- }
202
-
203
- // `multiline` and `markdown` are *admin* property options, so they have
204
- // to sit inside the `admin` block. Emitted at the top of the property —
205
- // where they were — `PostgresCollectionConfig` does not declare them and
206
- // the generated file does not compile.
207
- if (hasMarkdown) {
208
- adminOptions.push("multiline: true", "markdown: true");
209
- } else if (hasNewlines || maxLength > 100) {
210
- adminOptions.push("multiline: true");
211
- }
212
-
213
- if (maxLength > 0 && maxLength < 10000) { // arbitrary cap to avoid huge limits
214
- // Pad the max length slightly for the constraint
215
- const paddedMax = Math.ceil((maxLength * 1.5) / 10) * 10;
216
- // Only add length constraint if it seems like a bounded string, not a long text
217
- if (paddedMax < 255) {
218
- extraLines.push(` validation: {\n max: ${paddedMax}\n }`);
219
- }
220
- }
221
-
222
- // Storage & Media (Extracted from old logic)
223
- const isUrl = colNameLower.endsWith("_url") || colNameLower.endsWith("_uri") || colNameLower.endsWith("_link");
224
- const isMedia = colNameLower.includes("image") || colNameLower.includes("avatar") || colNameLower.includes("photo") || colNameLower.includes("logo") || colNameLower.includes("cover");
225
-
226
- const allAbsoluteUrls = validValues.every(v => typeof v === "string" && (v.startsWith("http://") || v.startsWith("https://")));
227
- if (allAbsoluteUrls) {
228
- const isImage = validValues.some(v => typeof v === "string" && v.match(/\.(jpeg|jpg|gif|png|webp|svg)/i));
229
- if (isImage || isMedia) {
230
- extraLines.push(" url: true");
231
- adminOptions.push("urlPreview: \"image\"");
232
- } else {
233
- extraLines.push(" url: true");
234
- }
235
- } else {
236
- const hasFileExtension = validValues.some(v => typeof v === "string" && v.match(/\.[a-zA-Z0-9]+$/));
237
- if (hasFileExtension) {
238
- const firstVal = validValues[0] as string;
239
- const lastSlash = firstVal.lastIndexOf("/");
240
- const inferredStoragePath = lastSlash > 0 ? firstVal.substring(0, lastSlash) : "files";
241
- extraLines.push(` storage: {\n storagePath: "${inferredStoragePath}"\n }`);
242
- } else if (isUrl) {
243
- extraLines.push(" url: true");
244
- if (isMedia) adminOptions.push("urlPreview: \"image\"");
245
- }
246
- }
247
- }
248
-
249
- if (emitAdmin && adminOptions.length > 0) {
250
- extraLines.push(` admin: {\n${adminOptions.map((o) => ` ${o}`).join(",\n")}\n }`);
251
- }
252
-
253
- result.extra = extraLines.length > 0 ? "\n" + extraLines.join(",\n") + "," : "";
254
- return result;
255
- }