prostgles-server 4.2.158 → 4.2.159

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 (145) hide show
  1. package/dist/Auth/AuthTypes.d.ts +4 -8
  2. package/dist/Auth/AuthTypes.d.ts.map +1 -1
  3. package/dist/Auth/setAuthProviders.d.ts.map +1 -1
  4. package/dist/Auth/setAuthProviders.js +4 -5
  5. package/dist/Auth/setAuthProviders.js.map +1 -1
  6. package/dist/Auth/setEmailProvider.js +1 -1
  7. package/dist/Auth/setEmailProvider.js.map +1 -1
  8. package/package.json +1 -1
  9. package/lib/Auth/AuthHandler.ts +0 -436
  10. package/lib/Auth/AuthTypes.ts +0 -285
  11. package/lib/Auth/getSafeReturnURL.ts +0 -35
  12. package/lib/Auth/sendEmail.ts +0 -83
  13. package/lib/Auth/setAuthProviders.ts +0 -129
  14. package/lib/Auth/setEmailProvider.ts +0 -85
  15. package/lib/Auth/setupAuthRoutes.ts +0 -161
  16. package/lib/DBEventsManager.ts +0 -178
  17. package/lib/DBSchemaBuilder.ts +0 -225
  18. package/lib/DboBuilder/DboBuilder.ts +0 -319
  19. package/lib/DboBuilder/DboBuilderTypes.ts +0 -361
  20. package/lib/DboBuilder/QueryBuilder/Functions.ts +0 -1153
  21. package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +0 -288
  22. package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +0 -263
  23. package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +0 -271
  24. package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +0 -136
  25. package/lib/DboBuilder/QueryBuilder/prepareHaving.ts +0 -22
  26. package/lib/DboBuilder/QueryStreamer.ts +0 -250
  27. package/lib/DboBuilder/TableHandler/DataValidator.ts +0 -428
  28. package/lib/DboBuilder/TableHandler/TableHandler.ts +0 -205
  29. package/lib/DboBuilder/TableHandler/delete.ts +0 -115
  30. package/lib/DboBuilder/TableHandler/insert.ts +0 -183
  31. package/lib/DboBuilder/TableHandler/insertTest.ts +0 -78
  32. package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +0 -62
  33. package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +0 -134
  34. package/lib/DboBuilder/TableHandler/update.ts +0 -126
  35. package/lib/DboBuilder/TableHandler/updateBatch.ts +0 -49
  36. package/lib/DboBuilder/TableHandler/updateFile.ts +0 -48
  37. package/lib/DboBuilder/TableHandler/upsert.ts +0 -34
  38. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +0 -393
  39. package/lib/DboBuilder/ViewHandler/count.ts +0 -38
  40. package/lib/DboBuilder/ViewHandler/find.ts +0 -153
  41. package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +0 -73
  42. package/lib/DboBuilder/ViewHandler/getExistsFilters.ts +0 -74
  43. package/lib/DboBuilder/ViewHandler/getInfo.ts +0 -32
  44. package/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts +0 -84
  45. package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +0 -96
  46. package/lib/DboBuilder/ViewHandler/parseFieldFilter.ts +0 -105
  47. package/lib/DboBuilder/ViewHandler/parseJoinPath.ts +0 -208
  48. package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +0 -163
  49. package/lib/DboBuilder/ViewHandler/prepareWhere.ts +0 -90
  50. package/lib/DboBuilder/ViewHandler/size.ts +0 -37
  51. package/lib/DboBuilder/ViewHandler/subscribe.ts +0 -118
  52. package/lib/DboBuilder/ViewHandler/validateViewRules.ts +0 -70
  53. package/lib/DboBuilder/dboBuilderUtils.ts +0 -222
  54. package/lib/DboBuilder/getColumns.ts +0 -114
  55. package/lib/DboBuilder/getCondition.ts +0 -201
  56. package/lib/DboBuilder/getSubscribeRelatedTables.ts +0 -190
  57. package/lib/DboBuilder/getTablesForSchemaPostgresSQL.ts +0 -426
  58. package/lib/DboBuilder/insertNestedRecords.ts +0 -355
  59. package/lib/DboBuilder/parseUpdateRules.ts +0 -187
  60. package/lib/DboBuilder/prepareShortestJoinPaths.ts +0 -186
  61. package/lib/DboBuilder/runSQL.ts +0 -182
  62. package/lib/DboBuilder/runTransaction.ts +0 -50
  63. package/lib/DboBuilder/sqlErrCodeToMsg.ts +0 -254
  64. package/lib/DboBuilder/uploadFile.ts +0 -69
  65. package/lib/Event_Trigger_Tags.ts +0 -118
  66. package/lib/FileManager/FileManager.ts +0 -358
  67. package/lib/FileManager/getValidatedFileType.ts +0 -69
  68. package/lib/FileManager/initFileManager.ts +0 -187
  69. package/lib/FileManager/upload.ts +0 -62
  70. package/lib/FileManager/uploadStream.ts +0 -79
  71. package/lib/Filtering.ts +0 -463
  72. package/lib/JSONBValidation/validate_jsonb_schema_sql.ts +0 -502
  73. package/lib/JSONBValidation/validation.ts +0 -143
  74. package/lib/Logging.ts +0 -127
  75. package/lib/PostgresNotifListenManager.ts +0 -143
  76. package/lib/Prostgles.ts +0 -485
  77. package/lib/ProstglesTypes.ts +0 -196
  78. package/lib/PubSubManager/PubSubManager.ts +0 -609
  79. package/lib/PubSubManager/addSub.ts +0 -138
  80. package/lib/PubSubManager/addSync.ts +0 -141
  81. package/lib/PubSubManager/getCreatePubSubManagerError.ts +0 -72
  82. package/lib/PubSubManager/getPubSubManagerInitQuery.ts +0 -662
  83. package/lib/PubSubManager/initPubSubManager.ts +0 -79
  84. package/lib/PubSubManager/notifListener.ts +0 -173
  85. package/lib/PubSubManager/orphanTriggerCheck.ts +0 -70
  86. package/lib/PubSubManager/pushSubData.ts +0 -55
  87. package/lib/PublishParser/PublishParser.ts +0 -162
  88. package/lib/PublishParser/getFileTableRules.ts +0 -124
  89. package/lib/PublishParser/getSchemaFromPublish.ts +0 -141
  90. package/lib/PublishParser/getTableRulesWithoutFileTable.ts +0 -177
  91. package/lib/PublishParser/publishTypesAndUtils.ts +0 -399
  92. package/lib/RestApi.ts +0 -127
  93. package/lib/SchemaWatch/SchemaWatch.ts +0 -90
  94. package/lib/SchemaWatch/createSchemaWatchEventTrigger.ts +0 -3
  95. package/lib/SchemaWatch/getValidatedWatchSchemaType.ts +0 -45
  96. package/lib/SchemaWatch/getWatchSchemaTagList.ts +0 -27
  97. package/lib/SyncReplication.ts +0 -557
  98. package/lib/TableConfig/TableConfig.ts +0 -468
  99. package/lib/TableConfig/getColumnDefinitionQuery.ts +0 -111
  100. package/lib/TableConfig/getConstraintDefinitionQueries.ts +0 -95
  101. package/lib/TableConfig/getFutureTableSchema.ts +0 -64
  102. package/lib/TableConfig/getPGIndexes.ts +0 -53
  103. package/lib/TableConfig/getTableColumnQueries.ts +0 -129
  104. package/lib/TableConfig/initTableConfig.ts +0 -326
  105. package/lib/index.ts +0 -13
  106. package/lib/initProstgles.ts +0 -319
  107. package/lib/onSocketConnected.ts +0 -102
  108. package/lib/runClientRequest.ts +0 -129
  109. package/lib/shortestPath.ts +0 -122
  110. package/lib/typeTests/DBoGenerated.d.ts +0 -320
  111. package/lib/typeTests/dboTypeCheck.ts +0 -81
  112. package/lib/utils.ts +0 -15
  113. package/tests/client/hooks.spec.ts +0 -205
  114. package/tests/client/index.ts +0 -139
  115. package/tests/client/package-lock.json +0 -637
  116. package/tests/client/package.json +0 -26
  117. package/tests/client/renderReactHook.ts +0 -177
  118. package/tests/client/tsconfig.json +0 -15
  119. package/tests/client/useProstgles.spec.ts +0 -120
  120. package/tests/clientFileTests.spec.ts +0 -102
  121. package/tests/clientOnlyQueries.spec.ts +0 -667
  122. package/tests/clientRestApi.spec.ts +0 -82
  123. package/tests/config_test/DBoGenerated.d.ts +0 -407
  124. package/tests/config_test/index.html +0 -109
  125. package/tests/config_test/index.js +0 -86
  126. package/tests/config_test/index.js.map +0 -1
  127. package/tests/config_test/index.ts +0 -91
  128. package/tests/config_test/init.sql +0 -48
  129. package/tests/config_test/package.json +0 -29
  130. package/tests/config_test/tsconfig.json +0 -23
  131. package/tests/config_testDBoGenerated.d.ts +0 -407
  132. package/tests/isomorphicQueries.spec.ts +0 -1493
  133. package/tests/server/DBoGenerated.d.ts +0 -537
  134. package/tests/server/index.html +0 -73
  135. package/tests/server/index.ts +0 -289
  136. package/tests/server/init.sql +0 -224
  137. package/tests/server/package-lock.json +0 -2164
  138. package/tests/server/package.json +0 -25
  139. package/tests/server/publishTypeCheck.ts +0 -136
  140. package/tests/server/server.ts +0 -35
  141. package/tests/server/testPublish.ts +0 -147
  142. package/tests/server/testTableConfig.ts +0 -156
  143. package/tests/server/tsconfig.json +0 -22
  144. package/tests/serverOnlyQueries.spec.ts +0 -32
  145. package/tests/test.sh +0 -20
@@ -1,468 +0,0 @@
1
- import { asName as _asName, AnyObject, TableInfo, ALLOWED_EXTENSION, ALLOWED_CONTENT_TYPE, isObject, JSONB, ColumnInfo } from "prostgles-types";
2
- import { isPlainObject, JoinInfo, LocalParams } from "../DboBuilder/DboBuilder";
3
- import { DB, DBHandlerServer, Prostgles } from "../Prostgles";
4
- import { InsertRule, ValidateRowArgs } from "../PublishParser/PublishParser";
5
- import { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
6
- import { uploadFile } from "../DboBuilder/uploadFile";
7
- import { initTableConfig } from "./initTableConfig";
8
-
9
- type ColExtraInfo = {
10
- min?: string | number;
11
- max?: string | number;
12
- hint?: string;
13
- };
14
-
15
- export type I18N_Config<LANG_IDS> = {
16
- [lang_id in keyof LANG_IDS]: string;
17
- }
18
-
19
- export const parseI18N = <LANG_IDS, Def extends string | undefined>(params: {
20
- config?: I18N_Config<LANG_IDS> | string;
21
- lang?: keyof LANG_IDS | string;
22
- defaultLang: keyof LANG_IDS | string;
23
- defaultValue: Def;
24
- }): Def | string => {
25
- const { config, lang, defaultLang, defaultValue } = params;
26
- if(config){
27
- if(isPlainObject(config)){
28
- //@ts-ignore
29
- return config[lang] ?? config[defaultLang];
30
- } else if(typeof config === "string"){
31
- return config;
32
- }
33
- }
34
-
35
- return defaultValue;
36
- }
37
-
38
- type BaseTableDefinition<LANG_IDS = AnyObject> = {
39
- info?: {
40
- label?: string | I18N_Config<LANG_IDS>;
41
- }
42
- dropIfExistsCascade?: boolean;
43
- dropIfExists?: boolean;
44
- hooks?: {
45
- /**
46
- * Hook used to run custom logic before inserting a row.
47
- * The returned row must satisfy the table schema
48
- */
49
- getPreInsertRow?: (args: GetPreInsertRowArgs) => Promise<{ row: AnyObject; onInserted: Promise<void>; }>;
50
- };
51
- triggers?: {
52
- [triggerName: string]: {
53
- /**
54
- * Use "before" when you need to change the data before the action
55
- */
56
- type: "before" | "after" | "instead of";
57
- actions: ("insert" | "update" | "delete")[];
58
- forEach: "statement" | "row";
59
- /**
60
- * @example
61
- * DECLARE
62
- x_rec record;
63
- BEGIN
64
- raise notice '=operation: % =', TG_OP;
65
- IF (TG_OP = 'UPDATE' OR TG_OP = 'DELETE') THEN
66
- FOR x_rec IN SELECT * FROM old_table LOOP
67
- raise notice 'OLD: %', x_rec;
68
- END loop;
69
- END IF;
70
- IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
71
- FOR x_rec IN SELECT * FROM new_table LOOP
72
- raise notice 'NEW: %', x_rec;
73
- END loop;
74
- END IF;
75
-
76
- RETURN NULL;
77
- END;
78
- */
79
- query: string;
80
- }
81
- };
82
- }
83
-
84
- type LookupTableDefinition<LANG_IDS> = {
85
- isLookupTable: {
86
- values: {
87
- [id_value: string]: {} | {
88
- [lang_id in keyof LANG_IDS]: string
89
- }
90
- }
91
- }
92
- }
93
-
94
- export type BaseColumn<LANG_IDS> = {
95
- /**
96
- * Will add these values to .getColumns() result
97
- */
98
- info?: ColExtraInfo;
99
-
100
- label?: string | Partial<{ [lang_id in keyof LANG_IDS]: string; }>;
101
- }
102
-
103
- type SQLDefColumn = {
104
-
105
- /**
106
- * Raw sql statement used in creating/adding column
107
- */
108
- sqlDefinition?: string;
109
- }
110
-
111
- export type BaseColumnTypes = {
112
- defaultValue?: any;
113
- nullable?: boolean;
114
- }
115
-
116
- type TextColumn = BaseColumnTypes & {
117
- isText: true;
118
- /**
119
- * Value will be trimmed before update/insert
120
- */
121
- trimmed?: boolean;
122
-
123
- /**
124
- * Value will be lower cased before update/insert
125
- */
126
- lowerCased?: boolean;
127
- }
128
-
129
- export type JSONBColumnDef = (BaseColumnTypes & {
130
- /**
131
- * If the new schema CHECK fails old rows the update old rows using this function
132
- */
133
- // onMigrationFail?: <T>(failedRow: T) => AnyObject | Promise<AnyObject>;
134
- }) & ({
135
- jsonbSchema: JSONB.JSONBSchema;
136
- jsonbSchemaType?: undefined;
137
- } | {
138
- jsonbSchema?: undefined;
139
- jsonbSchemaType: JSONB.ObjectType["type"];
140
- })
141
-
142
- /**
143
- * Allows referencing media to this table.
144
- * Requires this table to have a primary key AND a valid fileTable config
145
- */
146
- type MediaColumn = ({
147
-
148
- name: string;
149
- label?: string;
150
- files: "one" | "many";
151
- } & (
152
- {
153
-
154
- /**
155
- * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept
156
- */
157
- allowedContentType?: Record<Partial<("audio/*" | "video/*" | "image/*" | "text/*" | ALLOWED_CONTENT_TYPE)>, 1>
158
- } |
159
- {
160
- allowedExtensions?: Record<Partial<ALLOWED_EXTENSION>, 1>
161
- }
162
- ));
163
-
164
- type ReferencedColumn = {
165
- /**
166
- * Will create a lookup table that this column will reference
167
- */
168
- references?: BaseColumnTypes & {
169
- tableName: string;
170
- /**
171
- * Defaults to id
172
- */
173
- columnName?: string;
174
- }
175
- }
176
-
177
- type JoinDef = {
178
- sourceTable: string;
179
- targetTable: string;
180
- on: JoinInfo["paths"][number]["on"];
181
- }
182
-
183
- /**
184
- * Used in specifying a join path to a table. This column name can then be used in select
185
- */
186
- type NamedJoinColumn = {
187
- label?: string;
188
- joinDef: JoinDef[];
189
- }
190
-
191
- type Enum<T extends string | number = any> = {
192
- enum: T[] | readonly T[];
193
- nullable?: boolean;
194
- defaultValue?: T;
195
- };
196
-
197
- export type ColumnConfig<LANG_IDS = { en: 1 }> = string | StrictUnion<NamedJoinColumn | MediaColumn | (BaseColumn<LANG_IDS> & (SQLDefColumn | ReferencedColumn | TextColumn | JSONBColumnDef | Enum))>;
198
-
199
- export type ColumnConfigs<LANG_IDS = { en: 1 }> = {
200
- sql: string | BaseColumn<LANG_IDS> & SQLDefColumn;
201
- join: BaseColumn<LANG_IDS> & NamedJoinColumn;
202
- media: BaseColumn<LANG_IDS> & MediaColumn;
203
- referenced: BaseColumn<LANG_IDS> & ReferencedColumn;
204
- text: BaseColumn<LANG_IDS> & TextColumn;
205
- jsonb: BaseColumn<LANG_IDS> & JSONBColumnDef;
206
- enum: BaseColumn<LANG_IDS> & Enum;
207
- }
208
-
209
- type UnionKeys<T> = T extends T ? keyof T : never;
210
- type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
211
- export type StrictUnion<T> = StrictUnionHelper<T, T>
212
-
213
- export const CONSTRAINT_TYPES = ["PRIMARY KEY", "UNIQUE", "CHECK"] as const;
214
- export type TableDefinition<LANG_IDS> = {
215
- onMount?: (params: { dbo: DBHandlerServer; _db: DB }) => Promise<void | { onUnmount: () => void; }>;
216
- columns?: {
217
- [column_name: string]: ColumnConfig<LANG_IDS>
218
- },
219
- constraints?:
220
- | string[]
221
- | {
222
- [constraint_name: string]:
223
- | string
224
- | {
225
- type: typeof CONSTRAINT_TYPES[number];
226
- dropIfExists?: boolean;
227
- /**
228
- * E.g.:
229
- * colname
230
- * col1, col2
231
- * col1 > col3
232
- */
233
- content: string;
234
- }
235
- // & ({
236
- // }
237
- // | {
238
- // type: "FOREIGN KEY",
239
- // columns: string[];
240
- // ftable: string;
241
- // fcols: string[];
242
- // }
243
- // )
244
- },
245
-
246
- /**
247
- * Similar to unique constraints but expressions are allowed inside definition
248
- */
249
- replaceUniqueIndexes?: boolean;
250
- indexes?: {
251
- [index_name: string]: {
252
-
253
- /**
254
- * If true then will drop any existing index with this name
255
- * Overrides replaceUniqueIndexes
256
- */
257
- replace?: boolean;
258
-
259
- /**
260
- * Causes the system to check for duplicate values in the table when the index is created (if data already exist) and each time data is added.
261
- * Attempts to insert or update data which would result in duplicate entries will generate an error.
262
- */
263
- unique?: boolean;
264
-
265
- /**
266
- * When this option is used, PostgreSQL will build the index without taking any locks that prevent
267
- * concurrent inserts, updates, or deletes on the table; whereas a standard index build locks out writes (but not reads) on the table until it's done.
268
- * There are several caveats to be aware of when using this option — see Building Indexes Concurrently.
269
- */
270
- concurrently?: boolean;
271
-
272
- /**
273
- * Table name
274
- */
275
- // on?: string;
276
-
277
- /**
278
- * Column list
279
- * @example: col1, col2
280
- */
281
- columns: string;
282
-
283
- /**
284
- * Where clause without the "where"
285
- * Used to create a partial index. A partial index is an index that contains entries for only a portion of a table
286
- * Another possible application is to use WHERE with UNIQUE to enforce uniqueness over a subset of a table
287
- */
288
- where?: string;
289
-
290
- /**
291
- * The name of the index method to be used.
292
- * Choices are btree, hash, gist, and gin. The default method is btree.
293
- */
294
- using?: "btree" | "hash" | "gist" | "gin";
295
- }
296
- }
297
- }
298
-
299
- type GetPreInsertRowArgs = Omit<ValidateRowArgs, "localParams"> & {
300
- // preValidate: InsertRule["preValidate"];
301
- validate: InsertRule["validate"];
302
- localParams: LocalParams | undefined;
303
- }
304
-
305
- /**
306
- * Helper utility to create lookup tables for TEXT columns
307
- */
308
- export type TableConfig<LANG_IDS = { en: 1 }> = {
309
- [table_name: string]: BaseTableDefinition<LANG_IDS> & (TableDefinition<LANG_IDS> | LookupTableDefinition<LANG_IDS>);
310
- }
311
-
312
- /**
313
- * Will be run between initSQL and fileTable
314
- */
315
- export default class TableConfigurator<LANG_IDS = { en: 1 }> {
316
-
317
- instanceId = Date.now() + Math.random();
318
-
319
- config: TableConfig<LANG_IDS> = {};
320
- get dbo(): DBHandlerServer {
321
- if (!this.prostgles.dbo) throw "this.prostgles.dbo missing"
322
- return this.prostgles.dbo
323
- }
324
- get db(): DB {
325
- if (!this.prostgles.db) throw "this.prostgles.db missing"
326
- return this.prostgles.db
327
- }
328
- prostgles: Prostgles
329
-
330
- constructor(prostgles: Prostgles) {
331
- this.config = (prostgles.opts.tableConfig as any) ?? {};
332
- this.prostgles = prostgles;
333
- }
334
-
335
- destroy = async () => {
336
- for await(const { onUnmount } of Object.values(this.tableOnMounts)){
337
- try {
338
- await onUnmount();
339
- } catch (error) {
340
- console.error(error);
341
- }
342
- }
343
- }
344
-
345
- tableOnMounts: Record<string, { onUnmount: () => void; }> = {};
346
- setTableOnMounts = async () => {
347
- this.tableOnMounts = {};
348
- for (const [tableName, tableConfig] of Object.entries(this.config)) {
349
- if("onMount" in tableConfig && tableConfig.onMount){
350
- const cleanup = await tableConfig.onMount({ dbo: this.dbo, _db: this.db });
351
- if(cleanup){
352
- this.tableOnMounts[tableName] = cleanup;
353
- }
354
- }
355
- }
356
- }
357
-
358
- getColumnConfig = (tableName: string, colName: string): ColumnConfig | undefined => {
359
- const tconf = this.config?.[tableName];
360
- if (tconf && "columns" in tconf) {
361
- return tconf.columns?.[colName];
362
- }
363
- return undefined;
364
- }
365
-
366
- getTableInfo = (params: { tableName: string; lang?: string }): TableInfo["info"] | undefined => {
367
- const tconf = this.config?.[params.tableName];
368
-
369
- return {
370
- label: parseI18N<LANG_IDS, string>({ config: tconf?.info?.label, lang: params.lang, defaultLang: "en", defaultValue: params.tableName })
371
- }
372
- }
373
-
374
- getColInfo = (params: { col: string, table: string, lang?: string }): (ColExtraInfo & { label?: string; } & Pick<ColumnInfo, "jsonbSchema">) | undefined => {
375
- const colConf = this.getColumnConfig(params.table, params.col);
376
- let result: Partial<ReturnType<typeof this.getColInfo>> = undefined;
377
- if (colConf) {
378
-
379
- if (isObject(colConf)) {
380
- const { jsonbSchema, jsonbSchemaType, info } = colConf;
381
- result = {
382
- ...(result ?? {}),
383
- ...info,
384
- ...((jsonbSchema || jsonbSchemaType) && { jsonbSchema: { nullable: colConf.nullable, ...(jsonbSchema || { type: jsonbSchemaType }) } })
385
- }
386
-
387
- /**
388
- * Get labels from TableConfig if specified
389
- */
390
- if (colConf.label) {
391
- const { lang } = params;
392
- const lbl = colConf?.label;
393
- if (["string", "object"].includes(typeof lbl)) {
394
- if (typeof lbl === "string") {
395
- result ??= {};
396
- result.label = lbl
397
- } else if (lang && (lbl?.[lang as "en"] || lbl?.en)) {
398
- result ??= {};
399
- result.label = (lbl?.[lang as "en"]) || lbl?.en;
400
- }
401
- }
402
-
403
- }
404
-
405
- }
406
-
407
- }
408
-
409
-
410
- return result;
411
- }
412
-
413
- checkColVal = (params: { col: string, table: string, value: any }): void => {
414
- const conf = this.getColInfo(params);
415
- if (conf) {
416
- const { value } = params;
417
- const { min, max } = conf;
418
- if (min !== undefined && value !== undefined && value < min) throw `${params.col} must be greater than ${min}`
419
- if (max !== undefined && value !== undefined && value > max) throw `${params.col} must be less than ${max}`
420
- }
421
- }
422
-
423
- getJoinInfo = (sourceTable: string, targetTable: string): JoinInfo | undefined => {
424
- if (
425
- this.config &&
426
- sourceTable in this.config &&
427
- this.config[sourceTable] &&
428
- "columns" in this.config[sourceTable]!
429
- ) {
430
- const td = this.config[sourceTable]!;
431
- if ("columns" in td && td.columns?.[targetTable]) {
432
- const cd = td.columns[targetTable];
433
- if (isObject(cd) && "joinDef" in cd) {
434
- if(!cd.joinDef) throw "cd.joinDef missing"
435
- const { joinDef } = cd;
436
- const res: JoinInfo = {
437
- expectOne: false,
438
- paths: joinDef.map(({ sourceTable, targetTable: table, on }) => ({
439
- source: sourceTable,
440
- target: targetTable,
441
- table,
442
- on
443
- })),
444
- }
445
-
446
- return res;
447
- }
448
- }
449
- }
450
- return undefined;
451
- }
452
-
453
- getPreInsertRow = async (tableHandler: TableHandler, args: Pick<GetPreInsertRowArgs, "localParams" | "row" | "validate" | "dbx">): Promise<AnyObject> => {
454
- const tableHook = this.config?.[tableHandler.name]?.hooks?.getPreInsertRow;
455
- if(tableHandler.is_media){
456
- return uploadFile.bind(tableHandler)(args) as Promise<AnyObject>;
457
- }
458
- if(tableHook){
459
- return tableHook(args)
460
- }
461
-
462
- return args.row;
463
- }
464
-
465
- prevInitQueryHistory?: string[];
466
- initialising = false;
467
- init = initTableConfig.bind(this);
468
- }
@@ -1,111 +0,0 @@
1
- import { asName, pickKeys } from "prostgles-types";
2
- import { DB } from "../Prostgles";
3
- import { asValue } from "../PubSubManager/PubSubManager";
4
- import { VALIDATE_SCHEMA_FUNCNAME } from "../JSONBValidation/validate_jsonb_schema_sql";
5
- import { BaseColumnTypes, ColumnConfig } from "./TableConfig";
6
- import pgPromise from "pg-promise";
7
-
8
- type Args = {
9
- column: string;
10
- colConf: ColumnConfig;
11
- db: DB;
12
- table: string;
13
- };
14
-
15
- /**
16
- * Column create statement for a given config
17
- */
18
- export const getColumnDefinitionQuery = async ({ colConf: colConfRaw, column, db, table }: Args): Promise<string | undefined> => {
19
- const colConf = typeof colConfRaw === "string"? { sqlDefinition: colConfRaw } : colConfRaw;
20
- const colNameEsc = asName(column);
21
- const getColTypeDef = (colConf: BaseColumnTypes, pgType: "TEXT" | "JSONB") => {
22
- const { nullable, defaultValue } = colConf;
23
- return `${pgType} ${!nullable ? " NOT NULL " : ""} ${defaultValue ? ` DEFAULT ${asValue(defaultValue)} ` : ""}`
24
- }
25
-
26
- const jsonbSchema =
27
- ("jsonbSchema" in colConf && colConf.jsonbSchema) ? { jsonbSchema: colConf.jsonbSchema, jsonbSchemaType: undefined } :
28
- ("jsonbSchemaType" in colConf && colConf.jsonbSchemaType) ? { jsonbSchema: undefined, jsonbSchemaType: colConf.jsonbSchemaType } :
29
- undefined;
30
-
31
-
32
- if ("references" in colConf && colConf.references) {
33
-
34
- const { tableName: lookupTable, columnName: lookupCol = "id" } = colConf.references;
35
- return ` ${colNameEsc} ${getColTypeDef(colConf.references, "TEXT")} REFERENCES ${lookupTable} (${lookupCol}) `;
36
-
37
- } else if ("sqlDefinition" in colConf && colConf.sqlDefinition) {
38
-
39
- return ` ${colNameEsc} ${colConf.sqlDefinition} `;
40
-
41
- } else if ("isText" in colConf && colConf.isText) {
42
- let checks = "";
43
- const colChecks: string[] = [];
44
- if (colConf.lowerCased) {
45
- colChecks.push(`${colNameEsc} = LOWER(${colNameEsc})`)
46
- }
47
- if (colConf.trimmed) {
48
- colChecks.push(`${colNameEsc} = BTRIM(${colNameEsc})`)
49
- }
50
- if (colChecks.length) {
51
- checks = `CHECK (${colChecks.join(" AND ")})`
52
- }
53
- return ` ${colNameEsc} ${getColTypeDef(colConf, "TEXT")} ${checks}`;
54
-
55
- } else if (jsonbSchema) {
56
-
57
- const jsonbSchemaStr = asValue({
58
- ...pickKeys(colConf, ["enum", "nullable", "info"]),
59
- ...(jsonbSchema.jsonbSchemaType ? { type: jsonbSchema.jsonbSchemaType } : jsonbSchema.jsonbSchema)
60
- }) + "::TEXT";
61
-
62
- /** Validate default value against jsonbSchema */
63
- const validationQuery = `SELECT ${VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${asValue(colConf.defaultValue) + "::JSONB"}, ${asValue({ table, column })}) as v`;
64
- if (colConf.defaultValue) {
65
-
66
- const failedDefault = (err?: any) => {
67
- return { msg: `Default value (${colConf.defaultValue}) for ${table}.${column} does not satisfy the jsonb constraint check: ${validationQuery}`, err };
68
- }
69
- try {
70
- const row = await db.oneOrNone(validationQuery);
71
- if (!row?.v) {
72
- throw "Error";
73
- }
74
- } catch (e) {
75
- throw failedDefault(e);
76
- }
77
- }
78
-
79
- return ` ${colNameEsc} ${getColTypeDef(colConf, "JSONB")} CHECK(${VALIDATE_SCHEMA_FUNCNAME}(${jsonbSchemaStr}, ${colNameEsc}, ${asValue({ table, column })} ))`;
80
-
81
- } else if ("enum" in colConf) {
82
- if (!colConf.enum?.length) throw new Error("colConf.enum Must not be empty");
83
- const type = colConf.enum.every(v => Number.isFinite(v)) ? "NUMERIC" : "TEXT";
84
- const checks = colConf.enum.map(v => `${colNameEsc} = ${asValue(v)}`).join(" OR ");
85
- return ` ${colNameEsc} ${type} ${colConf.nullable ? "" : "NOT NULL"} ${"defaultValue" in colConf ? ` DEFAULT ${asValue(colConf.defaultValue)}` : ""} CHECK(${checks})`;
86
-
87
- } else {
88
- return undefined;
89
- // throw "Unknown column config: " + JSON.stringify(colConf);
90
- }
91
- }
92
-
93
-
94
- export type ColumnMinimalInfo = {
95
- table_name: string;
96
- table_schema: string;
97
- column_name: string;
98
- column_default: string | null;
99
- udt_name: string;
100
- nullable: boolean;
101
- };
102
- export const getTableColumns = ({ db, table }: { db: DB | pgPromise.ITask<{}>; table: string;}): Promise<ColumnMinimalInfo[]> => {
103
- return db.manyOrNone(`
104
- SELECT table_name,
105
- table_schema, column_name,
106
- column_default, udt_name,
107
- is_nullable = 'YES' as nullable
108
- FROM information_schema.columns
109
- WHERE table_name = $1
110
- `, [table]);
111
- }
@@ -1,95 +0,0 @@
1
- import pgPromise from "pg-promise";
2
- import { asName } from "prostgles-types";
3
- import { DB } from "../Prostgles";
4
- import { asValue } from "../PubSubManager/PubSubManager";
5
- import { TableConfig } from "./TableConfig";
6
-
7
- type Args = {
8
- tableName: string;
9
- tableConf: TableConfig[string]
10
- // tableConf: BaseTableDefinition<LANG_IDS> & (TableDefinition<LANG_IDS> | LookupTableDefinition<LANG_IDS>)
11
- };
12
-
13
- export type ConstraintDef = {
14
- /**
15
- * Named constraints are used to show a relevant error message
16
- */
17
- name?: string;
18
- content: string;
19
- alterQuery: string;
20
- };
21
- export const getConstraintDefinitionQueries = ({ tableConf, tableName }: Args): ConstraintDef[] | undefined => {
22
-
23
- if ("constraints" in tableConf && tableConf.constraints) {
24
- const { constraints } = tableConf;
25
- if(!constraints){
26
- return undefined;
27
- }
28
-
29
- if(Array.isArray(constraints)) {
30
- return constraints.map(c => ({ content: c, alterQuery: `ALTER TABLE ${asName(tableName)} ADD ${c}`}));
31
-
32
- } else {
33
- const constraintNames = Object.keys(constraints);
34
- return constraintNames.map(constraintName => {
35
- const _cnstr = constraints[constraintName]!;
36
- const constraintDef = typeof _cnstr === "string"? _cnstr : `${_cnstr.type} (${_cnstr.content})`;
37
-
38
- /** Drop constraints with the same name */
39
- // const existingConstraint = constraints.some(c => c.conname === constraintName);
40
- // if(existingConstraint){
41
- // if(canDrop) queries.push(`ALTER TABLE ${asName(tableName)} DROP CONSTRAINT ${asName(constraintName)};`);
42
- // }
43
-
44
- const alterQuery = `ALTER TABLE ${asName(tableName)} ADD CONSTRAINT ${asName(constraintName)} ${constraintDef};`;
45
-
46
- return { name: constraintName, alterQuery, content: constraintDef };
47
- });
48
- }
49
- }
50
- }
51
-
52
- export type ColConstraint = {
53
- name: string;
54
- table: string;
55
- type: "c" | "p" | "u" | "f";
56
- cols: Array<string>;
57
- definition: string;
58
- schema: string;
59
- }
60
- type ColConstraintsArgs = {
61
- db: DB | pgPromise.ITask<{}>;
62
- table?: string;
63
- column?: string;
64
- types?: ColConstraint["type"][];
65
- }
66
- export const getColConstraintsQuery = ({ column, table, types }: Omit<ColConstraintsArgs, "db">) => {
67
- let query = `
68
- SELECT *
69
- FROM (
70
- SELECT distinct c.conname as name, c.contype as type,
71
- pg_get_constraintdef(c.oid) as definition,
72
- nsp.nspname as schema,
73
- (SELECT r.relname from pg_class r where r.oid = c.conrelid) as "table",
74
- (SELECT array_agg(attname::text) from pg_attribute
75
- where attrelid = c.conrelid and ARRAY[attnum] <@ c.conkey) as cols
76
- -- (SELECT array_agg(attname::text) from pg_attribute
77
- -- where attrelid = c.confrelid and ARRAY[attnum] <@ c.confkey) as fcols,
78
- -- (SELECT r.relname from pg_class r where r.oid = c.confrelid) as ftable
79
- FROM pg_catalog.pg_constraint c
80
- INNER JOIN pg_catalog.pg_class rel
81
- ON rel.oid = c.conrelid
82
- INNER JOIN pg_catalog.pg_namespace nsp
83
- ON nsp.oid = connamespace
84
- ) t
85
- WHERE TRUE
86
- `;
87
- if (table) query += `\nAND "table" = ${asValue(table)}`;
88
- if (column) query += `\nAND cols @> ARRAY[${asValue(column)}]`;
89
- if (types?.length) query += `\nAND type IN (${types.map(v => asValue(v)).join(", ")})`;
90
- return query;
91
- }
92
- export const getColConstraints = ({ db, column, table, types }: ColConstraintsArgs ): Promise<ColConstraint[]> => {
93
-
94
- return db.manyOrNone(getColConstraintsQuery({ column, table, types }));
95
- }