prostgles-server 4.2.642 → 4.2.644

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 (173) hide show
  1. package/debug/caught-request-fix-build.log +4 -0
  2. package/debug/caught-request-fix-test-build.log +0 -0
  3. package/debug/caught-request-subscription-failure.log +603 -0
  4. package/debug/caught-validation-build.log +4 -0
  5. package/debug/caught-validation-fix-build.log +4 -0
  6. package/debug/caught-validation-fix-test-build.log +0 -0
  7. package/debug/caught-validation-test-build.log +0 -0
  8. package/debug/client-db-tx-build.log +4 -0
  9. package/debug/client-db-tx-test-server.log +3248 -0
  10. package/debug/client-db-tx-tests-build.log +0 -0
  11. package/debug/client-handler-shape-build.log +4 -0
  12. package/debug/client-handler-shape-test-server.log +544 -0
  13. package/debug/client-handler-shape-tests-build.log +0 -0
  14. package/debug/column-definitions-test-server.log +152 -164
  15. package/debug/fixes-review-build.log +4 -0
  16. package/debug/fixes-review-client-schema.backup +745 -0
  17. package/debug/fixes-review-generated-schema.backup +489 -0
  18. package/debug/fixes-review-probes-build.log +0 -0
  19. package/debug/fixes-review-probes.patch +43 -0
  20. package/debug/fixes-review-restore-build.log +0 -0
  21. package/debug/fixes-review-tests-build.log +0 -0
  22. package/debug/fixes-review-typecheck.log +8 -0
  23. package/debug/function-client-db-tx-build.log +4 -0
  24. package/debug/function-client-db-tx-tests-build.log +0 -0
  25. package/debug/review-current-fixes-build.log +4 -0
  26. package/debug/review-current-fixes-client.backup +745 -0
  27. package/debug/review-current-fixes-probes-build.log +0 -0
  28. package/debug/review-current-fixes-probes.patch +55 -0
  29. package/debug/review-current-fixes-restore-build.log +0 -0
  30. package/debug/review-current-fixes-rls.backup +478 -0
  31. package/debug/review-current-fixes-schema.backup +489 -0
  32. package/debug/review-current-fixes-test-build.log +0 -0
  33. package/debug/review-current-fixes-typecheck.log +8 -0
  34. package/debug/review-user-identity-build.log +4 -0
  35. package/debug/review-user-identity-probes-build.log +0 -0
  36. package/debug/review-user-identity-probes.log +558 -0
  37. package/debug/review-user-identity-probes.patch +45 -0
  38. package/debug/review-user-identity-restore-build.log +0 -0
  39. package/debug/review-user-identity-rls.backup +463 -0
  40. package/debug/review-user-identity-schema.backup +720 -0
  41. package/debug/review-user-identity-server.log +3248 -0
  42. package/debug/review-user-identity-test-build.log +0 -0
  43. package/debug/review-user-identity-typecheck.log +8 -0
  44. package/debug/schema-types-focused-strict-check.log +0 -0
  45. package/debug/schema-types-strict-check.log +38 -0
  46. package/debug/schema-types-tests-build.log +0 -0
  47. package/debug/security-review-baseline-tests.log +3250 -0
  48. package/debug/security-review-build.log +4 -0
  49. package/debug/security-review-checkfilter-repro.log +545 -0
  50. package/debug/security-review-clientSchemaTypes.spec.ts.backup +553 -0
  51. package/debug/security-review-repro-build.log +0 -0
  52. package/debug/security-review-repro.spec.ts +591 -0
  53. package/debug/security-review-restore-build.log +0 -0
  54. package/debug/security-review-server-tests.log +3254 -0
  55. package/debug/security-review-test-build.log +0 -0
  56. package/debug/server-user-lint.log +4 -0
  57. package/debug/server-user-test-server.log +538 -0
  58. package/debug/server-user-typecheck.log +8 -0
  59. package/debug/test-check-eslint.log +6 -0
  60. package/debug/test-check-lint-baseline.json +1 -0
  61. package/debug/test-check-npm-test.log +789 -0
  62. package/debug/test-check-types.log +8 -0
  63. package/debug/test-config-npm-test.log +223 -0
  64. package/debug/test-config-strict-null-check.log +50 -0
  65. package/debug/test-config-typecheck.log +8 -0
  66. package/debug/tryRunP-test-quick.log +78 -0
  67. package/debug/tryRunP-typecheck.log +42 -0
  68. package/debug/user-identity-direct-call-build.log +0 -0
  69. package/debug/user-identity-direct-call-schema.backup +489 -0
  70. package/debug/user-identity-regressions-build.log +4 -0
  71. package/debug/user-identity-regressions-generated-schema.backup +489 -0
  72. package/debug/user-identity-regressions-test-build.log +0 -0
  73. package/dist/Auth/AuthHandler.js +1 -1
  74. package/dist/Auth/AuthHandler.js.map +1 -1
  75. package/dist/Auth/AuthTypes.d.ts +11 -9
  76. package/dist/Auth/AuthTypes.d.ts.map +1 -1
  77. package/dist/Auth/AuthTypes.js.map +1 -1
  78. package/dist/Auth/utils/getClientRequestIPsInfo.d.ts +2 -1
  79. package/dist/Auth/utils/getClientRequestIPsInfo.d.ts.map +1 -1
  80. package/dist/Auth/utils/getClientRequestIPsInfo.js +8 -1
  81. package/dist/Auth/utils/getClientRequestIPsInfo.js.map +1 -1
  82. package/dist/Auth/utils/getSessionUser.d.ts +4 -3
  83. package/dist/Auth/utils/getSessionUser.d.ts.map +1 -1
  84. package/dist/Auth/utils/getSessionUser.js +4 -2
  85. package/dist/Auth/utils/getSessionUser.js.map +1 -1
  86. package/dist/Auth/utils/getSessionUser.spec.js +2 -4
  87. package/dist/Auth/utils/getSessionUser.spec.js.map +1 -1
  88. package/dist/Auth/utils/handleGetUser.d.ts.map +1 -1
  89. package/dist/Auth/utils/handleGetUser.js +16 -0
  90. package/dist/Auth/utils/handleGetUser.js.map +1 -1
  91. package/dist/Auth/utils/serverSideRequest.d.ts +17 -0
  92. package/dist/Auth/utils/serverSideRequest.d.ts.map +1 -0
  93. package/dist/Auth/utils/serverSideRequest.js +20 -0
  94. package/dist/Auth/utils/serverSideRequest.js.map +1 -0
  95. package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
  96. package/dist/DboBuilder/DboBuilder.js +4 -2
  97. package/dist/DboBuilder/DboBuilder.js.map +1 -1
  98. package/dist/DboBuilder/TableHandler/TableHandler.d.ts +1 -1
  99. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +0 -4
  100. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  101. package/dist/DboBuilder/ViewHandler/ViewHandler.js +5 -8
  102. package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
  103. package/dist/DboBuilder/ViewHandler/count.d.ts.map +1 -1
  104. package/dist/DboBuilder/ViewHandler/count.js +2 -1
  105. package/dist/DboBuilder/ViewHandler/count.js.map +1 -1
  106. package/dist/DboBuilder/ViewHandler/find.d.ts.map +1 -1
  107. package/dist/DboBuilder/ViewHandler/find.js +2 -1
  108. package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
  109. package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.d.ts +9 -2
  110. package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.d.ts.map +1 -1
  111. package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.js +57 -23
  112. package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.js.map +1 -1
  113. package/dist/DboBuilder/ViewHandler/size.d.ts.map +1 -1
  114. package/dist/DboBuilder/ViewHandler/size.js +2 -1
  115. package/dist/DboBuilder/ViewHandler/size.js.map +1 -1
  116. package/dist/DboBuilder/dboBuilderUtils.d.ts +1 -0
  117. package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
  118. package/dist/DboBuilder/dboBuilderUtils.js +2 -1
  119. package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
  120. package/dist/PublishParser/PublishParser.d.ts.map +1 -1
  121. package/dist/PublishParser/PublishParser.js +2 -1
  122. package/dist/PublishParser/PublishParser.js.map +1 -1
  123. package/dist/PublishParser/defineServerFunction.d.ts +2 -0
  124. package/dist/PublishParser/defineServerFunction.d.ts.map +1 -1
  125. package/dist/PublishParser/defineServerFunction.js.map +1 -1
  126. package/dist/PublishParser/getPublishedTableNames.d.ts.map +1 -1
  127. package/dist/PublishParser/getPublishedTableNames.js +2 -1
  128. package/dist/PublishParser/getPublishedTableNames.js.map +1 -1
  129. package/dist/PublishParser/publishTypesAndUtils.d.ts +1 -1
  130. package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
  131. package/dist/StorageClient/StorageClientTypes.d.ts +5 -4
  132. package/dist/StorageClient/StorageClientTypes.d.ts.map +1 -1
  133. package/dist/WebsocketAPI/getClientHandlers.d.ts +5 -0
  134. package/dist/WebsocketAPI/getClientHandlers.d.ts.map +1 -1
  135. package/dist/WebsocketAPI/getClientHandlers.js +33 -14
  136. package/dist/WebsocketAPI/getClientHandlers.js.map +1 -1
  137. package/dist/index.d.ts +1 -0
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +3 -1
  140. package/dist/index.js.map +1 -1
  141. package/dist/initProstgles.d.ts +12 -2
  142. package/dist/initProstgles.d.ts.map +1 -1
  143. package/dist/initProstgles.js +10 -1
  144. package/dist/initProstgles.js.map +1 -1
  145. package/dist/runClientRequest.d.ts +2 -1
  146. package/dist/runClientRequest.d.ts.map +1 -1
  147. package/dist/runClientRequest.js +7 -4
  148. package/dist/runClientRequest.js.map +1 -1
  149. package/eslint.config.mjs +21 -1
  150. package/lib/Auth/AuthHandler.ts +1 -1
  151. package/lib/Auth/AuthTypes.ts +12 -8
  152. package/lib/Auth/utils/getClientRequestIPsInfo.ts +11 -2
  153. package/lib/Auth/utils/getSessionUser.spec.ts +4 -6
  154. package/lib/Auth/utils/getSessionUser.ts +8 -5
  155. package/lib/Auth/utils/handleGetUser.ts +13 -0
  156. package/lib/Auth/utils/serverSideRequest.ts +27 -0
  157. package/lib/DboBuilder/DboBuilder.ts +7 -2
  158. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +11 -11
  159. package/lib/DboBuilder/ViewHandler/count.ts +2 -1
  160. package/lib/DboBuilder/ViewHandler/find.ts +2 -1
  161. package/lib/DboBuilder/ViewHandler/getDbHandlerWithAbort.ts +72 -29
  162. package/lib/DboBuilder/ViewHandler/size.ts +2 -1
  163. package/lib/DboBuilder/dboBuilderUtils.ts +2 -0
  164. package/lib/PublishParser/PublishParser.ts +2 -1
  165. package/lib/PublishParser/defineServerFunction.ts +3 -5
  166. package/lib/PublishParser/getPublishedTableNames.ts +2 -1
  167. package/lib/PublishParser/publishTypesAndUtils.ts +1 -1
  168. package/lib/StorageClient/StorageClientTypes.ts +5 -4
  169. package/lib/WebsocketAPI/getClientHandlers.ts +63 -29
  170. package/lib/index.ts +3 -3
  171. package/lib/initProstgles.ts +31 -5
  172. package/lib/runClientRequest.ts +10 -3
  173. package/package.json +5 -3
@@ -0,0 +1 @@
1
+ [{"filePath":"/home/s/prostgles-server-js/tests/DBGeneratedSchema.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-redundant-type-constituents","severity":2,"message":"'any' overrides all other types in this union type.","line":233,"column":20,"nodeType":"TSAnyKeyword","messageId":"overrides","endLine":233,"endColumn":23},{"ruleId":"@typescript-eslint/no-redundant-type-constituents","severity":2,"message":"'any' overrides all other types in this union type.","line":436,"column":20,"nodeType":"TSAnyKeyword","messageId":"overrides","endLine":436,"endColumn":23}],"suppressedMessages":[],"errorCount":3,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n __rb_test_commit: {\n columns: {\n id?: null | number;\n };\n \n };\n \"\\\"\\\"\\\"*\\\"\\\"\\\"\": {\n columns: {\n \"\\\"*\\\"\"?: null | string;\n id?: number;\n qq?: null | string;\n };\n \n };\n \"\\\"\\\"\\\"quoted0\\\"\\\"\\\"\": {\n columns: {\n \"\\\"id0\\\"\"?: number;\n \"\\\"quoted1_id\\\"\"?: null | number;\n \"\\\"text_col0\\\"\"?: null | string;\n };\n \n };\n \"\\\"\\\"\\\"quoted1\\\"\\\"\\\"\": {\n columns: {\n \"\\\"id1\\\"\"?: number;\n \"\\\"quoted2_id\\\"\"?: null | number;\n \"\\\"text_col1\\\"\"?: null | string;\n };\n referencedBy: {\"\\\"\\\"\\\"quoted0\\\"\\\"\\\"\":[\"\\\"quoted1_id\\\"\"]};\n };\n \"\\\"\\\"\\\"quoted2\\\"\\\"\\\"\": {\n columns: {\n \"\\\"id2\\\"\"?: number;\n \"\\\"text_col2\\\"\"?: null | string;\n };\n referencedBy: {\"\\\"\\\"\\\"quoted1\\\"\\\"\\\"\":[\"\\\"quoted2_id\\\"\"]};\n };\n \"\\\"*\\\"\": {\n columns: {\n \"*\"?: null | string;\n id?: number;\n };\n \n };\n api_table: {\n columns: {\n col1?: null | string;\n id?: number;\n };\n \n };\n bytea_test: {\n columns: {\n id?: number;\n value?: null | Uint8Array;\n };\n \n };\n ex_j_ins: {\n columns: {\n added?: null | string;\n id?: number;\n name: string;\n public?: null | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n metadata?: null | { description: string; };\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n version?: number;\n };\n referencedBy: {\"files_versions\":[\"file_id\"],\"users_public_info\":[\"avatar\"]};\n };\n files_versions: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n created?: string;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n file_id: string;\n id?: string;\n metadata?: null | { description: string; };\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key: string;\n updated?: string;\n url?: string;\n version: number;\n };\n \n };\n geography_columns: {\n columns: {\n coord_dimension?: null | number;\n f_geography_column?: null | string;\n f_table_catalog?: null | string;\n f_table_name?: null | string;\n f_table_schema?: null | string;\n srid?: null | number;\n type?: null | string;\n };\n \n };\n geometry_columns: {\n columns: {\n coord_dimension?: null | number;\n f_geometry_column?: null | string;\n f_table_catalog?: null | string;\n f_table_name?: null | string;\n f_table_schema?: null | string;\n srid?: null | number;\n type?: null | string;\n };\n \n };\n insert_rules: {\n columns: {\n added?: null | string;\n id?: number;\n name?: null | string;\n };\n \n };\n items: {\n columns: {\n h?: null | string[];\n id?: number;\n name?: null | string;\n };\n referencedBy: {\"items2\":[\"items_id\"],\"items4a\":[\"items_id\"],\"items_multi\":[\"items0_id\",\"items1_id\",\"items2_id\",\"items3_id\"],\"slow_items\":[\"id\"],\"very_slow_items\":[\"id\"]};\n };\n items_multi: {\n columns: {\n id?: number;\n items0_id?: null | number;\n items1_id?: null | number;\n items2_id?: null | number;\n items3_id?: null | number;\n name?: null | string;\n };\n \n };\n items2: {\n columns: {\n hh?: null | string[];\n id?: number;\n items_id?: null | number;\n name?: null | string;\n };\n referencedBy: {\"items4a\":[\"items2_id\"]};\n };\n items3: {\n columns: {\n h?: null | string[];\n id?: number;\n name?: null | string;\n };\n \n };\n items4: {\n columns: {\n added?: null | string;\n id?: number;\n name: string;\n public?: null | string;\n };\n \n };\n items4_pub: {\n columns: {\n added?: null | string;\n id?: number;\n name: string;\n public?: null | string;\n };\n \n };\n items4a: {\n columns: {\n id?: number;\n items_id?: null | number;\n items2_id?: null | number;\n name?: null | string;\n };\n \n };\n lookup_col1: {\n columns: {\n description?: null | string;\n id: \"a\" | \"b\"\n };\n referencedBy: {\"uuid_text\":[\"col1\",\"col2\",\"col3\"]};\n };\n newly_created_table: {\n columns: {\n id?: null | number;\n };\n \n };\n obj_table: {\n columns: {\n id?: number;\n obj?: null | any;\n };\n \n };\n planes: {\n columns: {\n flight_number?: null | string;\n id?: number;\n last_updated: number | string;\n x?: null | number;\n y?: null | number;\n };\n \n };\n \"prostgles_test.basic\": {\n columns: {\n id?: number;\n txt?: null | string;\n };\n referencedBy: {\"prostgles_test.basic1\":[\"id_basic\"]};\n };\n \"prostgles_test.basic1\": {\n columns: {\n id?: number;\n id_basic?: null | number;\n txt?: null | string;\n };\n referencedBy: {\"prostgles_test.mv_basic1\":[\"id\"]};\n };\n \"prostgles_test.mv_basic1\": {\n columns: {\n id: number;\n id_basic: number;\n txt: string;\n };\n \n };\n rec: {\n columns: {\n id?: number;\n parent_id?: null | number;\n recf?: null | number;\n };\n referencedBy: {\"rec\":[\"parent_id\"]};\n };\n rec_ref: {\n columns: {\n id?: number;\n };\n referencedBy: {\"rec\":[\"recf\"]};\n };\n schema_version: {\n columns: {\n id: number | string;\n table_config: any;\n };\n \n };\n self_join: {\n columns: {\n id?: number;\n my_id?: null | number;\n my_id1?: null | number;\n name?: null | string;\n };\n referencedBy: {\"self_join\":[\"my_id\",\"my_id1\"]};\n };\n shapes: {\n columns: {\n geog?: null | string;\n geom?: null | string;\n id?: string;\n };\n \n };\n slow_items: {\n columns: {\n h?: null | string[];\n id?: null | number;\n name?: null | string;\n };\n \n };\n spatial_ref_sys: {\n columns: {\n auth_name?: null | string;\n auth_srid?: null | number;\n proj4text?: null | string;\n srid: number;\n srtext?: null | string;\n };\n \n };\n symbols: {\n columns: {\n id: string;\n };\n referencedBy: {\"trades\":[\"symbol\"]};\n };\n table_name3434: {\n columns: {\n id: number;\n };\n referencedBy: {\"table_name3434cccc\":[\"id\",\"id2\"]};\n };\n table_name3434cccc: {\n columns: {\n id?: null | number;\n id2?: null | number;\n };\n \n };\n tjson: {\n columns: {\n colOneOf: \"a\" | \"b\" | \"c\"\n json: { a: boolean; arr: \"1\" | \"2\" | \"3\"; arr1: 1 | 2 | 3; arr2: number[]; arrStr?: null | string[]; o?: | null\n | { o1: number; }\n | { o2: boolean; }; };\n jsonOneOf?: \n | null\n | { command: \"a\"; }\n | { command: \"b\"; option: number[]; }\n status?: \n | null\n | { ok: string; }\n | { err: string; }\n | { loading: { loaded: number; total: number; }; }\n table_config?: null | { referencedTables?: ( { name: string; minFiles: number; } )[]; recType?: null | Record<\"a\" | \"b\", { bools: boolean[]; }>; };\n };\n \n };\n tr1: {\n columns: {\n id?: number;\n t1?: null | string;\n };\n referencedBy: {\"tr2\":[\"tr1_id\"]};\n };\n tr2: {\n columns: {\n id?: number;\n t1?: null | string;\n t2?: null | string;\n tr1_id?: null | number;\n };\n referencedBy: {\"tr3\":[\"tr2_id\"]};\n };\n tr3: {\n columns: {\n id?: number;\n t2?: null | string;\n tr2_id?: null | number;\n };\n \n };\n trades: {\n columns: {\n id?: number;\n price: number | string;\n symbol: string;\n };\n \n };\n users: {\n columns: {\n email: string;\n id?: number;\n preferences: { showIntro?: boolean; theme?: \"light\" | \"dark\" | \"auto\"; others: any[]; };\n status: \"active\" | \"disabled\" | \"pending\"\n type: string;\n };\n \n };\n users_public_info: {\n columns: {\n avatar?: null | string;\n id?: number;\n name?: null | string;\n sid?: null | string;\n };\n \n };\n uuid_text: {\n columns: {\n col1?: null | \"a\" | \"b\"\n col2?: null | \"a\" | \"b\"\n col3?: null | \"a\" | \"b\"\n id?: null | string;\n };\n \n };\n v_items: {\n columns: {\n id?: null | number;\n name?: null | string;\n };\n \n };\n various: {\n columns: {\n added?: null | string;\n h?: null | string[];\n id?: number;\n jsn?: null | any;\n name?: null | string;\n tsv?: null | string;\n };\n \n };\n very_slow_items: {\n columns: {\n h?: null | string[];\n id?: null | number;\n name?: null | string;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"myfunc\": (args: { arg1: number; }) => Promise<number>;\n \"myfuncVoid\": () => Promise<void>;\n \"myfuncWithBadReturn\": (args: { arg1: number; }) => Promise<string>;\n \"myfuncWithComplexReturn\": (args: { arg1: number; }) => Promise<(Array<number> | { a: number; b: string; c: { d: boolean } })>;\n \"myAdminFunc\": (args: { arg1: number; }) => Promise<number>;\n \"myfuncForDefault\": () => Promise<void>;\n \"myfuncForDefault2\": (args: { name: string; }) => Promise<({ a: number; b?: undefined } | { b: string; a?: undefined })>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/client/basicHooks.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":6,"column":1,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":63,"endColumn":4,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[203,203],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[203,203],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":6,"column":32,"nodeType":"Identifier","messageId":"unusedVar","endLine":6,"endColumn":33},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":7,"column":86,"nodeType":"Identifier","messageId":"unusedVar","endLine":7,"endColumn":87},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'start' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":8,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":8,"endColumn":16},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":39,"column":103,"nodeType":"Identifier","messageId":"unusedVar","endLine":39,"endColumn":104}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { strict as assert } from \"assert\";\nimport { describe, test } from \"node:test\";\nimport { useAsyncEffectQueue } from \"prostgles-client\";\nimport { renderReactHookManual } from \"./renderReactHook\";\n\ndescribe(\"React hooks\", async (t) => {\n await test(\"useAsyncEffectQueue executes the first and debounces the rest\", async (t) => {\n const start = Date.now();\n const calls: (string | number)[] = [];\n const addCall = (num: number) => {\n calls.push(num);\n // calls.push(num + \"-\" + (Date.now() - start));\n };\n const getHookArgs = (step: number) =>\n [\n async () => {\n addCall(step);\n await tout(500);\n return () => {\n addCall(step * 10 + step);\n };\n },\n [step],\n ] satisfies [() => Promise<any>, any[]];\n const { setProps, unmount } = await renderReactHookManual({\n hook: useAsyncEffectQueue,\n initialProps: getHookArgs(1),\n renderDuration: 10,\n });\n setProps(getHookArgs(2));\n setProps(getHookArgs(3));\n await tout(700);\n assert.deepStrictEqual(calls, [1, 11, 3]);\n unmount();\n await tout(900);\n assert.deepStrictEqual(calls, [1, 11, 3, 33]);\n });\n\n await test(\"useAsyncEffectQueue executes the first and debounces the rest if still mounted\", async (t) => {\n const calls: number[] = [];\n const getHookArgs = (step: number) =>\n [\n async () => {\n calls.push(step);\n (await tout(500)) as any;\n return () => {\n calls.push(step * 10 + step);\n };\n },\n [step],\n ] satisfies [() => Promise<any>, any[]];\n const { setProps, unmount } = await renderReactHookManual({\n hook: useAsyncEffectQueue,\n initialProps: getHookArgs(1),\n renderDuration: 10,\n });\n setProps(getHookArgs(2));\n setProps(getHookArgs(3));\n unmount();\n await tout(1500);\n assert.deepStrictEqual(calls, [1, 11]);\n });\n});\n\nconst tout = (ms: number) => new Promise((res) => setTimeout(res, ms));\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/client/hooks.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":14,"column":40,"nodeType":"Identifier","messageId":"unusedVar","endLine":14,"endColumn":41},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":18,"column":37,"nodeType":"Identifier","messageId":"unusedVar","endLine":18,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":26,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":26,"endColumn":39},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":69,"column":37,"nodeType":"Identifier","messageId":"unusedVar","endLine":69,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":71,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":71,"endColumn":39},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":91,"column":42,"nodeType":"Identifier","messageId":"unusedVar","endLine":91,"endColumn":43},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":93,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":93,"endColumn":34,"fix":{"range":[3191,3192],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":104,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":104,"endColumn":35},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'funcHandles' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":105,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":105,"endColumn":24},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":133,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":133,"endColumn":33,"fix":{"range":[4382,4383],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":148,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":148,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .isLoading on an `any` value.","line":149,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":149,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":150,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":150,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .data on an `any` value.","line":150,"column":36,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":150,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .length on an `any` value.","line":151,"column":29,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":151,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":152,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":152,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [0] on an `any` value.","line":152,"column":37,"nodeType":"Literal","messageId":"unsafeMemberExpression","endLine":152,"endColumn":38},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":156,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":156,"endColumn":30,"fix":{"range":[5124,5125],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":163,"column":42,"nodeType":"ChainExpression","messageId":"unsafeReturn","endLine":163,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [0] on an `any` value.","line":163,"column":49,"nodeType":"Literal","messageId":"unsafeMemberExpression","endLine":163,"endColumn":50},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":192,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":192,"endColumn":30,"fix":{"range":[6107,6108],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":196,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":196,"endColumn":42,"fix":{"range":[6234,6235],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":201,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":204,"endColumn":10},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":201,"column":26,"nodeType":"MemberExpression","messageId":"errorCall","endLine":201,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .useMemo on a type that cannot be resolved.","line":201,"column":32,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":201,"endColumn":39},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":202,"column":43,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":202,"endColumn":45,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[6470,6472],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":205,"column":35,"nodeType":"Property","messageId":"anyAssignment","endLine":205,"endColumn":43},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":214,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":214,"endColumn":62,"fix":{"range":[6761,6762],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":215,"column":45,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":215,"endColumn":47,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[6808,6810],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":218,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":218,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .run on a type that cannot be resolved.","line":218,"column":55,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":218,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .x on a type that cannot be resolved.","line":219,"column":45,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":219,"endColumn":46},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":221,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":221,"endColumn":32,"fix":{"range":[7012,7013],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":222,"column":45,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":222,"endColumn":47,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7082,7084],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .x on a type that cannot be resolved.","line":225,"column":50,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":225,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .run on a type that cannot be resolved.","line":226,"column":47,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":226,"endColumn":50},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":234,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":234,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .run on a type that cannot be resolved.","line":234,"column":65,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":234,"endColumn":68},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":236,"column":45,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":236,"endColumn":47,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7693,7695],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .x on a type that cannot be resolved.","line":239,"column":50,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":239,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .run on a type that cannot be resolved.","line":240,"column":47,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":240,"endColumn":50},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":253,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":253,"endColumn":30,"fix":{"range":[8330,8331],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":259,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":259,"endColumn":27,"fix":{"range":[8540,8541],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":266,"column":11,"nodeType":"MemberExpression","messageId":"errorCall","endLine":266,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .useMemo on a type that cannot be resolved.","line":266,"column":17,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":266,"endColumn":24},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":267,"column":58,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":267,"endColumn":60,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[8868,8870],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":270,"column":11,"nodeType":"MemberExpression","messageId":"errorCall","endLine":270,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .useMemo on a type that cannot be resolved.","line":270,"column":17,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":270,"endColumn":24},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":271,"column":58,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":271,"endColumn":60,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[9005,9007],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":274,"column":11,"nodeType":"MemberExpression","messageId":"errorCall","endLine":274,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .useMemo on a type that cannot be resolved.","line":274,"column":17,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":274,"endColumn":24},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":275,"column":58,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":275,"endColumn":60,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[9142,9144],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":288,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":288,"endColumn":62,"fix":{"range":[9450,9451],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":290,"column":54,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":290,"endColumn":56,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[9551,9553],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type error.","line":294,"column":73,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":294,"endColumn":76},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":296,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":296,"endColumn":32,"fix":{"range":[9769,9770],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .x on a type that cannot be resolved.","line":301,"column":59,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":301,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .run on a type that cannot be resolved.","line":302,"column":56,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":302,"endColumn":59},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":304,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":304,"endColumn":56,"fix":{"range":[10234,10235],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type error.","line":307,"column":83,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":307,"endColumn":86},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":308,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":308,"endColumn":48,"fix":{"range":[10394,10395],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .x on a type that cannot be resolved.","line":313,"column":59,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":313,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .run on a type that cannot be resolved.","line":314,"column":56,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":314,"endColumn":59},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":316,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":316,"endColumn":61,"fix":{"range":[10874,10875],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":328,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":328,"endColumn":27,"fix":{"range":[11232,11233],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":334,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":334,"endColumn":30,"fix":{"range":[11431,11432],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":337,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":337,"endColumn":30,"fix":{"range":[11594,11595],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":356,"column":13,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":356,"endColumn":15,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[12044,12046],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":357,"column":19,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":357,"endColumn":21,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[12084,12086],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":362,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":362,"endColumn":32,"fix":{"range":[12289,12290],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":366,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":366,"endColumn":32,"fix":{"range":[12447,12448],"text":""}}],"suppressedMessages":[],"errorCount":30,"fatalErrorCount":0,"warningCount":42,"fixableErrorCount":19,"fixableWarningCount":0,"source":"import { strict as assert } from \"assert\";\nimport { describe, test } from \"node:test\";\nimport { pickKeys } from \"prostgles-types\";\nimport React from \"react\";\nimport type { DBHandlerClient } from \"./index\";\nimport { renderReactHook, renderReactHookManual } from \"./renderReactHook\";\n\nexport const clientHooks = async (\n db: DBHandlerClient,\n reconnectSocket: (reattachOnly?: boolean) => Promise<void>,\n) => {\n let reconnectTestError: unknown;\n const resultLoading = { data: undefined, isLoading: true, error: undefined };\n await describe(\"React hooks\", async (t) => {\n const defaultFilter = { name: \"abc\" };\n await Promise.all(\n [\"useFind\", \"useSubscribe\", \"useFindOne\", \"useSubscribeOne\"].map(async (hookName) => {\n await test(hookName, async (t) => {\n const expectsOne = hookName.includes(\"One\");\n const options = {\n select: { added: \"$Mon\" },\n limit: expectsOne ? undefined : 1,\n };\n const expectedData = expectsOne ? { added: \"Dec\" } : [{ added: \"Dec\" }];\n const { rerender, results } = await renderReactHook({\n hook: db.items4[hookName]!,\n props: [{ name: \"abc\" }, options],\n expectedRerenders: 2,\n });\n\n assert.deepStrictEqual(results, [\n resultLoading,\n { data: expectedData, isLoading: false, error: undefined },\n ]);\n\n const { results: errorResults } = await rerender({\n props: [{ named: \"error\" }, options],\n expectedRerenders: 2,\n });\n\n assert.deepStrictEqual(errorResults, [\n resultLoading,\n {\n data: undefined,\n isLoading: false,\n error: {\n message:\n 'items4.named is invalid/disallowed for filtering. Allowed columns: added, \"id\", \"public\", \"name\"',\n },\n },\n ]);\n });\n })\n );\n\n await Promise.all(\n [\n {\n hookName: \"useCount\",\n result1: { data: 2, error: undefined, isLoading: false },\n result2: { data: 0, error: undefined, isLoading: false },\n },\n {\n hookName: \"useSize\",\n result1: { data: \"93\", error: undefined, isLoading: false },\n result2: { data: \"0\", error: undefined, isLoading: false },\n },\n ].map(async ({ hookName, result1, result2 }) => {\n await test(hookName, async (t) => {\n const { results, rerender } = await renderReactHook({\n hook: db.items4[hookName]!,\n props: [defaultFilter],\n expectedRerenders: 2,\n });\n\n // Initial state\n assert.deepStrictEqual(results, [resultLoading, result1]);\n\n // Rerender with different filter\n const { results: noResults } = await rerender({\n props: [{ id: -1 }],\n expectedRerenders: 2,\n });\n\n // New results\n assert.deepStrictEqual(noResults, [resultLoading, result2]);\n });\n })\n );\n\n await test(\"useCount planes\", async (t) => {\n const { results } = await renderReactHook({\n hook: db.planes.useCount!,\n props: [{}],\n expectedRerenders: 2,\n });\n assert.deepStrictEqual(results, [\n { data: undefined, isLoading: true, error: undefined },\n { data: 100, error: undefined, isLoading: false },\n ]);\n });\n\n // // TODO fix useSync test\n await test(\"useSync\", async (t) => {\n const funcHandles = {\n $cloneMultiSync: 1,\n $cloneSync: 1,\n $delete: 1,\n $find: 1,\n $get: 1,\n $unsync: 1,\n $update: 1,\n };\n const plane0 = {\n id: 0,\n x: 20,\n y: 0,\n };\n // await db.planes.insert({ name: \"abc\" });\n\n // const { results: firstPlaneResults } = await renderReactHook({\n // hook: db.planes.useFindOne!,\n // props: [{ }],\n // expectedRerenders: 2\n // });\n // assert.deepStrictEqual(firstPlaneResults, [\n // { data: undefined, isLoading: true, error: undefined },\n // { data: undefined, error: undefined, isLoading: false },\n // ]);\n\n const props = [{ id: 0 }, { handlesOnData: true }]; // , select: { id: 1, x: 1 }\n const { results, rerender } = await renderReactHook({\n hook: db.planes.useSync!,\n props,\n expectedRerenders: 3,\n });\n assert.equal(results.length, 3);\n assert.deepStrictEqual(results[0], {\n data: undefined,\n isLoading: true,\n error: undefined,\n });\n /** This fails from time to time */\n // assert.deepStrictEqual(\n // results[1],\n // { data: [], error: undefined, isLoading: false },\n // );\n const lastResult = results.at(-1);\n assert.equal(lastResult?.isLoading, false);\n const lastData = lastResult?.data;\n assert.equal(lastData.length, 1);\n const lastDataItem = lastData[0];\n assert.deepStrictEqual(pickKeys(lastDataItem, Object.keys(plane0)), plane0);\n\n // Update item\n await db.planes.update!({ id: 0 }, { x: 230 });\n const { results: deletedResults } = await rerender({\n props,\n expectedRerenders: 3,\n });\n\n assert.deepStrictEqual(\n deletedResults.map(({ data }) => data?.[0]?.x),\n [\n undefined, // TODO - should be defined and 20\n 20,\n 230,\n ]\n );\n\n // // Rerender with different filter\n // rerender({ id: -1 });\n\n // await expectValues(\n // result,\n // [\n // { data: undefined, error: undefined, isLoading: true },\n // { data: [], error: undefined, isLoading: false },\n // ]\n // );\n\n // await expectValues(\n // result,\n // [\n // { data: undefined, error: undefined, isLoading: true },\n // { data: [], error: undefined, isLoading: false }\n // ]\n // );\n });\n\n await test(\"useSync updates invalidate useMemo without mutating old data\", async () => {\n await db.planes.update!({ id: 0 }, { x: 20 });\n\n let memoRun = 0;\n const useSyncWithMemo = () => {\n const result = db.planes.useSync!<\n { id: number; x: number },\n { handlesOnData: true }\n >({ id: 0 }, { handlesOnData: true });\n const { data } = result;\n const memoized = React.useMemo(\n () => ({ run: ++memoRun, x: data?.[0]?.x }),\n [data],\n );\n return { ...result, data, memoized };\n };\n\n const rendered = await renderReactHookManual({\n hook: useSyncWithMemo,\n initialProps: [],\n });\n\n try {\n const getLatest = () => rendered.getResults().at(-1)!;\n await waitFor(() => getLatest().data?.[0]?.x === 20);\n\n const initialResult = getLatest();\n const initialMemoRun = initialResult.memoized.run;\n assert.equal(initialResult.memoized.x, 20);\n\n await db.planes.update!({ id: 0 }, { x: 231 });\n await waitFor(() => getLatest().data?.[0]?.x === 231);\n\n const serverUpdateResult = getLatest();\n assert.equal(serverUpdateResult.memoized.x, 231);\n assert.ok(serverUpdateResult.memoized.run > initialMemoRun);\n assert.notStrictEqual(serverUpdateResult.data, initialResult.data);\n assert.notStrictEqual(\n serverUpdateResult.data[0],\n initialResult.data[0],\n );\n assert.equal(initialResult.data[0].x, 20);\n\n const serverUpdateMemoRun = serverUpdateResult.memoized.run;\n await serverUpdateResult.data[0].$update({ x: 232 });\n await waitFor(() => getLatest().data?.[0]?.x === 232);\n\n const handleUpdateResult = getLatest();\n assert.equal(handleUpdateResult.memoized.x, 232);\n assert.ok(handleUpdateResult.memoized.run > serverUpdateMemoRun);\n assert.notStrictEqual(handleUpdateResult.data, serverUpdateResult.data);\n assert.notStrictEqual(\n handleUpdateResult.data[0],\n serverUpdateResult.data[0],\n );\n assert.equal(serverUpdateResult.data[0].x, 231);\n } finally {\n rendered.unmount();\n }\n });\n\n await test(\"concurrent useSync hooks with matching options all update\", async () => {\n await db.planes.update!({ id: 0 }, { x: 30 });\n\n const filter = { id: 0 };\n const syncOptions = { handlesOnData: true } as const;\n const memoRuns = [0, 0, 0];\n const usePlaneSync = () =>\n db.planes.useSync!<\n { id: number; x: number },\n { handlesOnData: true }\n >(filter, syncOptions);\n const useConcurrentSyncs = () => {\n const syncs = [usePlaneSync(), usePlaneSync(), usePlaneSync()];\n const memoized = [\n React.useMemo(\n () => ({ run: ++memoRuns[0], x: syncs[0].data?.[0]?.x }),\n [syncs[0].data],\n ),\n React.useMemo(\n () => ({ run: ++memoRuns[1], x: syncs[1].data?.[0]?.x }),\n [syncs[1].data],\n ),\n React.useMemo(\n () => ({ run: ++memoRuns[2], x: syncs[2].data?.[0]?.x }),\n [syncs[2].data],\n ),\n ];\n return { syncs, memoized };\n };\n\n const rendered = await renderReactHookManual({\n hook: useConcurrentSyncs,\n initialProps: [],\n });\n\n try {\n const getLatest = () => rendered.getResults().at(-1)!;\n const allSyncsHaveX = (x: number) =>\n getLatest().syncs.every((sync) => sync.data?.[0]?.x === x);\n await waitFor(() => allSyncsHaveX(30));\n\n const initialResult = getLatest();\n const initialMemoRuns = initialResult.memoized.map(({ run }) => run);\n\n await db.planes.update!({ id: 0 }, { x: 31 });\n await waitFor(() => allSyncsHaveX(31));\n\n const serverUpdateResult = getLatest();\n serverUpdateResult.syncs.forEach((sync, index) => {\n assert.equal(serverUpdateResult.memoized[index].x, 31);\n assert.ok(serverUpdateResult.memoized[index].run > initialMemoRuns[index]);\n assert.notStrictEqual(sync.data, initialResult.syncs[index].data);\n assert.equal(initialResult.syncs[index].data![0].x, 30);\n });\n\n const serverUpdateMemoRuns = serverUpdateResult.memoized.map(({ run }) => run);\n await serverUpdateResult.syncs[0].data![0].$update({ x: 32 });\n await waitFor(() => allSyncsHaveX(32));\n\n const handleUpdateResult = getLatest();\n handleUpdateResult.syncs.forEach((sync, index) => {\n assert.equal(handleUpdateResult.memoized[index].x, 32);\n assert.ok(handleUpdateResult.memoized[index].run > serverUpdateMemoRuns[index]);\n assert.notStrictEqual(sync.data, serverUpdateResult.syncs[index].data);\n assert.equal(serverUpdateResult.syncs[index].data![0].x, 31);\n });\n } finally {\n rendered.unmount();\n }\n });\n\n await test(\"concurrent useSync hooks receive inserts after reattachment and reconnect\", async () => {\n const y = 999_999;\n const filter = { y };\n const options = { handlesOnData: false } as const;\n const usePlane = () =>\n db.planes.useSync!<\n { id: number; x: number; y: number },\n { handlesOnData: false }\n >(filter, options);\n const usePlanes = () => [usePlane(), usePlane()];\n\n await db.planes.delete!(filter);\n // Exceed the default 50-row snapshot and give the cursor distinct timestamps.\n const start = Date.now() - 1000;\n await db.planes.insert!(\n Array.from({ length: 101 }, (_, index) => ({\n id: 999_000 + index,\n x: 1 + index,\n y,\n last_updated: start + index,\n })),\n );\n\n const rendered = await renderReactHookManual({\n hook: usePlanes,\n initialProps: [],\n });\n\n try {\n const allSyncsHaveX = (x: number, count: number) =>\n rendered\n .getResults()\n .at(-1)\n ?.every(({ data }) =>\n data?.length === count && data.some((plane) => plane.x === x),\n );\n await waitFor(() => Boolean(allSyncsHaveX(101, 101)));\n\n await reconnectSocket(true);\n await db.planes.insert!({ id: 999_999, x: 102, y });\n await waitFor(() => Boolean(allSyncsHaveX(102, 102)));\n\n await reconnectSocket();\n await db.planes.insert!({ id: 1_000_000, x: 103, y });\n await waitFor(() => Boolean(allSyncsHaveX(103, 103)));\n } catch (error) {\n reconnectTestError = error;\n throw error;\n } finally {\n rendered.unmount();\n }\n });\n });\n\n // node:test records nested failures instead of rejecting describe().\n if (reconnectTestError) throw reconnectTestError;\n};\n\nconst waitFor = async (condition: () => boolean, timeout = 5000) => {\n const start = Date.now();\n while (!condition()) {\n if (Date.now() - start > timeout) {\n throw new Error(\"Timed out waiting for useSync update\");\n }\n await tout(20);\n }\n};\n\nconst tout = (ms: number) => new Promise((res) => setTimeout(res, ms));\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/client/index.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":5,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":5,"endColumn":68,"fix":{"range":[166,166],"text":" type"}},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":7,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":7,"endColumn":66,"fix":{"range":[307,330],"text":"import type { DBSchemaTable} from \"prostgles-types\";\nimport {"}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":21,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":21,"endColumn":93},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":22,"column":15,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":22,"endColumn":88},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":79,"column":5,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":79,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe object destructuring of a property with an `any` value.","line":84,"column":11,"nodeType":"Identifier","messageId":"unsafeObjectPattern","endLine":84,"endColumn":14},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":84,"column":19,"nodeType":"Identifier","messageId":"neverNullish","endLine":84,"endColumn":23},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":85,"column":7,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":85,"endColumn":11},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":94,"column":7,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":94,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":94,"column":29,"nodeType":"Property","messageId":"anyAssignment","endLine":94,"endColumn":63},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":94,"column":34,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":94,"endColumn":61},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .toString on an `any` value.","line":94,"column":53,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":94,"endColumn":61},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":94,"column":65,"nodeType":"Property","messageId":"anyAssignment","endLine":94,"endColumn":75},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'cb' is defined but never used. Allowed unused args must match /^_/u.","line":95,"column":8,"nodeType":"Identifier","messageId":"unusedVar","endLine":95,"endColumn":10},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'data' is defined but never used. Allowed unused args must match /^_/u.","line":116,"column":30,"nodeType":"Identifier","messageId":"unusedVar","endLine":116,"endColumn":34},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":118,"column":5,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":174,"endColumn":8,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[3886,3886],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[3886,3886],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'socket' is defined but never used. Allowed unused args must match /^_/u.","line":123,"column":21,"nodeType":"Identifier","messageId":"unusedVar","endLine":123,"endColumn":27},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":128,"column":13,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":128,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":138,"column":34,"nodeType":"ConditionalExpression","messageId":"unsafeReturn","endLine":138,"endColumn":79},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'url' is defined but never used. Allowed unused args must match /^_/u.","line":142,"column":64,"nodeType":"Identifier","messageId":"unusedVar","endLine":142,"endColumn":67},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'lineNumber' is defined but never used. Allowed unused args must match /^_/u.","line":142,"column":69,"nodeType":"Identifier","messageId":"unusedVar","endLine":142,"endColumn":79},{"ruleId":"@typescript-eslint/restrict-plus-operands","severity":2,"message":"Invalid operand for a '+' operation. Operands must each be a number or string, allowing a string + any of: `any`, `boolean`, `null`, `RegExp`, `undefined`. Got `Event`.","line":143,"column":49,"nodeType":"Identifier","messageId":"invalid","endLine":143,"endColumn":57},{"ruleId":"@typescript-eslint/no-base-to-string","severity":2,"message":"'errorMsg' may use Object's default stringification format ('[object Object]') when stringified.","line":143,"column":49,"nodeType":"Identifier","messageId":"baseToString","endLine":143,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":150,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":150,"endColumn":15},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":151,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":151,"endColumn":16},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":152,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":152,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":153,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":153,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":154,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":154,"endColumn":17},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":155,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":155,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":171,"column":22,"nodeType":"Property","messageId":"anyAssignment","endLine":171,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ err: any; }`.","line":178,"column":12,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":178,"endColumn":13}],"suppressedMessages":[],"errorCount":11,"fatalErrorCount":0,"warningCount":21,"fixableErrorCount":2,"fixableWarningCount":0,"source":"import prostgles from \"prostgles-client\";\nimport io from \"socket.io-client\";\n\nimport type { DBHandlerClient, UseProstglesClientProps } from \"prostgles-client\";\nimport { AuthHandler } from \"prostgles-client/dist/getAuthHandler\";\nimport type { ClientFunctionHandler } from \"prostgles-client/dist/getMethods\";\nimport { DBSchemaTable, type SQLHandler } from \"prostgles-types\";\nimport { clientFileTests } from \"../clientFileTests.spec\";\nimport { clientOnlyQueries } from \"../clientOnlyQueries.spec\";\nimport { clientRestApi } from \"../clientRestApi.spec\";\nimport { isomorphicQueries } from \"../isomorphicQueries.spec\";\nimport { isomorphicQueriesTyped } from \"../isomorphicQueriesTyped.spec\";\nimport { clientHooks } from \"./hooks.spec\";\nimport { newly_created_table, useProstglesTest } from \"./useProstgles.spec\";\nexport { DBHandlerClient } from \"prostgles-client\";\nexport { AuthHandler } from \"prostgles-client/dist/getAuthHandler\";\nexport type { ClientFunctionHandler } from \"prostgles-client/dist/getMethods\";\n\nconst start = Date.now();\nconst log = (msgOrObj: any, extra?: any) => {\n const msg = msgOrObj && typeof msgOrObj === \"object\" ? JSON.stringify(msgOrObj) : msgOrObj;\n console.log(...[`(client) t+ ${Date.now() - start}ms ` + msg, extra].filter((v) => v));\n};\nlog(\"Started client...\");\n\nconst { TEST_NAME } = process.env;\nconst url = \"http://127.0.0.1:3001\";\nconst defaultPath = \"/teztz/s\";\nconst pathWatchSchema = \"/teztz/sWatchSchema\";\nconst getClientOptions = (watchSchema = false) => {\n const path = watchSchema ? pathWatchSchema : defaultPath;\n return {\n endpoint: url,\n // token: TEST_NAME,\n socketOptions: {\n query: { token: TEST_NAME },\n path,\n },\n } satisfies UseProstglesClientProps;\n};\nconst { endpoint, socketOptions } = getClientOptions();\nconst socket = io(endpoint, { ...socketOptions });\n\ntype ClientTestSpecV2 = (args: {\n db: DBHandlerClient<void>;\n sql: SQLHandler | undefined;\n methods: ClientFunctionHandler;\n tableSchema: DBSchemaTable[];\n isReconnect?: boolean;\n auth: AuthHandler;\n reconnectSocket: (reattachOnly?: boolean) => Promise<void>;\n}) => Promise<void>;\n\nlet reconnectReadyResolve: () => void;\n\nconst tests: Record<string, ClientTestSpecV2> = {\n main: async ({ db, sql, methods, tableSchema, auth, reconnectSocket }) => {\n await sql(`DROP TABLE IF EXISTS ${newly_created_table}`);\n await isomorphicQueries(db, sql, log, TEST_NAME);\n await isomorphicQueriesTyped(\n //@ts-ignore\n db,\n );\n await clientOnlyQueries(db, sql, auth, log, methods, tableSchema, TEST_NAME);\n await clientHooks(db, reconnectSocket);\n },\n useProstgles: async ({ db, sql }) => {\n await useProstglesTest(db, sql, getClientOptions);\n },\n files: async ({ db, sql }) => {\n await clientFileTests(db, sql);\n },\n rest_api: async ({ db, tableSchema }) => {\n await clientRestApi(db, tableSchema, TEST_NAME);\n },\n};\n\nconst testFileFunc = tests[TEST_NAME];\nif (!testFileFunc) {\n throw `Invalid TEST_NAME env var provided (${TEST_NAME}). Expecting one of: ${Object.keys(tests)}`;\n}\n\nconst stopTest = (args?: { err: any }) => {\n const { err } = args ?? {};\n if (args) {\n log(`TEST_NAME: ${TEST_NAME} Error: ${JSON.stringify(err)}`, err);\n } else {\n log(`TEST_NAME: ${TEST_NAME} Finished OK`);\n }\n\n setTimeout(() => {\n socket.emit(\n \"stop-test\",\n !args ? undefined : { err: (err ?? \"Unknown\").toString(), error: err },\n (cb) => {\n log(\"Stopping client...\");\n if (err) console.trace(err);\n },\n );\n setTimeout(() => {\n process.exit(err ? 1 : 0);\n }, 1000);\n }, 1000);\n};\n\ntry {\n socket.on(\"connected\", () => {\n log(\"Client connected.\");\n });\n socket.on(\"connect\", () => {\n log(\"Client connect.\");\n });\n socket.on(\"connect_failed\", (err) => {\n log(\"connect_failed\", err);\n });\n socket.once(\"start-test\", (data) => {\n //@ts-ignore\n prostgles({\n socket,\n onDisconnect: () => {\n log(\"Disconnected\");\n },\n onReconnect: (socket) => {\n log(\"Reconnected\");\n },\n onReady: async ({ db, sql, methods, tableSchema, auth, isReconnect }) => {\n log(`TEST_NAME: ${TEST_NAME} Started`);\n if (reconnectReadyResolve) {\n reconnectReadyResolve();\n return;\n }\n try {\n //@ts-ignore\n if (typeof window !== \"undefined\") {\n const onLog = (...args: any[]) => {\n socket.emit(\n \"log\",\n args.map((v) => (typeof v === \"object\" ? JSON.stringify(v) : v)).join(\" \"),\n );\n };\n //@ts-ignore\n window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {\n console.error(\"Error occured: \" + errorMsg);\n stopTest({ err: errorMsg });\n return false;\n };\n console.log = onLog;\n }\n await testFileFunc({\n db,\n sql,\n methods,\n tableSchema,\n auth,\n isReconnect,\n reconnectSocket: async (reattachOnly = false) => {\n const ready = new Promise<void>((resolve) => {\n reconnectReadyResolve = resolve;\n });\n if (reattachOnly) {\n socket.emit(\"reattach-syncs\");\n } else {\n socket.io.engine.close();\n }\n await ready;\n },\n });\n\n stopTest();\n } catch (err) {\n stopTest({ err });\n }\n },\n });\n });\n} catch (e) {\n console.trace(e);\n stopTest(e);\n throw e;\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/client/renderReactHook.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":1,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":1,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":2,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":3,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":14,"endColumn":3},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe construction of an `any` typed value.","line":3,"column":20,"nodeType":"NewExpression","messageId":"unsafeNew","endLine":14,"endColumn":3},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .navigator on an `any` value.","line":29,"column":31,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":29,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .document on an `any` value.","line":30,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":30,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-function-type","severity":2,"message":"The `Function` type accepts any function-like value.\nPrefer explicitly defining any function parameters and return type.","line":51,"column":17,"nodeType":"Identifier","messageId":"bannedFunctionType","endLine":51,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":52,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":52,"endColumn":64},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":52,"column":14,"nodeType":"Identifier","messageId":"errorCall","endLine":52,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":52,"column":25,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":52,"endColumn":55},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .document on an `any` value.","line":52,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":52,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":62,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":62,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any` type.","line":62,"column":25,"nodeType":"SpreadElement","messageId":"unsafeSpread","endLine":62,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":63,"column":5,"nodeType":"MemberExpression","messageId":"errorCall","endLine":63,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .useEffect on a type that cannot be resolved.","line":63,"column":11,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":63,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type error.","line":67,"column":5,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":67,"endColumn":53},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":67,"column":12,"nodeType":"MemberExpression","messageId":"errorCall","endLine":67,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createElement on a type that cannot be resolved.","line":67,"column":18,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":67,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":69,"column":3,"nodeType":"MemberExpression","messageId":"errorCall","endLine":69,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .render on a type that cannot be resolved.","line":69,"column":8,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":69,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":69,"column":15,"nodeType":"MemberExpression","messageId":"errorCall","endLine":69,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createElement on a type that cannot be resolved.","line":69,"column":21,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":69,"endColumn":34},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'props' is defined but never used. Allowed unused args must match /^_/u.","line":78,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":78,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type error.","line":79,"column":5,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":79,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":79,"column":12,"nodeType":"MemberExpression","messageId":"errorCall","endLine":79,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createElement on a type that cannot be resolved.","line":79,"column":18,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":79,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":81,"column":3,"nodeType":"MemberExpression","messageId":"errorCall","endLine":81,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .render on a type that cannot be resolved.","line":81,"column":8,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":81,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":81,"column":15,"nodeType":"MemberExpression","messageId":"errorCall","endLine":81,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createElement on a type that cannot be resolved.","line":81,"column":21,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":81,"endColumn":34},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":112,"column":7,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":112,"endColumn":27,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[2911,2911],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[2911,2911],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":112,"column":15,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":112,"endColumn":17,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2919,2921],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any[]` assigned to a parameter of type `ReturnType<H>[]`.","line":112,"column":18,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":112,"endColumn":25},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":115,"column":13,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":115,"endColumn":22},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":116,"column":11,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":116,"endColumn":37},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":119,"column":20,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":119,"endColumn":22,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3140,3142],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any[]` assigned to a parameter of type `ReturnType<H>[]`.","line":119,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":119,"endColumn":30},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":125,"column":24,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":125,"endColumn":26,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3360,3362],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any[]` assigned to a parameter of type `ReturnType<H>[]`.","line":125,"column":27,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":125,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any[]`.","line":127,"column":29,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":127,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":135,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":135,"endColumn":62},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":135,"column":34,"nodeType":"MemberExpression","messageId":"errorCall","endLine":135,"endColumn":48},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .useState on a type that cannot be resolved.","line":135,"column":40,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":135,"endColumn":48},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":136,"column":7,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":136,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":137,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":137,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an error typed type.","line":137,"column":27,"nodeType":"SpreadElement","messageId":"unsafeSpread","endLine":137,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":138,"column":7,"nodeType":"MemberExpression","messageId":"errorCall","endLine":138,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .useEffect on a type that cannot be resolved.","line":138,"column":13,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":138,"endColumn":22},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":140,"column":20,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":140,"endColumn":22,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3801,3803],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type error.","line":144,"column":7,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":144,"endColumn":55},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":144,"column":14,"nodeType":"MemberExpression","messageId":"errorCall","endLine":144,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createElement on a type that cannot be resolved.","line":144,"column":20,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":144,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":146,"column":5,"nodeType":"MemberExpression","messageId":"errorCall","endLine":146,"endColumn":16},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .render on a type that cannot be resolved.","line":146,"column":10,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":146,"endColumn":16},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":146,"column":17,"nodeType":"MemberExpression","messageId":"errorCall","endLine":146,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createElement on a type that cannot be resolved.","line":146,"column":23,"nodeType":"Identifier","messageId":"errorMemberExpression","endLine":146,"endColumn":36},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":159,"column":22,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":159,"endColumn":32},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":160,"column":7,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":160,"endColumn":17},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":170,"column":15,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":170,"endColumn":17,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[4630,4632],"text":""},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":11,"fatalErrorCount":0,"warningCount":49,"fixableErrorCount":0,"fixableWarningCount":0,"source":"const jsdom = require(\"jsdom\");\nconst { JSDOM } = jsdom;\nconst { window } = new JSDOM(`\n<!DOCTYPE html>\n<html>\n\t<head>\n\t</head>\n\t<body>\n <div id=\"root\"></div>\n\t\t<script>\n\t\t</script>\n\t</body>\n</html>\n`);\n\nconst setGlobal = (key: \"window\" | \"navigator\" | \"document\", value: any) => {\n try {\n Object.defineProperty(globalThis, key, {\n value,\n configurable: true,\n writable: true,\n });\n } catch {\n // Node 24 may expose getter-only globals; keep existing value in that case.\n }\n};\n\nsetGlobal(\"window\", window);\nsetGlobal(\"navigator\", window.navigator);\nsetGlobal(\"document\", window.document);\n\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\ntype Hook = (...args: any[]) => any;\n\n// TODO: add hook result types\ntype RenderHookArgs = {\n hook: Hook;\n props: any[];\n onResult?: (result: any) => void;\n expectedRerenders: number;\n timeout?: number;\n /**\n * Time to wait after the last render to resolve the promise\n * Used to catch any extra unwanted renders\n */\n lastRenderWait?: number;\n};\n\nlet testedHook: Function;\nconst root = createRoot(window.document.getElementById(\"root\"));\nconst reactRender = ({\n hook,\n props,\n onResult,\n onUnmount,\n}: Pick<Required<RenderHookArgs>, \"hook\" | \"props\" | \"onResult\"> & {\n onUnmount: () => void;\n}) => {\n const BasicComponent = ({ props }) => {\n const result = hook(...props);\n React.useEffect(() => {\n return onUnmount;\n }, []);\n onResult(result);\n return React.createElement(\"h1\", null, `Hello`);\n };\n root.render(React.createElement(BasicComponent, { props }, null));\n};\n\ntype RenderResult = {\n results: any[];\n rerender: (args: Omit<RenderHookArgs, \"hook\">) => Promise<RenderResult>;\n};\n\nconst resetBasicComponent = () => {\n const OtherBasicComponent = ({ props }) => {\n return React.createElement(\"div\", null, `Goodbye`);\n };\n root.render(React.createElement(OtherBasicComponent, { props: {} }, null));\n};\n\ntype OnEnd<H extends Hook> = (results: ReturnType<H>[]) => Promise<void> | void;\n\nexport const renderReactHookManual = async <H extends Hook>(rootArgs: {\n hook: H;\n initialProps: Parameters<H>;\n onUnmount?: () => void;\n /**\n * Time to wait after the last render to resolve the promise\n * default: 250\n */\n renderDuration?: number;\n onEnd?: OnEnd<H>;\n onRender?: OnEnd<H>;\n}): Promise<{\n setProps: (props: Parameters<H>, opts?: { waitFor?: number; onEnd?: OnEnd<H> }) => void;\n getResults: () => ReturnType<H>[];\n unmount: () => void;\n}> => {\n const { hook, onUnmount, renderDuration = 250, onEnd, onRender } = rootArgs;\n let lastRenderWaitTimeout: NodeJS.Timeout | null = null;\n let didResolve = false;\n let setProps: (props: any[]) => void;\n resetBasicComponent();\n return new Promise((resolve, reject) => {\n const results = [];\n const onCompRender = (result) => {\n results.push(result);\n if (didResolve) return;\n onRender?.(results);\n clearTimeout(lastRenderWaitTimeout);\n lastRenderWaitTimeout = setTimeout(async () => {\n if (!setProps) {\n reject(\"setProps not set\");\n return;\n }\n await onEnd?.(results);\n didResolve = true;\n return resolve({\n setProps: async (props, { waitFor = 250, onEnd } = {}) => {\n setProps(props);\n await tout(waitFor);\n await onEnd?.(results);\n },\n getResults: () => results,\n unmount: () => {\n resetBasicComponent();\n },\n });\n }, renderDuration);\n };\n const BasicComponent = ({ props: initialProps }) => {\n const [props, _setProps] = React.useState(initialProps);\n setProps = _setProps;\n const result = hook(...props);\n React.useEffect(() => {\n return () => {\n onUnmount?.();\n };\n }, []);\n onCompRender(result);\n return React.createElement(\"h1\", null, `Hello`);\n };\n root.render(React.createElement(BasicComponent, { props: rootArgs.initialProps }, null));\n });\n};\n\nexport const renderReactHook = (rootArgs: RenderHookArgs): Promise<RenderResult> => {\n const {\n hook,\n props,\n onResult,\n expectedRerenders,\n timeout = 5000,\n lastRenderWait = 250,\n } = rootArgs;\n const isRerender = testedHook && testedHook === hook;\n if (testedHook && testedHook !== hook) {\n resetBasicComponent();\n }\n testedHook = hook;\n let lastRenderWaitTimeout: NodeJS.Timeout | null = null;\n return new Promise((resolve, reject) => {\n const results: any[] = [];\n let resolved = false;\n const onRender = (result) => {\n results.push(result);\n onResult?.(result);\n clearTimeout(lastRenderWaitTimeout);\n resolved = expectedRerenders === results.length;\n if (resolved) {\n lastRenderWaitTimeout = setTimeout(() => {\n resolve({\n results,\n rerender: (args: Omit<RenderHookArgs, \"hook\">) =>\n renderReactHook({\n hook,\n ...args,\n }),\n });\n }, lastRenderWait);\n }\n };\n reactRender({\n hook,\n props,\n onResult: onRender,\n onUnmount: () => {\n if (isRerender) {\n reject(new Error(\"Unmounted before expected rerenders\"));\n }\n },\n });\n setTimeout(() => {\n if (!resolved) {\n reject(\n new Error(\n `Expected ${expectedRerenders} rerenders, got ${results.length}:\\n${JSON.stringify(results)}`,\n ),\n );\n }\n }, timeout);\n });\n};\n\nconst tout = (ms: number) => new Promise((res) => setTimeout(res, ms));\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/client/useProstgles.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":17,"column":46,"nodeType":"Identifier","messageId":"unusedVar","endLine":17,"endColumn":47},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":19,"column":45,"nodeType":"Identifier","messageId":"unusedVar","endLine":19,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe array destructuring of an `any` array value.","line":21,"column":18,"nodeType":"ArrayPattern","messageId":"unsafeArrayPattern","endLine":21,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .db on an `any` value.","line":28,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":28,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .db on an `any` value.","line":29,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":29,"endColumn":35},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":32,"column":64,"nodeType":"Identifier","messageId":"unusedVar","endLine":32,"endColumn":65},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'onRender' has no 'await' expression.","line":38,"column":9,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":38,"endColumn":25,"suggestions":[{"messageId":"removeAsync","fix":{"range":[1540,1546],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":40,"column":11,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":40,"endColumn":67,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[1615,1615],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[1615,1615],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":48,"column":35,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":48,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2017,2019],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":48,"column":60,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":48,"endColumn":62,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2042,2044],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":50,"column":35,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":50,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2147,2149],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":53,"column":35,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":53,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2273,2275],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":59,"column":63,"nodeType":"Identifier","messageId":"unusedVar","endLine":59,"endColumn":64},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'onEnd' has no 'await' expression.","line":63,"column":9,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":63,"endColumn":22,"suggestions":[{"messageId":"removeAsync","fix":{"range":[2606,2612],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/await-thenable","severity":1,"message":"Unexpected `await` of a non-Promise (non-\"Thenable\") value.","line":67,"column":7,"nodeType":"AwaitExpression","messageId":"await","endLine":87,"endColumn":9,"suggestions":[{"messageId":"removeAwait","fix":{"range":[2737,2742],"text":""},"desc":"Remove unnecessary `await`."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":80,"column":35,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":80,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3255,3257],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":85,"column":59,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":85,"endColumn":61,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3465,3467],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/await-thenable","severity":1,"message":"Unexpected `await` of a non-Promise (non-\"Thenable\") value.","line":89,"column":7,"nodeType":"AwaitExpression","messageId":"await","endLine":104,"endColumn":9,"suggestions":[{"messageId":"removeAwait","fix":{"range":[3518,3523],"text":""},"desc":"Remove unnecessary `await`."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'res1' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":92,"column":18,"nodeType":"Identifier","messageId":"unusedVar","endLine":92,"endColumn":22},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'res2' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":92,"column":24,"nodeType":"Identifier","messageId":"unusedVar","endLine":92,"endColumn":28},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'res3' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":92,"column":30,"nodeType":"Identifier","messageId":"unusedVar","endLine":92,"endColumn":34},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'res4' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":92,"column":36,"nodeType":"Identifier","messageId":"unusedVar","endLine":92,"endColumn":40}],"suppressedMessages":[],"errorCount":10,"fatalErrorCount":0,"warningCount":13,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { strict as assert } from \"assert\";\nimport { describe, test } from \"node:test\";\nimport { useProstglesClient, type UseProstglesClientProps } from \"prostgles-client\";\nimport type { DBHandlerClient } from \"./index\";\nimport { renderReactHook, renderReactHookManual } from \"./renderReactHook\";\nimport type { SQLHandler } from \"prostgles-types\";\n\nexport const newly_created_table = \"newly_created_table\";\nexport const useProstglesTest = async (\n db: DBHandlerClient,\n sql: SQLHandler,\n getSocketOptions: (watchSchema?: boolean) => UseProstglesClientProps,\n) => {\n await sql(`DROP TABLE IF EXISTS ${newly_created_table};`);\n /** Wait for schema changes to propagate */\n await sql(`select pg_sleep(3);`);\n await describe(\"useProstgles hook\", async (t) => {\n const clientOptions = getSocketOptions();\n await test(\"useProstglesClient\", async (t) => {\n const {\n results: [res1, res2],\n } = await renderReactHook({\n hook: useProstglesClient,\n props: [clientOptions],\n expectedRerenders: 2,\n });\n assert.deepStrictEqual(res1, { isLoading: true, hasError: false });\n assert.equal(typeof res2?.db.items4.useFind, \"function\");\n assert.equal(typeof res2?.db[newly_created_table], \"undefined\");\n });\n\n await test(\"useProstglesClient with schema reload\", async (t) => {\n await sql(`select pg_sleep(1)`);\n await renderReactHookManual({\n hook: useProstglesClient,\n initialProps: [getSocketOptions(true)],\n renderDuration: 1000,\n onRender: async (results) => {\n if (results.length !== 1) return;\n sql(`CREATE TABLE ${newly_created_table}(id integer);`);\n },\n onEnd: async (results) => {\n const [res1, res2, res3] = results;\n assert.deepStrictEqual(res1, { isLoading: true, hasError: false });\n assert.equal(res2.isLoading, false);\n assert.equal(res2.hasError, false);\n assert.equal(res3.isLoading, false);\n assert.equal(typeof res2?.db[newly_created_table]?.useFind, \"undefined\");\n assert.equal(res3.hasError, false);\n assert.equal(typeof res3?.db[newly_created_table].useFind, \"function\");\n assert.equal(results.length, 3);\n\n const count = await res3?.db[newly_created_table].count();\n assert.equal(count, 0);\n },\n });\n });\n\n await test(\"useProstglesClient with initial skip\", async (t) => {\n const { setProps } = await renderReactHookManual({\n hook: useProstglesClient,\n initialProps: [{ ...clientOptions, skip: true }],\n onEnd: async (results) => {\n assert.deepStrictEqual(results, [{ isLoading: true, hasError: false }]);\n },\n });\n await setProps([clientOptions], {\n onEnd: async (results) => {\n assert.equal(results.length, 3);\n const [res1, res2, res3] = results;\n assert.deepStrictEqual(\n [res1, res2],\n [\n { isLoading: true, hasError: false },\n { isLoading: true, hasError: false },\n ],\n );\n if (res3.isLoading) throw \"Still loading\";\n if (res3.hasError || !(\"db\" in res3)) throw res3.error;\n const count = await res3?.db.items4.count();\n assert.equal(count, 0);\n\n assert.equal(res3.isLoading, false);\n if (\"error\" in res3) throw res3.error;\n assert.equal(typeof res3.db[newly_created_table]?.useFind, \"undefined\");\n },\n });\n\n await setProps([getSocketOptions(true)], {\n onEnd: async (results) => {\n assert.equal(results.length, 5);\n const [res1, res2, res3, res4, res5] = results;\n assert.equal(results.length, 5);\n assert.equal(res5.isLoading, false);\n if (\"error\" in res5) throw res5.error;\n\n const count = await res5.db.items4.count();\n assert.equal(count, 0);\n\n assert.equal(typeof res5.db[newly_created_table].useFind, \"function\");\n const count0 = await res5.db[newly_created_table].count();\n assert.equal(count0, 0);\n },\n });\n });\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/clientFileTests.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":10,"column":31,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":10,"endColumn":33,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[452,454],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":11,"column":14,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":11,"endColumn":16,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[536,538],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":31,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":31,"endColumn":41,"fix":{"range":[1149,1150],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":41,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":41,"endColumn":62,"fix":{"range":[1480,1481],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":45,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":45,"endColumn":41,"fix":{"range":[1607,1608],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":47,"column":53,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":47,"endColumn":55},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":52,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":52,"endColumn":53,"fix":{"range":[2008,2009],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":67,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":67,"endColumn":31,"fix":{"range":[2528,2529],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":70,"column":22,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":70,"endColumn":44},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .message on an `any` value.","line":70,"column":26,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":70,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":80,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":80,"endColumn":44,"fix":{"range":[3081,3082],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":81,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":81,"endColumn":55,"fix":{"range":[3164,3165],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":82,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":82,"endColumn":44,"fix":{"range":[3244,3245],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":92,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":92,"endColumn":45,"fix":{"range":[3556,3557],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":114,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":114,"endColumn":37,"fix":{"range":[4292,4293],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":118,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":118,"endColumn":32},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":124,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":124,"endColumn":25,"fix":{"range":[4533,4534],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":141,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":141,"endColumn":29,"fix":{"range":[5107,5108],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":142,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":142,"endColumn":44,"fix":{"range":[5186,5187],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":145,"column":27,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":145,"endColumn":29,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[5291,5293],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":158,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":158,"endColumn":53,"fix":{"range":[5868,5869],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":163,"column":39,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":163,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":167,"column":40,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":167,"endColumn":48},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":185,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":185,"endColumn":29,"fix":{"range":[6871,6872],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":186,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":186,"endColumn":55,"fix":{"range":[6929,6930],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":191,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":191,"endColumn":51,"fix":{"range":[7111,7112],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":192,"column":19,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":192,"endColumn":21,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7132,7134],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":196,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":196,"endColumn":41},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":196,"column":26,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":196,"endColumn":28,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7231,7233],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":196,"column":33,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":196,"endColumn":35,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7238,7240],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":197,"column":48,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":197,"endColumn":50,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7295,7297],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":197,"column":67,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":197,"endColumn":69},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":198,"column":69,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":198,"endColumn":71,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7389,7391],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":203,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":203,"endColumn":53,"fix":{"range":[7614,7615],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":205,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":205,"endColumn":31,"fix":{"range":[7682,7683],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":205,"column":50,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":205,"endColumn":52},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":206,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":206,"endColumn":43,"fix":{"range":[7750,7751],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":209,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":209,"endColumn":41,"fix":{"range":[7818,7819],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":210,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":210,"endColumn":41,"fix":{"range":[7862,7863],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":212,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":212,"endColumn":59,"fix":{"range":[7965,7966],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":214,"column":32,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":214,"endColumn":34,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[8050,8052],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":214,"column":53,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":214,"endColumn":55,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[8071,8073],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":34,"fatalErrorCount":0,"warningCount":9,"fixableErrorCount":23,"fixableWarningCount":0,"source":"import { strict as assert } from \"assert\";\nimport fs from \"fs\";\nimport { describe, test } from \"node:test\";\nimport type { DBHandlerClient } from \"./client\";\nimport type { AnyObject, SQLHandler } from \"prostgles-types\";\n\nexport const clientFileTests = async (db: DBHandlerClient, sql: SQLHandler) => {\n await describe(\"clientFileTests\", async () => {\n const fileFolder = `${__dirname}/../../server/dist/server/media/`;\n const getFiles = () => sql?.(\"SELECT id, original_name FROM files\", {}, { returnType: \"rows\" });\n await sql?.(\n `\n ALTER TABLE users_public_info \n DROP CONSTRAINT \"users_public_info_avatar_fkey\";\n\n ALTER TABLE \"users_public_info\"\n ADD FOREIGN KEY (\"avatar\")\n REFERENCES \"files\" (\"id\")\n ON DELETE SET NULL\n `,\n {},\n );\n const initialFiles = await getFiles();\n\n /**\n * Although only users_public_info is published,\n * file table should show because it is referenced by users_public_info\n * and show only show files that are referenced by users_public_info\n */\n await test(\"Files table is present\", async () => {\n const files = await db.files.find!();\n assert.deepStrictEqual(files, []);\n });\n\n const file = {\n data: Buffer.from(\"This is a string\", \"utf-8\"),\n original_name: \"sample_file.txt\",\n };\n let insertedFile: AnyObject;\n await test(\"Insert file from nested insert\", async () => {\n const nestedInsert = await db.users_public_info.insert!(\n { name: \"somename.txt\", avatar: file },\n { returning: \"*\" },\n );\n const files = await db.files.find!();\n assert.equal(files.length, 1);\n assert.equal(files[0].id, nestedInsert.avatar.id);\n assert.equal(files[0].original_name, file.original_name);\n const initialFileStr = fs.readFileSync(fileFolder + files[0].storage_key).toString(\"utf8\");\n assert.equal(file.data.toString(), initialFileStr);\n insertedFile = files[0];\n const versions = await db.files_versions.find!({\n file_id: insertedFile.id,\n });\n assert.equal(versions.length, 1);\n assert.equal(versions[0].version, 1);\n assert.deepEqual(versions[0].metadata, {\n description: \"Updated by afterEach hook\",\n });\n assert.equal(db.files_versions.insert, undefined);\n assert.equal(db.files_versions.update, undefined);\n assert.equal(db.files_versions.delete, undefined);\n });\n\n await test(\"Cannot Insert file directly\", async () => {\n try {\n await db.files.insert!(file, { returning: \"*\" });\n throw \"Should not be able to insert files directly\";\n } catch (err: any) {\n assert.equal(err.message.startsWith(\"Direct inserts not allowed\"), true);\n }\n });\n\n await test(\"Disallowed updates cannot change stored bytes or create nested uploads\", async () => {\n const before = fs.readdirSync(fileFolder).sort();\n await sql(\"UPDATE users_public_info SET sid = 'another-user' WHERE avatar = $1\", [\n insertedFile.id,\n ]);\n try {\n assert.ok(!(await db.files.findOne!({ id: insertedFile.id })));\n assert.deepEqual(await db.files_versions.find!({ file_id: insertedFile.id }), []);\n const rows = await db.files.update!(\n { id: insertedFile.id },\n {\n data: Buffer.from(\"unauthorized replacement\"),\n original_name: \"forbidden.txt\",\n },\n { returning: \"*\" },\n );\n assert.deepEqual(rows, []);\n assert.deepEqual(\n await db.users_public_info.update!(\n { avatar: insertedFile.id },\n { avatar: file },\n { returning: \"*\" },\n ),\n [],\n );\n assert.equal(\n fs.readFileSync(fileFolder + insertedFile.storage_key, \"utf8\"),\n file.data.toString(),\n );\n assert.deepEqual(fs.readdirSync(fileFolder).sort(), before);\n } finally {\n await sql(\"UPDATE users_public_info SET sid = 'files' WHERE avatar = $1\", [\n insertedFile.id,\n ]);\n }\n });\n\n await test(\"Duplicate file IDs and failed validation preserve the original object\", async () => {\n const before = fs.readdirSync(fileFolder).sort();\n await assert.rejects(() =>\n db.users_public_info.insert!({\n name: \"duplicate\",\n avatar: {\n ...file,\n id: insertedFile.id,\n data: Buffer.from(\"collision\"),\n },\n }),\n );\n await assert.rejects(() =>\n db.files.update!(\n { id: insertedFile.id },\n { data: Buffer.from(\"invalid\"), original_name: \"missing-extension\" },\n ),\n );\n assert.equal(\n fs.readFileSync(fileFolder + insertedFile.storage_key, \"utf8\"),\n file.data.toString(),\n );\n assert.deepEqual(fs.readdirSync(fileFolder).sort(), before);\n });\n\n await test(\"Can update allowed files directly\", async () => {\n const newData = {\n data: Buffer.from(\"# Replacement markdown\", \"utf-8\"),\n original_name: \"replacement.md\",\n };\n await db.files.update!({ id: insertedFile.id }, newData);\n const newFiles = await db.files.find!();\n assert.equal(newFiles.length, 1);\n const [newFile] = newFiles;\n assert.equal(newFile?.original_name, newData.original_name);\n assert.equal(newFile.id, insertedFile.id);\n assert.equal(newFile.content_type, \"text/markdown\");\n assert.equal(newFile.extension, \"md\");\n assert.equal(\n fs\n .readFileSync(fileFolder + newFile.storage_key)\n .toString(\"utf8\")\n .toString(),\n newData.data.toString(),\n );\n assert.notEqual(newFile.storage_key, insertedFile.storage_key);\n assert.equal(fs.existsSync(fileFolder + insertedFile.storage_key), true);\n const versions = await db.files_versions.find!(\n { file_id: insertedFile.id },\n { orderBy: \"version\" },\n );\n assert.deepEqual(\n versions.map(({ version }) => version),\n [1, 2],\n );\n assert.deepEqual(\n versions.map(({ metadata }) => metadata),\n Array(2).fill({ description: \"Updated by afterEach hook\" }),\n );\n const previousFile = await fetch(`http://localhost:3001${versions[0].url}`, {\n headers: {\n Authorization: `Bearer ${Buffer.from(\"files\").toString(\"base64\")}`,\n },\n });\n assert.equal(await previousFile.text(), file.data.toString());\n const disallowedPreviousFile = await fetch(`http://localhost:3001${versions[0].url}`, {\n headers: {\n Authorization: `Bearer ${Buffer.from(\"files_versions_denied\").toString(\"base64\")}`,\n },\n });\n assert.equal(disallowedPreviousFile.status, 404);\n });\n\n await test(\"Can insert allowed files through a nested update\", async () => {\n await db.files.delete!();\n const user = await db.users_public_info.findOne!();\n const newData = {\n data: Buffer.from(\"nestedupdate\", \"utf-8\"),\n original_name: \"nestedupdate.txt\",\n };\n const d = await db.users_public_info.update!(\n { id: user?.id },\n { avatar: newData },\n { returning: \"*\" },\n );\n const avatarRow = d?.at(0)?.avatar;\n const avatarFile = await db.files.findOne?.({ id: avatarRow.id });\n const initialFileStr = fs.readFileSync(fileFolder + avatarFile?.storage_key).toString(\"utf8\");\n assert.equal(newData.data.toString(), initialFileStr);\n });\n\n await test(\"Can delete only allowed files directly\", async () => {\n const users = await db.users_public_info.find!();\n for (const user of users) {\n await db.files.delete!({ id: user.avatar.id });\n await db.users_public_info.delete!({ id: user.id });\n }\n\n await db.users_public_info.delete!();\n const files = await db.files.find!();\n assert.deepStrictEqual(files, []);\n assert.deepStrictEqual(await db.files_versions.find!(), []);\n const latestFiles = await getFiles();\n assert.equal(initialFiles?.length, latestFiles?.length);\n });\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/clientOnlyQueries.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"Imports \"AnyObject\", \"DBSchemaTable\" and \"SocketSQLStreamPacket\" are only used as type.","line":3,"column":1,"nodeType":"ImportDeclaration","messageId":"someImportsAreOnlyTypes","endLine":10,"endColumn":26,"fix":{"range":[87,150],"text":"import type {\n AnyObject,\n DBSchemaTable,\n SocketSQLStreamPacket} from \"prostgles-types\";\nimport {"}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'t' is defined but never used. Allowed unused args must match /^_/u.","line":24,"column":48,"nodeType":"Identifier","messageId":"unusedVar","endLine":24,"endColumn":49},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":31,"column":31,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":31,"endColumn":33,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1069,1071],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":31,"column":49,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":31,"endColumn":51,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1087,1089],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":32,"column":38,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":32,"endColumn":40,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1139,1141],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":32,"column":56,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":32,"endColumn":58,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1157,1159],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":34,"column":35,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":34,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1217,1219],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":39,"column":28,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":39,"endColumn":30,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1448,1450],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":39,"column":46,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":39,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1466,1468],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":40,"column":35,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":40,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1515,1517],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":40,"column":53,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":40,"endColumn":55,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1533,1535],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":42,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":42,"endColumn":45,"fix":{"range":[1603,1604],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":57,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":57,"endColumn":51,"fix":{"range":[2179,2180],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":77,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":77,"endColumn":31,"fix":{"range":[2981,2982],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function 'listener' has no 'await' expression.","line":82,"column":64,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":82,"endColumn":66,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3137,3143],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":84,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":84,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":86,"column":17,"nodeType":"MemberExpression","messageId":"alwaysTruthy","endLine":86,"endColumn":28},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe spread of an `any` value in an array.","line":87,"column":23,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":87,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe spread of an `any` value in an array.","line":87,"column":32,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":87,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":92,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":92,"endColumn":22},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":105,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":105,"endColumn":31,"fix":{"range":[3945,3946],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function 'listener' has no 'await' expression.","line":110,"column":64,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":110,"endColumn":66,"suggestions":[{"messageId":"removeAsync","fix":{"range":[4095,4101],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":113,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":113,"endColumn":21},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator. A rejection handler that is not a function will be ignored.","line":120,"column":17,"nodeType":"ExpressionStatement","messageId":"floatingUselessRejectionHandlerVoid","endLine":120,"endColumn":78,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[4530,4530],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[4530,4530],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `(reason: any) => PromiseLike<never>`.","line":120,"column":70,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":120,"endColumn":76},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [0] on an `any` value.","line":125,"column":45,"nodeType":"Literal","messageId":"unsafeMemberExpression","endLine":125,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":126,"column":17,"nodeType":"Identifier","messageId":"unsafeCall","endLine":126,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":130,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":130,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":140,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":140,"endColumn":31,"fix":{"range":[5329,5330],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function 'listener' has no 'await' expression.","line":142,"column":64,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":142,"endColumn":66,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5460,5466],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":144,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":144,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":149,"column":19,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":149,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [0] on an `any` value.","line":149,"column":40,"nodeType":"Literal","messageId":"unsafeMemberExpression","endLine":149,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `number`.","line":150,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":150,"endColumn":26},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator. A rejection handler that is not a function will be ignored.","line":152,"column":15,"nodeType":"ExpressionStatement","messageId":"floatingUselessRejectionHandlerVoid","endLine":152,"endColumn":53,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[5861,5861],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[5861,5861],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `(reason: any) => PromiseLike<never>`.","line":152,"column":45,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":152,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":156,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":156,"endColumn":22},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":167,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":167,"endColumn":31,"fix":{"range":[6335,6336],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":170,"column":38,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":170,"endColumn":42,"fix":{"range":[6524,6525],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .message on an `any` value.","line":177,"column":39,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":177,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":178,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":178,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":183,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":183,"endColumn":19},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator. A rejection handler that is not a function will be ignored.","line":188,"column":11,"nodeType":"ExpressionStatement","messageId":"floatingUselessRejectionHandlerVoid","endLine":188,"endColumn":45,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[7229,7229],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[7229,7229],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `(reason: any) => PromiseLike<never>`.","line":188,"column":37,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":188,"endColumn":43},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":195,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":195,"endColumn":31,"fix":{"range":[7438,7439],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function 'listener' has no 'await' expression.","line":200,"column":64,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":200,"endColumn":66,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7595,7601],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":202,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":202,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":207,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":207,"endColumn":20},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":221,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":221,"endColumn":33,"fix":{"range":[8310,8311],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":226,"column":40,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":226,"endColumn":44,"fix":{"range":[8578,8579],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":232,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":232,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":235,"column":35,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":235,"endColumn":49},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":240,"column":17,"nodeType":"Identifier","messageId":"unsafeCall","endLine":240,"endColumn":23},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator. A rejection handler that is not a function will be ignored.","line":246,"column":13,"nodeType":"ExpressionStatement","messageId":"floatingUselessRejectionHandlerVoid","endLine":246,"endColumn":51,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[9280,9280],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[9280,9280],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `(reason: any) => PromiseLike<never>`.","line":246,"column":43,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":246,"endColumn":49},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":256,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":256,"endColumn":35,"fix":{"range":[9573,9574],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function 'listener' has no 'await' expression.","line":262,"column":68,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":262,"endColumn":70,"suggestions":[{"messageId":"removeAsync","fix":{"range":[9783,9789],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":264,"column":17,"nodeType":"Identifier","messageId":"unsafeCall","endLine":264,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":269,"column":19,"nodeType":"Identifier","messageId":"unsafeCall","endLine":269,"endColumn":26},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":280,"column":49,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":280,"endColumn":51,"suggestions":[{"messageId":"removeAsync","fix":{"range":[10340,10346],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":283,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":283,"endColumn":35,"fix":{"range":[10498,10499],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function 'listener' has no 'await' expression.","line":284,"column":68,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":284,"endColumn":70,"suggestions":[{"messageId":"removeAsync","fix":{"range":[10589,10595],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":291,"column":17,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":291,"endColumn":28},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator. A rejection handler that is not a function will be ignored.","line":299,"column":11,"nodeType":"ExpressionStatement","messageId":"floatingUselessRejectionHandlerVoid","endLine":306,"endColumn":28,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[11100,11100],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[11100,11100],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":303,"column":17,"nodeType":"Identifier","messageId":"unsafeCall","endLine":303,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `(reason: any) => PromiseLike<never>`.","line":306,"column":20,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":306,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":313,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":313,"endColumn":31,"fix":{"range":[11577,11578],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":316,"column":19,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":316,"endColumn":80},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":316,"column":42,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":316,"endColumn":46,"fix":{"range":[11748,11749],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":316,"column":76,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":316,"endColumn":79},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .message on an `any` value.","line":318,"column":39,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":318,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":320,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":320,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":322,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":322,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":331,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":331,"endColumn":31,"fix":{"range":[12353,12354],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":334,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":334,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":340,"column":37,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":340,"endColumn":41,"fix":{"range":[12765,12766],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":353,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":353,"endColumn":20},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":362,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":362,"endColumn":19,"fix":{"range":[13503,13504],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":363,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":363,"endColumn":19,"fix":{"range":[13572,13573],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":364,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":364,"endColumn":31,"fix":{"range":[13661,13662],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":367,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":367,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":372,"column":37,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":372,"endColumn":41,"fix":{"range":[14061,14062],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":373,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":373,"endColumn":23,"fix":{"range":[14121,14122],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":376,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":376,"endColumn":20},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":384,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":384,"endColumn":31,"fix":{"range":[14535,14536],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":387,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":387,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":392,"column":37,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":392,"endColumn":41,"fix":{"range":[14950,14951],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":393,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":393,"endColumn":23,"fix":{"range":[14995,14996],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":396,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":396,"endColumn":20},{"ruleId":"no-extra-boolean-cast","severity":2,"message":"Redundant double negation.","line":414,"column":18,"nodeType":"UnaryExpression","messageId":"unexpectedNegation","endLine":414,"endColumn":47,"fix":{"range":[15787,15816],"text":"h.getColumns && h.getInfo"}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":414,"column":21,"nodeType":"MemberExpression","messageId":"alwaysTruthy","endLine":414,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":414,"column":37,"nodeType":"MemberExpression","messageId":"alwaysTruthy","endLine":414,"endColumn":46},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":422,"column":11,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":422,"endColumn":29},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":427,"column":38,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":427,"endColumn":40,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[16480,16482],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":427,"column":50,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":427,"endColumn":52,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[16492,16494],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":428,"column":38,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":428,"endColumn":40,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[16535,16537],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":428,"column":47,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":428,"endColumn":49,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[16544,16546],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":430,"column":80,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":430,"endColumn":85,"fix":{"range":[16682,16683],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":440,"column":17,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":440,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":451,"column":26,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":451,"endColumn":50},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":451,"column":40,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":451,"endColumn":42,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[17395,17397],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .join on an `any` value.","line":451,"column":46,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":451,"endColumn":50},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":453,"column":31,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":453,"endColumn":33,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[17510,17512],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":487,"column":17,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":487,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":496,"column":17,"nodeType":"Identifier","messageId":"unsafeCall","endLine":496,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":502,"column":41,"nodeType":"Identifier","messageId":"unsafeCall","endLine":502,"endColumn":48},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":504,"column":19,"nodeType":"Identifier","messageId":"unsafeCall","endLine":504,"endColumn":25},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":508,"column":15,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":508,"endColumn":46,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[19397,19397],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[19397,19397],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":510,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":510,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":517,"column":19,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":517,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .message on an `any` value.","line":523,"column":28,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":523,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":523,"column":50,"nodeType":"Identifier","messageId":"unsafeCall","endLine":523,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":525,"column":19,"nodeType":"Identifier","messageId":"unsafeCall","endLine":525,"endColumn":25},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":529,"column":15,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":536,"endColumn":14,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[20121,20121],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[20121,20121],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":545,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":545,"endColumn":34,"fix":{"range":[20423,20424],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":546,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":546,"endColumn":21,"fix":{"range":[20447,20448],"text":""}},{"ruleId":"prefer-const","severity":2,"message":"'inserts' is never reassigned. Use 'const' instead.","line":547,"column":15,"nodeType":"Identifier","messageId":"useConst","endLine":547,"endColumn":22,"fix":{"range":[20509,20684],"text":"const inserts = new Array(100).fill(null).map((d, i) => ({\n id: i,\n flight_number: `FN${i}`,\n x: Math.random(),\n y: i,\n }));"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":553,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":553,"endColumn":34,"fix":{"range":[20717,20718],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":557,"column":22,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":557,"endColumn":38,"fix":{"range":[20803,20804],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":570,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":570,"endColumn":48,"fix":{"range":[21389,21390],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":570,"column":79,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":570,"endColumn":81,"suggestions":[{"messageId":"removeAsync","fix":{"range":[21406,21412],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":591,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":591,"endColumn":40,"fix":{"range":[22368,22369],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":592,"column":65,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":592,"endColumn":81,"fix":{"range":[22479,22480],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'updateCount' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":599,"column":15,"nodeType":"Identifier","messageId":"unusedVar","endLine":599,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":600,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":600,"endColumn":45,"fix":{"range":[22716,22717],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'deltas' is defined but never used. Allowed unused args must match /^_/u.","line":600,"column":84,"nodeType":"Identifier","messageId":"unusedVar","endLine":600,"endColumn":90},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'update' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":605,"column":17,"nodeType":"Identifier","messageId":"unusedVar","endLine":605,"endColumn":23},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":612,"column":17,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":612,"endColumn":39,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[23253,23253],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[23253,23253],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":612,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":612,"endColumn":27,"fix":{"range":[23262,23263],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":634,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":634,"endColumn":42,"fix":{"range":[24001,24002],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":635,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":635,"endColumn":42,"fix":{"range":[24055,24056],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":636,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":636,"endColumn":47,"fix":{"range":[24114,24115],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":639,"column":24,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":639,"endColumn":26,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[24227,24229],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":640,"column":24,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":640,"endColumn":26,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[24296,24298],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":641,"column":27,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":641,"endColumn":29,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[24368,24370],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":641,"column":39,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":641,"endColumn":41,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[24380,24382],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":649,"column":13,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":649,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":662,"column":28,"nodeType":"MemberExpression","messageId":"alwaysTruthy","endLine":662,"endColumn":37},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":667,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":667,"endColumn":39,"fix":{"range":[25236,25237],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":673,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":673,"endColumn":49,"fix":{"range":[25446,25447],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":687,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":690,"endColumn":32},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":687,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":687,"endColumn":52,"fix":{"range":[25828,25829],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":690,"column":26,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":690,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":691,"column":20,"nodeType":"LogicalExpression","messageId":"unsafeArgument","endLine":691,"endColumn":64},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .message on an `any` value.","line":691,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":691,"endColumn":40},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":693,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":693,"endColumn":53,"fix":{"range":[26103,26104],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":702,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":702,"endColumn":52,"fix":{"range":[26380,26381],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":706,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":706,"endColumn":50,"fix":{"range":[26579,26580],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":707,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":707,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":710,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":710,"endColumn":38,"fix":{"range":[26723,26724],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":711,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":711,"endColumn":38,"fix":{"range":[26803,26804],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":712,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":712,"endColumn":38,"fix":{"range":[26880,26881],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'err' is defined but never used. Allowed unused caught errors must match /^_/u.","line":714,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":714,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":715,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":715,"endColumn":53,"fix":{"range":[27056,27057],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":718,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":718,"endColumn":39,"fix":{"range":[27172,27173],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":723,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":723,"endColumn":39,"fix":{"range":[27307,27308],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":728,"column":16,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":728,"endColumn":18,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[27436,27438],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":729,"column":25,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":729,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":733,"column":54,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":733,"endColumn":56,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[27674,27676],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":733,"column":85,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":733,"endColumn":88},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":806,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":806,"endColumn":42,"fix":{"range":[30048,30049],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'deltas' is defined but never used. Allowed unused args must match /^_/u.","line":806,"column":88,"nodeType":"Identifier","messageId":"unusedVar","endLine":806,"endColumn":94},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":806,"column":96,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":806,"endColumn":98,"suggestions":[{"messageId":"removeAsync","fix":{"range":[30079,30085],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":811,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":811,"endColumn":42,"fix":{"range":[30269,30270],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'deltas' is defined but never used. Allowed unused args must match /^_/u.","line":811,"column":83,"nodeType":"Identifier","messageId":"unusedVar","endLine":811,"endColumn":89},{"ruleId":"@typescript-eslint/await-thenable","severity":1,"message":"Unexpected `await` of a non-Promise (non-\"Thenable\") value.","line":818,"column":7,"nodeType":"AwaitExpression","messageId":"await","endLine":818,"endColumn":28,"suggestions":[{"messageId":"removeAwait","fix":{"range":[30578,30583],"text":""},"desc":"Remove unnecessary `await`."}]},{"ruleId":"@typescript-eslint/await-thenable","severity":1,"message":"Unexpected `await` of a non-Promise (non-\"Thenable\") value.","line":819,"column":7,"nodeType":"AwaitExpression","messageId":"await","endLine":819,"endColumn":28,"suggestions":[{"messageId":"removeAwait","fix":{"range":[30607,30612],"text":""},"desc":"Remove unnecessary `await`."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":825,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":825,"endColumn":39,"fix":{"range":[30800,30801],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":831,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":831,"endColumn":28,"fix":{"range":[30961,30962],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":833,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":833,"endColumn":57,"fix":{"range":[31070,31071],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":841,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":841,"endColumn":57,"fix":{"range":[31347,31348],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'reject' is defined but never used. Allowed unused args must match /^_/u.","line":853,"column":38,"nodeType":"Identifier","messageId":"unusedVar","endLine":853,"endColumn":44},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":853,"column":46,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":853,"endColumn":48,"suggestions":[{"messageId":"removeAsync","fix":{"range":[31567,31573],"text":""},"desc":"Remove 'async'."}]}],"suppressedMessages":[],"errorCount":106,"fatalErrorCount":0,"warningCount":68,"fixableErrorCount":58,"fixableWarningCount":0,"source":"import { strict as assert } from \"assert\";\nimport { describe, test } from \"node:test\";\nimport {\n AnyObject,\n DBSchemaTable,\n SocketSQLStreamPacket,\n isDefined,\n omitKeys,\n type SQLHandler,\n} from \"prostgles-types\";\nimport type { AuthHandler, ClientFunctionHandler, DBHandlerClient } from \"./client\";\nimport type { GeneratedFunctionSchema } from \"./DBGeneratedSchema\";\nimport { tryRun, tryRunP } from \"./isomorphicQueries.spec\";\n\nexport const clientOnlyQueries = async (\n db: DBHandlerClient,\n sql: SQLHandler | undefined,\n auth: AuthHandler,\n log: (...args: any[]) => any,\n serverFunctions: ClientFunctionHandler,\n tableSchema: DBSchemaTable[],\n token: string,\n) => {\n await describe(\"Client only queries\", async (t) => {\n await test(\"modifyClientSchema adds custom table and column metadata\", async () => {\n const planesTable = tableSchema.find((table) => table.name === \"planes\") as\n | (DBSchemaTable & {\n clientSchemaTest?: { sid?: string; tableIndex: number };\n })\n | undefined;\n assert.equal(planesTable?.clientSchemaTest?.sid, token);\n assert.equal(typeof planesTable?.clientSchemaTest?.tableIndex, \"number\");\n\n const idColumn = planesTable?.columns.find((column) => column.name === \"id\") as\n | (DBSchemaTable[\"columns\"][number] & {\n clientSchemaTest?: { sid?: string; columnIndex: number };\n })\n | undefined;\n assert.equal(idColumn?.clientSchemaTest?.sid, token);\n assert.equal(typeof idColumn?.clientSchemaTest?.columnIndex, \"number\");\n\n const info = (await db.planes.getInfo!()) as Awaited<\n ReturnType<NonNullable<typeof db.planes.getInfo>>\n > & {\n clientSchemaTest: {\n sid?: string;\n passes: number;\n primaryKeys: string[];\n };\n };\n assert.equal(info.clientSchemaTest.sid, token);\n assert.equal(info.clientSchemaTest.passes, 1);\n assert.deepEqual(info.clientSchemaTest.primaryKeys, [\"id\"]);\n assert.equal(\"columns\" in info, false);\n\n // A language forces a server request instead of returning cached schema columns.\n const columns = (await db.planes.getColumns!(\"en\")) as (DBSchemaTable[\"columns\"][number] & {\n clientSchemaTest: { sid?: string; passes: number };\n })[];\n assert.ok(columns.length);\n for (const column of columns) {\n assert.equal(column.clientSchemaTest.sid, token);\n assert.equal(column.clientSchemaTest.passes, 1);\n }\n });\n\n // await test(\"Social auth redirect routes work\", async ( ) => {\n // assert.equal(!!auth.login.withProvider.github, true);\n // const response = await fetch(\"http://localhost:3001/auth/github\");\n // assert.equal(response.status, 302);\n // });\n\n await test(\"SQL Stream more than 1k records\", async () => {\n const expectedRowCount = 2e3;\n await tryRunP(\"\", async (resolve, reject) => {\n let rows: any[] = [];\n const res = await sql!(\n `SELECT * FROM generate_series(1, ${expectedRowCount})`,\n {},\n { returnType: \"stream\" },\n );\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n if (packet.rows) {\n rows = [...rows, ...packet.rows];\n }\n if (packet.ended) {\n assert.equal(packet.ended, true);\n assert.equal(rows.length, expectedRowCount);\n resolve(\"ok\");\n }\n }\n };\n await res.start(listener);\n });\n });\n\n await test(\"SQL Stream persistedConnection with streamLimit works for subsequent queries\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const query = \"SELECT * FROM generate_series(1, 100)\";\n let results: any[] = [];\n const streamLimit = 10;\n const res = await sql!(\n query,\n {},\n { returnType: \"stream\", persistStreamConnection: true, streamLimit },\n );\n const listener = async (packet: SocketSQLStreamPacket) => {\n try {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n results = results.concat(packet.rows);\n if (results.length === streamLimit) {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.equal(packet.rows.length, 10);\n startHandler.run(`SELECT '${query}' as query`).catch(reject);\n } else {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.equal(packet.rows.length, 1);\n assert.equal(packet.rows[0][0], query);\n resolve(\"ok\");\n }\n }\n } catch (err) {\n reject(err);\n }\n };\n const startHandler = await res.start(listener);\n });\n });\n\n await test(\"SQL Stream ensure the connection is never released (same pg_backend_pid is the same for subsequent) when using persistConnectionId\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const query = \"SELECT pg_backend_pid()\";\n const res = await sql!(query, {}, { returnType: \"stream\", persistStreamConnection: true });\n const pids: number[] = [];\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.equal(packet.rows.length, 1);\n const pid = packet.rows[0][0];\n pids.push(pid);\n if (pids.length === 1) {\n startHandler.run(query).catch(reject);\n }\n if (pids.length === 2) {\n assert.equal(pids[0], pids[1]);\n resolve(\"ok\");\n }\n }\n };\n const startHandler = await res.start(listener);\n });\n });\n\n await test(\"SQL Stream stop kills the query\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const query = \"SELECT * FROM pg_sleep(5)\";\n const res = await sql!(query, {}, { returnType: \"stream\" });\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n const queryState = await sql!(\n \"SELECT * FROM pg_stat_activity WHERE query = $1\",\n [query],\n { returnType: \"rows\" },\n );\n assert.equal(queryState.length, 1);\n assert.equal(queryState[0].state, \"idle\");\n assert.equal(packet.error.message, \"canceling statement due to user request\");\n resolve(\"ok\");\n } else {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.deepStrictEqual(packet.rows, [[\"\"]]);\n reject(\"SQL Stream stop kills the query\");\n }\n };\n const startHandler = await res.start(listener);\n setTimeout(() => {\n startHandler.stop().catch(reject);\n }, 1000);\n });\n });\n\n await test(\"SQL Stream limit works\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const res = await sql!(\n \"SELECT * FROM generate_series(1, 1e5)\",\n {},\n { returnType: \"stream\", streamLimit: 10 },\n );\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.equal(packet.rows.length, 10);\n resolve(\"ok\");\n }\n };\n await res.start(listener);\n });\n });\n\n await test(\n \"SQL Stream stop with terminate kills the query (expect flakiness)\",\n { timeout: 10_000 },\n async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const totalRows = 5e6;\n const query = `SELECT * FROM generate_series(1, ${totalRows})`;\n const res = await sql!(query, {}, { returnType: \"stream\" });\n const rowsReceived: any[] = [];\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n await tout(100);\n const queryState = await sql!(\n \"SELECT * FROM pg_stat_activity WHERE query = $1\",\n [query],\n { returnType: \"rows\" },\n );\n assert.deepStrictEqual(queryState, []);\n resolve(\"ok\");\n } else {\n try {\n rowsReceived.push(...packet.rows);\n console.log(rowsReceived.length);\n assert.equal(packet.ended, false);\n assert.equal(rowsReceived.length < totalRows, true);\n } catch (error) {\n reject(error);\n }\n }\n };\n const startHandler = await res.start(listener);\n setTimeout(() => {\n startHandler.stop(true).catch(reject);\n }, 22);\n });\n },\n );\n\n await test(\"SQL Stream\", async () => {\n await Promise.all(\n [1e3, 1e2].map(async (numberOfRows) => {\n await tryRunP(\"\", async (resolve, reject) => {\n const res = await sql!(\n `SELECT v.* FROM generate_series(1, ${numberOfRows}) v`,\n {},\n { returnType: \"stream\" },\n );\n let rows: any[] = [];\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n rows = rows.concat(packet.rows);\n if (packet.ended) {\n assert.equal(rows.length, numberOfRows);\n resolve(\"ok\");\n }\n }\n };\n await res.start(listener);\n });\n }),\n );\n });\n\n await test(\"SQL Stream parallel execution + parameters\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const getExpected = (val: string) =>\n new Promise(async (resolve, reject) => {\n const res = await sql!(\"SELECT ${val} as val\", { val }, { returnType: \"stream\" });\n const listener = async (packet: SocketSQLStreamPacket) => {\n try {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.deepStrictEqual(packet.rows, [[val]]);\n resolve(1);\n } catch (err) {\n reject(err);\n }\n };\n await res.start(listener);\n });\n let resolved = 0;\n const expected = [\"a\", \"b\", \"c\"];\n expected.forEach((val) => {\n getExpected(val)\n .then(() => {\n resolved++;\n if (resolved === expected.length) {\n resolve(\"ok\");\n }\n })\n .catch(reject);\n });\n });\n });\n await test(\"SQL Stream query error structure matches default sql run error\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const badQuery = \"SELECT * FROM not_existing_table\";\n const res = await sql!(badQuery, {}, { returnType: \"stream\" });\n const listener = async (packet: SocketSQLStreamPacket) => {\n try {\n const normalSqlError = await sql!(badQuery, {}).catch((err) => err);\n assert.equal(packet.type, \"error\");\n assert.equal(packet.error.message, 'relation \"not_existing_table\" does not exist');\n assert.deepEqual(packet.error, normalSqlError);\n resolve(\"ok\");\n } catch (err) {\n reject(err);\n }\n };\n await res.start(listener);\n });\n });\n await test(\"SQL Stream streamLimit\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const generate_series = \"SELECT * FROM generate_series(1, 100)\";\n const res = await sql!(generate_series, {}, { returnType: \"stream\", streamLimit: 10 });\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.equal(packet.rows.length, 10);\n\n const normalSql = await sql!(generate_series, {});\n\n /** fields the same as on normal sql request */\n assert.deepStrictEqual(packet.fields, normalSql.fields);\n\n /** result is rowMode=array */\n assert.equal(Array.isArray(packet.rows), true);\n assert.equal(Array.isArray(packet.rows[0]), true);\n\n assert.deepStrictEqual(\n packet.rows.flat(),\n Array.from({ length: 10 }, (_, i) => i + 1).flat(),\n );\n resolve(\"ok\");\n }\n };\n await res.start(listener);\n });\n });\n\n await test(\"SQL Stream table fields are the same as on default request\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n await sql!(\"TRUNCATE planes RESTART IDENTITY CASCADE;\", {});\n await sql!(\"INSERT INTO planes (last_updated) VALUES (56789);\", {});\n const res = await sql!(\"SELECT * FROM planes\", {}, { returnType: \"stream\" });\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.equal(packet.rows.length, 1);\n const normalSql = await sql!(\"SELECT * FROM planes LIMIT 1\", {});\n await sql!(\"DELETE FROM planes\", {});\n assert.deepStrictEqual(packet.fields, normalSql.fields);\n assert.equal(packet.fields.length > 0, true);\n resolve(\"ok\");\n }\n };\n await res.start(listener);\n });\n });\n await test(\"SQL Stream works for multiple statements\", async () => {\n await tryRunP(\"\", async (resolve, reject) => {\n const res = await sql!(\"SELECT * FROM planes; SELECT 1 as a\", {}, { returnType: \"stream\" });\n const listener = async (packet: SocketSQLStreamPacket) => {\n if (packet.type === \"error\") {\n reject(packet.error);\n } else {\n assert.equal(packet.type, \"data\");\n assert.equal(packet.ended, true);\n assert.equal(packet.rows.length, 1);\n const normalSql = await sql!(\"SELECT 1 as a\", {});\n await sql!(\"DELETE FROM planes\", {});\n assert.deepStrictEqual(packet.fields, normalSql.fields);\n assert.equal(packet.fields.length > 0, true);\n resolve(\"ok\");\n }\n };\n await res.start(listener);\n });\n });\n\n /**\n * tableSchema must contan an array of all tables and their columns that have getInfo and getColumns allowed\n */\n await test(\"Check tableSchema\", async () => {\n // Connection setup and direct requests apply customization different numbers of times.\n const withoutPassCount = ({ clientSchemaTest, ...info }: AnyObject) => ({\n ...info,\n clientSchemaTest: omitKeys(clientSchemaTest, [\"passes\"]),\n });\n const dbTables = Object.entries(db)\n .map(([k, h]) => {\n return !!(h.getColumns && h.getInfo) ? k : undefined;\n })\n .filter(isDefined);\n const missingTbl = dbTables.find((t) => !tableSchema.some((st) => st.name === t));\n if (missingTbl) {\n throw `${missingTbl} is missing from tableSchema: ${JSON.stringify(tableSchema)}`;\n }\n const missingSchemaTable = tableSchema.find((t) => !dbTables.includes(t.name));\n if (missingSchemaTable) {\n throw `${JSON.stringify([missingSchemaTable.name, missingSchemaTable.publishInfo])} is missing from db (${dbTables.join(\", \")})`;\n }\n await Promise.all(\n tableSchema.map(async ({ name, columns, ...otherInfo }) => {\n const cols = await db[name]?.getColumns?.();\n const info = await db[name]?.getInfo?.();\n assert.deepStrictEqual(columns, cols);\n assert.deepStrictEqual(withoutPassCount(otherInfo), withoutPassCount(info!));\n }),\n );\n });\n\n const testRealtime = () => {\n return new Promise(async (resolveTest, rejectTest) => {\n try {\n /* RAWSQL */\n await tryRun(\"SQL Full result\", async () => {\n if (!sql) throw \"sql missing\";\n const sqlStatement = await sql(\"SELECT $1\", [1], {\n returnType: \"statement\",\n });\n assert.equal(sqlStatement, \"SELECT 1\", \"sql statement query failed\");\n\n await sql(\"SELECT 1 -- ${param}\", {}, { hasParams: false });\n\n const arrayMode = await sql(\"SELECT 1 as a, 2 as a\", undefined, {\n returnType: \"arrayMode\",\n });\n assert.equal(arrayMode.rows?.[0].join(\".\"), \"1.2\", \"sql statement arrayMode failed\");\n assert.equal(\n arrayMode.fields?.map((f) => f.name).join(\".\"),\n \"a.a\",\n \"sql statement arrayMode failed\",\n );\n\n const select1 = await sql(\"SELECT $1 as col1\", [1], {\n returnType: \"rows\",\n });\n assert.deepStrictEqual(select1[0], { col1: 1 }, \"sql justRows query failed\");\n\n const fullResult = await sql(\"SELECT $1 as col1\", [1]);\n // console.log(fullResult)\n assert.deepStrictEqual(fullResult.rows[0], { col1: 1 }, \"sql query failed\");\n assert.deepStrictEqual(\n fullResult.fields,\n [\n {\n name: \"col1\",\n tableID: 0,\n columnID: 0,\n dataTypeID: 23,\n dataTypeSize: 4,\n dataTypeModifier: -1,\n format: \"text\",\n dataType: \"int4\",\n udt_name: \"int4\",\n tsDataType: \"number\",\n },\n ],\n \"sql query failed\",\n );\n });\n\n await tryRunP(\"sql LISTEN NOTIFY events\", async (resolve, reject) => {\n if (!sql) throw \"sql missing\";\n\n try {\n const sub = await sql(\n \"LISTEN chnl \",\n {},\n { allowListen: true, returnType: \"arrayMode\" },\n );\n if (!(\"addListener\" in sub)) {\n reject(\"addListener missing\");\n return;\n }\n\n sub.addListener((notif) => {\n const expected = \"hello\";\n if (notif === expected) resolve(true);\n else\n reject(\n `Notif value is not what we expect: ${JSON.stringify(notif)} is not ${JSON.stringify(expected)} (expected) `,\n );\n });\n sql(\"NOTIFY chnl , 'hello'; \");\n } catch (e) {\n reject(e);\n }\n });\n\n await tryRunP(\n \"sql NOTICE events\",\n async (resolve, reject) => {\n if (!sql) throw \"sql missing\";\n\n const sub = await sql(\"\", {}, { returnType: \"noticeSubscription\" });\n\n sub.addListener((notice) => {\n const expected = \"hello2\";\n if (notice.message === expected) resolve(true);\n else\n reject(\n `Notice value is not what we expect: ${JSON.stringify(notice)} is not ${JSON.stringify(expected)} (expected) `,\n );\n });\n sql(`\n DO $$ \n BEGIN\n\n RAISE NOTICE 'hello2';\n\n END $$;\n `);\n },\n { log },\n );\n\n /* REPLICATION */\n log(\"Started testRealtime\");\n const start = Date.now();\n\n await db.planes.delete!();\n await sql!(\"TRUNCATE planes RESTART IDENTITY CASCADE;\", {});\n let inserts = new Array(100).fill(null).map((d, i) => ({\n id: i,\n flight_number: `FN${i}`,\n x: Math.random(),\n y: i,\n }));\n await db.planes.insert!(inserts);\n\n const CLOCK_DRIFT = 2000;\n\n if ((await db.planes.count!()) !== 100) throw \"Not 100 planes\";\n\n /**\n * Two listeners are added at the same time to dbo.planes (which has 100 records):\n * subscribe({ x: 10 }\n * sync({}\n *\n * Then sync starts updating x to 10 for each record\n * subscribe waits for 100 records of x=10 and then updates everything to x=20\n * sync waits for 100 records of x=20 and finishes the test\n */\n\n /* After all sync records are updated to x10 here we'll update them to x20 */\n const sP = await db.planes.subscribe!({ x: 10 }, {}, async (planes) => {\n const p10 = planes.filter((p) => p.x == 10);\n log(\n Date.now() +\n \": sub stats: x10 -> \" +\n p10.length +\n \" x20 ->\" +\n planes.filter((p) => p.x == 20).length,\n );\n\n if (p10.length === 100) {\n /** 2 second delay to account for client-server clock drift */\n setTimeout(async () => {\n // db.planes.findOne({}, { select: { last_updated: \"$max\"}}).then(log);\n\n await sP.unsubscribe();\n log(Date.now() + \": sub: db.planes.update({}, { x: 20, last_updated });\");\n const dLastUpdated = Math.max(...p10.map((v) => +v.last_updated));\n const last_updated = Date.now();\n if (dLastUpdated >= last_updated)\n throw \"dLastUpdated >= last_updated should not happen\";\n await db.planes.update!({}, { x: 20, last_updated });\n log(Date.now() + \": sub: Updated to x20\", await db.planes.count!({ x: 20 }));\n\n // db.planes.findOne({}, { select: { last_updated: \"$max\"}}).then(log)\n }, CLOCK_DRIFT);\n }\n });\n\n let updateCount = 0;\n const sync = await db.planes.sync!({}, { handlesOnData: true }, (planes, deltas) => {\n const x20 = planes.filter((p) => p.x == 20).length;\n const x10 = planes.filter((p) => p.x == 10);\n log(Date.now() + `: sync stats: x10 -> ${x10.length} x20 -> ${x20}`);\n\n let update = false;\n planes.map((p) => {\n // if(p.y === 1) window.up = p;\n if (typeof p.x !== \"number\") log(typeof p.x);\n if (+p.x < 10) {\n updateCount++;\n update = true;\n p.$update!({ x: 10 });\n log(Date.now() + `: sync: p.$update({ x: 10 }); (id: ${p.id})`);\n }\n });\n // if(update) log(\"$update({ x: 10 })\", updt)\n\n if (x20 === 100) {\n // log(22)\n // console.timeEnd(\"test\")\n log(\n Date.now() +\n \": sync end: Finished replication test. Inserting 100 rows then updating two times took: \" +\n (Date.now() - start - CLOCK_DRIFT) +\n \"ms\",\n );\n resolveTest(true);\n }\n });\n\n const msLimit = 20000;\n setTimeout(async () => {\n const dbCounts = {\n x10: await db.planes.count!({ x: 10 }),\n x20: await db.planes.count!({ x: 20 }),\n latest: await db.planes.findOne!({}, { orderBy: { last_updated: -1 } }),\n };\n const syncCounts = {\n x10: sync?.getItems().filter((d) => d.x == 10).length,\n x20: sync?.getItems().filter((d) => d.x == 20).length,\n latest: sync?.getItems()?.sort((a, b) => +b.last_updated - +a.last_updated)[0],\n };\n const msg =\n \"Replication test failed due to taking longer than \" +\n msLimit +\n \"ms \\n \" +\n JSON.stringify({ dbCounts, syncCounts }, null, 2);\n log(msg);\n rejectTest(msg);\n }, msLimit);\n } catch (err) {\n log(JSON.stringify(err));\n await tout(1000);\n throw err;\n }\n });\n };\n\n log(\"auth.user:\", auth.user);\n\n assert.equal(auth.loginType, \"email+password\", \"auth.login.withPassword should be defined\");\n const isUser = Boolean(auth.user && auth.user.type !== \"public\");\n\n // Public data\n await test(\"Security rules example\", { skip: isUser }, async () => {\n log(\"Checking public data\");\n const vQ = await db.items4.find!({}, { select: { added: 0 } });\n assert.deepStrictEqual(vQ, [\n { id: 1, public: \"public data\" },\n { id: 2, public: \"public data\" },\n ]);\n\n const aggregate = await db.items4.findOne!(\n {},\n {\n select: {\n count: { $count: [], $filter: { name: \"abc\" } },\n values: { $array_agg: [\"public\"], $orderBy: { added: 1 } },\n },\n },\n );\n assert.deepStrictEqual(aggregate, {\n count: \"2\",\n values: [\"public data\", \"public data\"],\n });\n\n const orderByError = await db.items4.findOne!(\n {},\n { select: { values: { $array_agg: [\"public\"], $orderBy: { public: 1 } } } },\n ).catch((error) => error);\n assert.match(orderByError.message ?? String(orderByError), /invalid\\/disallowed/i);\n\n const cols = await db.insert_rules.getColumns!();\n assert.equal(\n cols.filter(({ insert, update: u, select: s, delete: d }) => insert && !u && s && !d)\n .length,\n 2,\n \"Validated getColumns failed\",\n );\n\n /* Validated insert */\n const expectB = await db.insert_rules.insert!({ name: \"a\" }, { returning: \"*\" });\n assert.deepStrictEqual(expectB, { name: \"b\" }, \"Validated insert failed\");\n\n /* forced UUID insert */\n const row: any = await db.uuid_text.insert!({}, { returning: \"*\" });\n assert.equal(row.id, \"c81089e1-c4c1-45d7-a73d-e2d613cb7c3e\");\n\n try {\n await db.insert_rules.insert!({ name: \"notfail\" }, { returning: \"*\" });\n await db.insert_rules.insert!({ name: \"fail\" }, { returning: \"*\" });\n await db.insert_rules.insert!({ name: \"fail-check\" }, { returning: \"*\" });\n throw \"post insert checks should have failed\";\n } catch (err) {}\n assert.equal(0, +(await db.insert_rules.count!({ name: \"fail\" })), \"postValidation failed\");\n assert.equal(\n 0,\n +(await db.insert_rules.count!({ name: \"fail-check\" })),\n \"checkFilter failed\",\n );\n assert.equal(\n 1,\n +(await db.insert_rules.count!({ name: \"notfail\" })),\n \"postValidation failed\",\n );\n\n const funcError = await serverFunctions\n .myfunc?.(undefined as unknown as any)\n .catch((err) => err);\n assert.deepStrictEqual(funcError, {\n error: \"input is of invalid type. Expecting { arg1: number }\",\n });\n const funcResult = await serverFunctions.myfunc?.({ arg1: 1 }).catch((err) => err);\n assert.equal(funcResult, 222, \"methods.myfunc() failed\");\n\n assert.equal(serverFunctions.myAdminFunc, undefined, \"myAdminFunc should not be defined\");\n\n const typedServerFunctions = serverFunctions as unknown as GeneratedFunctionSchema;\n const res = await typedServerFunctions.myfunc({ arg1: 1 });\n () =>\n typedServerFunctions.myfuncWithBadReturn({\n //@ts-expect-error\n arg2: 1,\n });\n if (\n //@ts-expect-error\n res === \"2\"\n ) {\n throw \"methods.myfuncWithReturn() failed\";\n }\n if (res === 2) {\n }\n\n const typedComplexFunc = await typedServerFunctions.myfuncWithComplexReturn({ arg1: 5 });\n if (Array.isArray(typedComplexFunc)) {\n const item = typedComplexFunc[0];\n // @ts-expect-error\n item satisfies string;\n item satisfies number;\n } else {\n typedComplexFunc satisfies { a: number; b: string; c: { d: boolean } };\n // @ts-expect-error\n typedComplexFunc satisfies { a: string };\n }\n });\n\n // await tryRun(\"Duplicate subscription\", async () => {\n\n // return new Promise(async (resolve, reject) => {\n // let data1 = [], data2 = [], cntr = 0;\n // function check(){\n // cntr++;\n // if(cntr === 2){\n // assert.equal(data1.length, data2.length);\n // console.error(data1, data2)\n // reject( data1);\n // resolve(data1)\n // }\n // }\n\n // const sub1 = await db.planes.subscribe({}, {}, data => {\n // data1 = data;\n // check()\n // });\n // const sub2 = await db.planes.subscribe({}, {}, data => {\n // data2 = data;\n // check()\n // });\n // })\n // })\n\n await test(\"Realtime\", { skip: isUser }, async () => {\n await testRealtime();\n });\n\n /* Bug: \n doing a \n some_table.sync({}, { handlesOnData: true }, console.log);\n will make all subsequent \n some_table.sync({}, { handlesOnData: false }, console.log);\n return no data items\n */\n await test(\"sync handlesOnData true -> false no data bug\", { skip: isUser }, async () => {\n let sync1Planes: AnyObject[] = [];\n let sync2Planes: AnyObject[] = [];\n const sync1 = await db.planes.sync!({}, { handlesOnData: true }, async (planes1, deltas) => {\n sync1Planes = planes1;\n log(\"sync handlesOnData true\", planes1.length);\n });\n await tout(1000);\n const sync2 = await db.planes.sync!({}, { handlesOnData: false }, (planes2, deltas) => {\n sync2Planes = planes2;\n });\n await tout(1000);\n if (sync1Planes.length !== sync2Planes.length || sync1Planes.length === 0) {\n throw `sync2Planes.length !== 100: ${sync1Planes.length} vs ${sync2Planes.length}`;\n }\n await sync1.$unsync();\n await sync2.$unsync();\n });\n\n // User data\n await test(\"Security rules example\", { skip: !isUser }, async () => {\n log(\"Checking User data\");\n const vQ = await db.items4.find!();\n assert.deepStrictEqual(vQ, [\n { id: 1, public: \"public data\" },\n { id: 2, public: \"public data\" },\n ]);\n\n await db.items4.find!({}, { select: { id: 1 }, orderBy: { added: 1 } });\n\n const dynamicCols = await db.uuid_text.getColumns!(undefined, {\n rule: \"update\",\n filter: {\n id: \"c81089e1-c4c1-45d7-a73d-e2d613cb7c3e\",\n },\n });\n assert.equal(dynamicCols.length, 1);\n assert.equal(dynamicCols[0].name, \"id\");\n const defaultCols = await db.uuid_text.getColumns!(undefined, {\n rule: \"update\",\n filter: {\n id: \"not matching\",\n },\n });\n throw defaultCols.map((c) => c.name);\n });\n });\n};\n\nconst tout = (t = 3000) => {\n return new Promise(async (resolve, reject) => {\n setTimeout(() => {\n resolve(true);\n }, t);\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/clientRestApi.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'AuthHandler' is defined but never used. Allowed unused vars must match /^_/u.","line":2,"column":32,"nodeType":"Identifier","messageId":"unusedVar","endLine":2,"endColumn":43,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"AuthHandler"},"fix":{"range":[72,85],"text":""},"desc":"Remove unused variable \"AuthHandler\"."}]},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"Imports \"DBSchemaTable\" are only used as type.","line":3,"column":1,"nodeType":"ImportDeclaration","messageId":"someImportsAreOnlyTypes","endLine":3,"endColumn":75,"fix":{"range":[105,128],"text":"import type { DBSchemaTable} from \"prostgles-types\";\nimport {"}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `Promise<any>`.","line":14,"column":8,"nodeType":"CallExpression","messageId":"unsafeReturn","endLine":14,"endColumn":86},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":14,"column":68,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":14,"endColumn":85},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":14,"column":72,"nodeType":"Identifier","messageId":"neverNullish","endLine":14,"endColumn":78},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":16,"column":34,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":16,"endColumn":51},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":16,"column":38,"nodeType":"Identifier","messageId":"neverNullish","endLine":16,"endColumn":44},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":18,"column":48,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":18,"endColumn":65},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":18,"column":52,"nodeType":"Identifier","messageId":"neverNullish","endLine":18,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":20,"column":44,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":20,"endColumn":61},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":20,"column":48,"nodeType":"Identifier","messageId":"neverNullish","endLine":20,"endColumn":54},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":28,"column":29,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":28,"endColumn":31,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1365,1367],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":29,"column":43,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":29,"endColumn":45,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1423,1425],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":30,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":30,"endColumn":66},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":33,"column":78,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":33,"endColumn":83},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":41,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":41,"endColumn":85},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'last_updated' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":43,"column":15,"nodeType":"Identifier","messageId":"unusedVar","endLine":43,"endColumn":27},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":43,"column":48,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":43,"endColumn":53,"fix":{"range":[2085,2086],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":48,"column":42,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":48,"endColumn":44,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2284,2286],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":49,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":49,"endColumn":64},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":53,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":53,"endColumn":80},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":56,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":56,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tableSchema on an `any` value.","line":57,"column":59,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":57,"endColumn":70},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":58,"column":27,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":58,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tableSchema on an `any` value.","line":58,"column":43,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":58,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .name on an `any` value.","line":58,"column":77,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":58,"endColumn":81},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":63,"column":31,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":63,"endColumn":33,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2959,2961],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":63,"column":49,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":63,"endColumn":51,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2977,2979],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":65,"column":35,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":65,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3027,3029],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":70,"column":28,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":70,"endColumn":30,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3258,3260],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":70,"column":46,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":70,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3276,3278],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":78,"column":38,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":78,"endColumn":40,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3709,3711],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":78,"column":50,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":78,"endColumn":52,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3721,3723],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":79,"column":38,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":79,"endColumn":40,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3764,3766],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":79,"column":47,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":79,"endColumn":49,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3773,3775],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":80,"column":15,"nodeType":"ChainExpression","messageId":"alwaysTruthy","endLine":80,"endColumn":35},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":80,"column":23,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":80,"endColumn":25,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3801,3803],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":81,"column":19,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":81,"endColumn":66},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":83,"column":67,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":83,"endColumn":79},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .map on an `any` value.","line":83,"column":76,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":83,"endColumn":79},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .length on an `any` value.","line":86,"column":34,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":86,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .clientSchemaTest on an `any` value.","line":88,"column":37,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":88,"endColumn":53},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .clientSchemaTest on an `any` value.","line":89,"column":37,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":89,"endColumn":53},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":96,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":96,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":96,"column":65,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":96,"endColumn":70},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":98,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":98,"endColumn":82},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":98,"column":76,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":98,"endColumn":81},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":105,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":105,"endColumn":74},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":105,"column":68,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":105,"endColumn":73},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":110,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":112,"endColumn":10},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":111,"column":22,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":111,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":123,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":123,"endColumn":74},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":123,"column":68,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":123,"endColumn":73},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":148,"column":12,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":148,"endColumn":14,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[6136,6138],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":156,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":162,"endColumn":5},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":158,"column":7,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":158,"endColumn":31},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":165,"column":12,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":165,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":167,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":167,"endColumn":22}],"suppressedMessages":[],"errorCount":22,"fatalErrorCount":0,"warningCount":37,"fixableErrorCount":2,"fixableWarningCount":0,"source":"import { strict as assert } from \"assert\";\nimport type { DBHandlerClient, AuthHandler } from \"./client\";\nimport { DBSchemaTable, omitKeys, type AnyObject } from \"prostgles-types\";\nimport { describe, test } from \"node:test\";\n\nexport const clientRestApi = async (\n db: DBHandlerClient,\n tableSchema: DBSchemaTable[],\n token: string,\n) => {\n const rest = async (\n { tableName, command, noAuth }: { tableName: string; command: string; noAuth?: boolean },\n ...params: any[]\n ) => post({ path: `db/${tableName}/${command}`, noAuth, token }, ...(params ?? []));\n const dbRest = (tableName: string, command: string, ...params: any[]) =>\n rest({ tableName, command }, ...(params ?? []));\n const dbRestNoAuth = (tableName: string, command: string, ...params: any[]) =>\n rest({ tableName, command, noAuth: true }, ...(params ?? []));\n const sqlRest = (query: string, ...params: any[]) =>\n post({ path: `db/sql`, token }, query, ...(params ?? []));\n const dbMethod = (methodName: string, input?: unknown) =>\n post({ path: `methods/${methodName}`, token, onlyFirstParam: true }, input);\n\n await describe(\"clientRestApi\", async () => {\n await test(\"Rest api test\", async () => {\n const dataFilter = { id: 123123123, last_updated: Date.now() };\n const dataFilter1 = { id: 123123124, last_updated: Date.now() };\n await db.planes.insert?.(dataFilter);\n const item = await db.planes.findOne?.(dataFilter);\n const itemR = await dbRest(\"planes\", \"findOne\", dataFilter);\n /** last_updated excluded from select.fields and select.filterFields */\n assert.deepStrictEqual(\n await dbRestNoAuth(\"planes\", \"findOne\", dataFilter).catch((error) => error),\n {\n error: {\n message:\n 'planes.last_updated is invalid/disallowed for filtering. Allowed columns: \"id\", \"x\", \"y\", \"flight_number\"',\n },\n },\n );\n const itemRNA = await dbRestNoAuth(\"planes\", \"findOne\", { id: dataFilter.id });\n assert.deepStrictEqual(item, itemR);\n const { last_updated, ...allowedData } = item!;\n assert.deepStrictEqual(allowedData, itemRNA);\n\n await dbRest(\"planes\", \"insert\", dataFilter1);\n const filter = { \"id.>=\": dataFilter.id };\n const count = await db.planes.count?.(filter);\n const restCount = await dbRest(\"planes\", \"count\", filter);\n assert.equal(count, 2);\n assert.equal(restCount, 2);\n\n const sqlRes = await sqlRest(\"select 1 as a\", {}, { returnType: \"rows\" });\n assert.deepStrictEqual(sqlRes, [{ a: 1 }]);\n\n const restTableSchema = await post({ path: \"schema\", token });\n assert.deepStrictEqual(tableSchema, restTableSchema.tableSchema);\n const planesTable = restTableSchema.tableSchema.find((table) => table.name === \"planes\") as\n | (DBSchemaTable & {\n clientSchemaTest?: { sid?: string; tableIndex: number };\n })\n | undefined;\n assert.equal(planesTable?.clientSchemaTest?.sid, token);\n\n const idColumn = planesTable?.columns.find((column) => column.name === \"id\") as\n | (DBSchemaTable[\"columns\"][number] & {\n clientSchemaTest?: { sid?: string; columnIndex: number };\n })\n | undefined;\n assert.equal(idColumn?.clientSchemaTest?.sid, token);\n // Connection setup and direct requests apply customization different numbers of times.\n const withoutPassCount = ({ clientSchemaTest, ...info }: AnyObject) => ({\n ...info,\n clientSchemaTest: clientSchemaTest && omitKeys(clientSchemaTest, [\"passes\"]),\n });\n await Promise.all(\n tableSchema.map(async ({ name, columns, ...otherInfo }) => {\n const cols = await db[name]?.getColumns?.();\n const info = await db[name]?.getInfo?.();\n if (db[name]?.getColumns) {\n const restCols = await dbRest(name, \"getColumns\", {});\n assert.deepStrictEqual(columns, cols);\n assert.deepStrictEqual(columns.map(withoutPassCount), restCols.map(withoutPassCount));\n assert.deepStrictEqual(withoutPassCount(otherInfo), withoutPassCount(info));\n if (name === \"planes\") {\n assert.ok(restCols.length);\n for (const column of restCols) {\n assert.equal(column.clientSchemaTest.passes, 1);\n assert.equal(column.clientSchemaTest.sid, token);\n }\n }\n }\n }),\n );\n\n const err = await dbMethod(\"myfunc\", {}).catch((error) => error);\n assert.deepStrictEqual(err, { error: { message: \"arg1 is missing but required\" } });\n const two22 = await dbMethod(\"myfunc\", { arg1: 1 }).catch((error) => error);\n assert.equal(two22, 222);\n });\n\n await test(\"Rest api security\", async () => {\n const sensitiveKeys = [\"constructor\", \"__proto__\", \"prototype\"];\n for (const key of sensitiveKeys) {\n const res = await dbRest(key, \"find\", {}).catch((error) => error);\n assert.deepStrictEqual(res, {\n error: { message: `tableName ${key} is invalid or not allowed` },\n });\n\n const res1 = await dbRest(\"planes\", \"find\", JSON.parse(`{\"${key}\": {}}`)).catch(\n (error) => error,\n );\n assert.deepStrictEqual(\n res1,\n\n {\n error: {\n message: `planes.${key} is invalid/disallowed for filtering. Allowed columns: \"id\", \"x\", \"y\", \"flight_number\", \"last_updated\"`,\n },\n },\n );\n\n const methodRes = await dbMethod(key, {}).catch((error) => error);\n assert.deepStrictEqual(methodRes, {\n error: { message: `Disallowed/missing function \"${key}\"` },\n });\n }\n });\n });\n};\n\nconst post = async (\n {\n path,\n noAuth,\n token,\n onlyFirstParam,\n }: { path: string; token: string; noAuth?: boolean; onlyFirstParam?: boolean },\n ...params: any[]\n) => {\n const headers = new Headers({\n Authorization: `Bearer ${Buffer.from(noAuth ? \"noAuth\" : token, \"utf-8\").toString(\"base64\")}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n });\n\n const body =\n !params?.length ? undefined\n : onlyFirstParam ? JSON.stringify(params[0])\n : JSON.stringify(params);\n const res = await fetch(`http://127.0.0.1:3001/api/${path}`, {\n method: \"POST\",\n headers,\n body,\n });\n const resBodyJson = await res.text().then((text) => {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n });\n\n if (res.status !== 200) {\n return Promise.reject(resBodyJson);\n }\n return resBodyJson;\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/config_test/index.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":12,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":12,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":13,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":13,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":13,"column":14,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":13,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createServer on an `any` value.","line":13,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":13,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":14,"column":1,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .listen on an `any` value.","line":14,"column":6,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":12},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":75,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":75,"endColumn":52,"fix":{"range":[1930,1930],"text":" type"}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a type that could not be resolved.","line":77,"column":1,"nodeType":"Identifier","messageId":"errorCall","endLine":77,"endColumn":10},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":82,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":82,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .users on an `any` value.","line":82,"column":14,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":82,"endColumn":19}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":9,"fixableErrorCount":1,"fixableWarningCount":0,"source":"/* Dashboard */\nimport express from \"express\";\n\nprocess.on(\"unhandledRejection\", (reason, p) => {\n console.trace(\"Unhandled Rejection at:\", p, \"reason:\", reason);\n process.exit(1);\n});\n\nconst app = express();\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\nconst _http = require(\"http\");\nconst http = _http.createServer(app);\nhttp.listen(process.env.NPORT || 3000);\n\n// import WebSocket from 'ws';\n// const wss = new WebSocket.Server({\n// // port: 3001,\n// server: http,\n// path: \"/s\",\n// perMessageDeflate: {\n// zlibDeflateOptions: {\n// // See zlib defaults.\n// chunkSize: 1024,\n// memLevel: 7,\n// level: 3\n// },\n// zlibInflateOptions: {\n// chunkSize: 10 * 1024\n// },\n// // Other options settable:\n// clientNoContextTakeover: true, // Defaults to negotiated value.\n// serverNoContextTakeover: true, // Defaults to negotiated value.\n// serverMaxWindowBits: 10, // Defaults to negotiated value.\n// // Below options specified as default values.\n// concurrencyLimit: 10, // Limits zlib concurrency for perf.\n// threshold: 1024 // Size (in bytes) below which messages\n// // should not be compressed.\n// }\n// });\n// wss.on(\"connection\", s => {\n// s.on(\"message\", console.log)\n// })\n\nconst connectionString = `postgresql://api:api@localhost/postgres`;\n\n// await db.sql(`\n// DROP TABLE USERS;\n// CREATE TABLE users (\n// id SERIAL,\n// email TEXT NOT NULL,\n// preferences JSONB,\n// status TEXT,\n// type TEXT\n// );\n// `);\n// type DBGeneratedSchema = any;\n\n// const user = await db.users.find(\n// { type: \"admin\", status: \"active\" },\n// { select: { email: 1 } }\n// )\n// await db.sql(`\n// DROP TABLE USERS;\n// CREATE TABLE users (\n// id SERIAL,\n// email TEXT NOT NULL,\n// preferences JSONB,\n// status TEXT NOT NULL,\n// type TEXT NOT NULL\n// );\n// `);\n\nimport prostgles from \"prostgles-server\";\nimport { DBGeneratedSchema } from \"./DBoGenerated\";\n\nprostgles<DBGeneratedSchema>({\n dbConnection: { connectionString },\n tsGeneratedTypesDir: __dirname,\n watchSchema: true,\n onReady: async (db) => {\n await db.users.insert({});\n },\n});\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/isomorphicQueries.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"Imports \"SubscriptionHandler\" are only used as type.","line":8,"column":1,"nodeType":"ImportDeclaration","messageId":"someImportsAreOnlyTypes","endLine":19,"endColumn":26,"fix":{"range":[133,184],"text":"import type {\n SubscriptionHandler} from \"prostgles-types\";\nimport {\n ABORTABLE_METHODS"}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'getSerialisableError' is defined but never used. Allowed unused vars must match /^_/u.","line":11,"column":3,"nodeType":"Identifier","messageId":"unusedVar","endLine":11,"endColumn":23,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"getSerialisableError"},"fix":{"range":[184,208],"text":""},"desc":"Remove unused variable \"getSerialisableError\"."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'DBHandler' is defined but never used. Allowed unused vars must match /^_/u.","line":17,"column":8,"nodeType":"Identifier","messageId":"unusedVar","endLine":17,"endColumn":17,"suggestions":[{"messageId":"removeUnusedVar","data":{"varName":"DBHandler"},"fix":{"range":[282,300],"text":""},"desc":"Remove unused variable \"DBHandler\"."}]},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":20,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":20,"endColumn":73,"fix":{"range":[353,353],"text":" type"}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'DBHandlerServer' is defined but never used. Allowed unused vars must match /^_/u.","line":23,"column":15,"nodeType":"Identifier","messageId":"unusedVar","endLine":23,"endColumn":30,"suggestions":[{"messageId":"removeUnusedImportDeclaration","data":{"varName":"DBHandlerServer"},"fix":{"range":[531,579],"text":""},"desc":"Remove unused import declaration."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":34,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":34,"endColumn":39,"fix":{"range":[871,872],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .dboBuilder on an `any` value.","line":63,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":63,"endColumn":50},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":66,"column":46,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":66,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1838,1840],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":71,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":71,"endColumn":32,"fix":{"range":[1962,1963],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":73,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":73,"endColumn":36,"fix":{"range":[2004,2005],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":74,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":74,"endColumn":32,"fix":{"range":[2041,2042],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":75,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":75,"endColumn":32,"fix":{"range":[2078,2079],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":76,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":76,"endColumn":31,"fix":{"range":[2114,2115],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":78,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":78,"endColumn":17,"fix":{"range":[2144,2145],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":79,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":79,"endColumn":17,"fix":{"range":[2206,2207],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":83,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":83,"endColumn":76},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":83,"column":42,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":83,"endColumn":44,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2387,2389],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":83,"column":72,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":83,"endColumn":75},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":84,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":84,"endColumn":78},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":84,"column":44,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":84,"endColumn":46,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2466,2468],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":84,"column":74,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":84,"endColumn":77},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":85,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":85,"endColumn":76},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":85,"column":42,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":85,"endColumn":44,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2543,2545],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":85,"column":72,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":85,"endColumn":75},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":86,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":86,"endColumn":82},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":86,"column":48,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":86,"endColumn":50,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2626,2628],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":86,"column":78,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":86,"endColumn":81},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":87,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":87,"endColumn":80},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":87,"column":46,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":87,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2707,2709],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":87,"column":76,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":87,"endColumn":79},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":88,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":88,"endColumn":84},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":88,"column":46,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":88,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2788,2790],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":88,"column":80,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":88,"endColumn":83},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":89,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":89,"endColumn":98},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":89,"column":56,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":89,"endColumn":58,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2883,2885],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":89,"column":94,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":89,"endColumn":97},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":90,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":90,"endColumn":84},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":90,"column":46,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":90,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2972,2974],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":90,"column":80,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":90,"endColumn":83},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":91,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":91,"endColumn":80},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":91,"column":46,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":91,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3057,3059],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":91,"column":76,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":91,"endColumn":79},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":92,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":94,"endColumn":29},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":93,"column":19,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":93,"endColumn":21,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3153,3155],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":94,"column":25,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":94,"endColumn":28},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":95,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":97,"endColumn":29},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":96,"column":22,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":96,"endColumn":24,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3282,3284],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":97,"column":25,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":97,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":119,"column":25,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":119,"endColumn":28},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{}`.","line":134,"column":46,"nodeType":"LogicalExpression","messageId":"unsafeArgument","endLine":134,"endColumn":55},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .detail on an `any` value.","line":136,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":136,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .query on an `any` value.","line":137,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":137,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .length on an `any` value.","line":138,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":138,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .position on an `any` value.","line":139,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":139,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .file on an `any` value.","line":140,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":140,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .line on an `any` value.","line":141,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":141,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .routine on an `any` value.","line":142,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":142,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .code_info on an `any` value.","line":143,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":143,"endColumn":44},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'oid' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":155,"column":9,"nodeType":"Identifier","messageId":"unusedVar","endLine":155,"endColumn":12},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'isFileTable' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":156,"column":9,"nodeType":"Identifier","messageId":"unusedVar","endLine":156,"endColumn":20},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'publishInfo' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":157,"column":9,"nodeType":"Identifier","messageId":"unusedVar","endLine":157,"endColumn":20},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":159,"column":12,"nodeType":"AwaitExpression","messageId":"neverNullish","endLine":159,"endColumn":38},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":159,"column":34,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":159,"endColumn":36,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[5208,5210],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":182,"column":11,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":182,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":184,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":184,"endColumn":29,"fix":{"range":[5797,5798],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":185,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":185,"endColumn":30,"fix":{"range":[5830,5831],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":187,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":187,"endColumn":41,"fix":{"range":[5875,5876],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":195,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":195,"endColumn":30,"fix":{"range":[6159,6160],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":195,"column":45,"nodeType":"Property","messageId":"anyAssignment","endLine":195,"endColumn":65},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":195,"column":63,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":195,"endColumn":65},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":196,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":196,"endColumn":30,"fix":{"range":[6229,6230],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":197,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":197,"endColumn":30,"fix":{"range":[6296,6297],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":202,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":202,"endColumn":48,"fix":{"range":[6550,6551],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":208,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":208,"endColumn":51,"fix":{"range":[6775,6776],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":209,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":209,"endColumn":48,"fix":{"range":[6826,6827],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":213,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":213,"endColumn":30,"fix":{"range":[6888,6889],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":214,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":214,"endColumn":34,"fix":{"range":[6967,6968],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":216,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":216,"endColumn":31,"fix":{"range":[7056,7057],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":226,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":226,"endColumn":34,"fix":{"range":[7393,7394],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":229,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":229,"endColumn":51,"fix":{"range":[7509,7510],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":230,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":230,"endColumn":50,"fix":{"range":[7591,7592],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":233,"column":45,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":233,"endColumn":54,"fix":{"range":[7760,7761],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":234,"column":45,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":234,"endColumn":52,"fix":{"range":[7844,7845],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":240,"column":30,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":240,"endColumn":32,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[8066,8068],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":246,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":246,"endColumn":51,"fix":{"range":[8302,8303],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":254,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":256,"endColumn":29},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":255,"column":14,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":255,"endColumn":16,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[8554,8556],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":256,"column":25,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":256,"endColumn":28},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":258,"column":11,"nodeType":"Property","messageId":"anyAssignment","endLine":258,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .message on an `any` value.","line":258,"column":31,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":258,"endColumn":38},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":272,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":272,"endColumn":46,"fix":{"range":[9120,9121],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":279,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":279,"endColumn":46,"fix":{"range":[9389,9390],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":291,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":291,"endColumn":46,"fix":{"range":[9752,9753],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":294,"column":55,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":294,"endColumn":57,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[9977,9979],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":295,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":295,"endColumn":46,"fix":{"range":[10054,10055],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":298,"column":55,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":298,"endColumn":57,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[10281,10283],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":305,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":305,"endColumn":31,"fix":{"range":[10552,10553],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":306,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":306,"endColumn":31,"fix":{"range":[10606,10607],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":312,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":312,"endColumn":46,"fix":{"range":[10830,10831],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":330,"column":15,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":330,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":337,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":337,"endColumn":31,"fix":{"range":[11507,11508],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":341,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":341,"endColumn":31,"fix":{"range":[11668,11669],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":349,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":349,"endColumn":31,"fix":{"range":[11909,11910],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":354,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":354,"endColumn":31,"fix":{"range":[12076,12077],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":355,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":355,"endColumn":31,"fix":{"range":[12130,12131],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":372,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":372,"endColumn":42,"fix":{"range":[12596,12597],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":382,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":382,"endColumn":46,"fix":{"range":[12915,12916],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":386,"column":15,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":386,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":395,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":395,"endColumn":31,"fix":{"range":[13225,13226],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":403,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":403,"endColumn":31,"fix":{"range":[13454,13455],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":408,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":408,"endColumn":31,"fix":{"range":[13629,13630],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":409,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":409,"endColumn":31,"fix":{"range":[13683,13684],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":415,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":415,"endColumn":46,"fix":{"range":[13902,13903],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":419,"column":15,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":419,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":426,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":426,"endColumn":31,"fix":{"range":[14208,14209],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":431,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":431,"endColumn":31,"fix":{"range":[14402,14403],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'inserted' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":442,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":442,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":442,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":442,"endColumn":46,"fix":{"range":[14643,14644],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":443,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":443,"endColumn":41,"fix":{"range":[14730,14731],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":448,"column":33,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":448,"endColumn":35,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[14875,14877],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":452,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":452,"endColumn":42,"fix":{"range":[15036,15037],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":457,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":457,"endColumn":46,"fix":{"range":[15202,15203],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":461,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":461,"endColumn":46,"fix":{"range":[15349,15350],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":469,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":469,"endColumn":30,"fix":{"range":[15680,15681],"text":""}},{"ruleId":"prefer-const","severity":2,"message":"'str' is never reassigned. Use 'const' instead.","line":475,"column":11,"nodeType":"Identifier","messageId":"useConst","endLine":475,"endColumn":14},{"ruleId":"prefer-const","severity":2,"message":"'data' is never reassigned. Use 'const' instead.","line":476,"column":9,"nodeType":"Identifier","messageId":"useConst","endLine":476,"endColumn":13},{"ruleId":"prefer-const","severity":2,"message":"'mediaFile' is never reassigned. Use 'const' instead.","line":477,"column":9,"nodeType":"Identifier","messageId":"useConst","endLine":477,"endColumn":18,"fix":{"range":[15872,15998],"text":"const str = \"This is a string\",\n data = Buffer.from(str, \"utf-8\"),\n mediaFile = { data, original_name: fileName };"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":480,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":482,"endColumn":22,"fix":{"range":[16168,16169],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":485,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":485,"endColumn":58,"fix":{"range":[16375,16376],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":485,"column":37,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":485,"endColumn":54,"fix":{"range":[16371,16372],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":489,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":489,"endColumn":64,"fix":{"range":[16561,16562],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":494,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":494,"endColumn":66},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":496,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":496,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":496,"column":24,"nodeType":"Property","messageId":"anyAssignment","endLine":496,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":496,"column":38,"nodeType":"Property","messageId":"anyAssignment","endLine":496,"endColumn":51},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":513,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":513,"endColumn":29,"fix":{"range":[17262,17263],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":515,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":515,"endColumn":41,"fix":{"range":[17311,17312],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":519,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":519,"endColumn":29,"fix":{"range":[17524,17525],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":536,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":536,"endColumn":29,"fix":{"range":[18143,18144],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":537,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":537,"endColumn":45,"fix":{"range":[18195,18196],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":554,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":554,"endColumn":29,"fix":{"range":[18898,18899],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":556,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":556,"endColumn":43,"fix":{"range":[18973,18974],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":557,"column":59,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":557,"endColumn":61,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[19055,19057],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":560,"column":24,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":560,"endColumn":26,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[19152,19154],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":564,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":564,"endColumn":43,"fix":{"range":[19297,19298],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":678,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":678,"endColumn":50,"fix":{"range":[22274,22275],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":686,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":686,"endColumn":48,"fix":{"range":[22488,22489],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'tr1' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":692,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":692,"endColumn":16},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":692,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":692,"endColumn":39,"fix":{"range":[22690,22691],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'tr2' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":693,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":693,"endColumn":16},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":693,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":693,"endColumn":39,"fix":{"range":[22734,22735],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":699,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":699,"endColumn":29,"fix":{"range":[22840,22841],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'e' is defined but never used. Allowed unused caught errors must match /^_/u.","line":700,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":700,"endColumn":17},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":701,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":701,"endColumn":40,"fix":{"range":[22904,22905],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":705,"column":11,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":705,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":711,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":711,"endColumn":41,"fix":{"range":[23101,23102],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":723,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":723,"endColumn":39,"fix":{"range":[23402,23403],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":724,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":724,"endColumn":40,"fix":{"range":[23487,23488],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":735,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":735,"endColumn":29,"fix":{"range":[23836,23837],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":741,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":741,"endColumn":43,"fix":{"range":[24039,24040],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":750,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":750,"endColumn":19,"fix":{"range":[24289,24290],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":753,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":753,"endColumn":40,"fix":{"range":[24475,24476],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":766,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":766,"endColumn":19,"fix":{"range":[24892,24893],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":774,"column":34,"nodeType":"Identifier","messageId":"neverNullish","endLine":774,"endColumn":45},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":777,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":777,"endColumn":21,"fix":{"range":[25168,25169],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":798,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":798,"endColumn":41,"fix":{"range":[25848,25849],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":808,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":808,"endColumn":29,"fix":{"range":[26120,26121],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":811,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":811,"endColumn":41,"fix":{"range":[26266,26267],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":816,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":816,"endColumn":33,"fix":{"range":[26419,26420],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":827,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":827,"endColumn":42,"fix":{"range":[26656,26657],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":830,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":830,"endColumn":42,"fix":{"range":[26760,26761],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":842,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":842,"endColumn":32,"fix":{"range":[27139,27140],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":868,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":868,"endColumn":41,"fix":{"range":[27869,27870],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":915,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":915,"endColumn":42,"fix":{"range":[29322,29323],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":926,"column":26,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":926,"endColumn":28,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[29650,29652],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":953,"column":16,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":953,"endColumn":18,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[30497,30499],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":961,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":961,"endColumn":31,"fix":{"range":[30969,30970],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":962,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":962,"endColumn":31,"fix":{"range":[31014,31015],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":964,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":964,"endColumn":46,"fix":{"range":[31094,31095],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":964,"column":95,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":964,"endColumn":97,"suggestions":[{"messageId":"removeAsync","fix":{"range":[31134,31140],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":968,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":968,"endColumn":31,"fix":{"range":[31236,31237],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":971,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":971,"endColumn":31,"fix":{"range":[31370,31371],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":974,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":974,"endColumn":31,"fix":{"range":[31526,31527],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":977,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":977,"endColumn":31,"fix":{"range":[31702,31703],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":984,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":984,"endColumn":31,"fix":{"range":[31935,31936],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":985,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":985,"endColumn":31,"fix":{"range":[31980,31981],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":988,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":988,"endColumn":46,"fix":{"range":[32092,32093],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":991,"column":19,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":991,"endColumn":21,"suggestions":[{"messageId":"removeAsync","fix":{"range":[32188,32194],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":996,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":996,"endColumn":31,"fix":{"range":[32304,32305],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1005,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1005,"endColumn":31,"fix":{"range":[32694,32695],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1008,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1008,"endColumn":31,"fix":{"range":[32811,32812],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1011,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1011,"endColumn":31,"fix":{"range":[32925,32926],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'reject' is defined but never used. Allowed unused args must match /^_/u.","line":1020,"column":25,"nodeType":"Identifier","messageId":"unusedVar","endLine":1020,"endColumn":31},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1021,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1021,"endColumn":35,"fix":{"range":[33187,33188],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1022,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1022,"endColumn":50,"fix":{"range":[33251,33252],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1023,"column":21,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1023,"endColumn":23,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[33310,33312],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1024,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1024,"endColumn":39,"fix":{"range":[33370,33371],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1026,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1026,"endColumn":22},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1029,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1029,"endColumn":35,"fix":{"range":[33552,33553],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1030,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1030,"endColumn":35,"fix":{"range":[33621,33622],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1031,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1031,"endColumn":35,"fix":{"range":[33690,33691],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1040,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1040,"endColumn":65,"fix":{"range":[34003,34004],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1044,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1044,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1046,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1046,"endColumn":56,"fix":{"range":[34235,34236],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1052,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1052,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1055,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1055,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1058,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1058,"endColumn":19},{"ruleId":"prefer-const","severity":2,"message":"'callbacksFired' is never reassigned. Use 'const' instead.","line":1066,"column":13,"nodeType":"Identifier","messageId":"useConst","endLine":1066,"endColumn":49,"fix":{"range":[34769,34815],"text":"const callbacksFired: Record<string, true> = {};"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1069,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1069,"endColumn":56,"fix":{"range":[34968,34969],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'items' is defined but never used. Allowed unused args must match /^_/u.","line":1069,"column":81,"nodeType":"Identifier","messageId":"unusedVar","endLine":1069,"endColumn":86},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":1069,"column":88,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":1069,"endColumn":90,"suggestions":[{"messageId":"removeAsync","fix":{"range":[34987,34993],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `(reason: any) => PromiseLike<never>`.","line":1077,"column":17,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":1077,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1084,"column":9,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1084,"endColumn":16},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1110,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1110,"endColumn":33,"fix":{"range":[36491,36492],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1134,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1134,"endColumn":33,"fix":{"range":[37228,37229],"text":""}},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":1135,"column":9,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":1135,"endColumn":22,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[37288,37288],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[37288,37288],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1136,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1136,"endColumn":19,"fix":{"range":[37319,37320],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1156,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1156,"endColumn":33,"fix":{"range":[37913,37914],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1168,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1168,"endColumn":46,"fix":{"range":[38346,38347],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":1168,"column":87,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":1168,"endColumn":89,"suggestions":[{"messageId":"removeAsync","fix":{"range":[38373,38379],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1210,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1210,"endColumn":35,"fix":{"range":[39841,39842],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1213,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1213,"endColumn":53,"fix":{"range":[39983,39984],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1220,"column":17,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1220,"endColumn":23},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":1223,"column":19,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":1223,"endColumn":23},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1224,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1224,"endColumn":41,"fix":{"range":[40454,40455],"text":""}},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":1225,"column":17,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":1225,"endColumn":35,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[40493,40493],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[40493,40493],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1226,"column":17,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1226,"endColumn":24},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1230,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1230,"endColumn":35,"fix":{"range":[40620,40621],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1231,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1231,"endColumn":35,"fix":{"range":[40689,40690],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1243,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1243,"endColumn":53,"fix":{"range":[41094,41095],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'item' is defined but never used. Allowed unused args must match /^_/u.","line":1246,"column":20,"nodeType":"Identifier","messageId":"unusedVar","endLine":1246,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1251,"column":19,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1251,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1254,"column":19,"nodeType":"Identifier","messageId":"unsafeCall","endLine":1254,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1259,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1259,"endColumn":35,"fix":{"range":[41652,41653],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1268,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1268,"endColumn":49,"fix":{"range":[41888,41889],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":1268,"column":88,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":1268,"endColumn":90,"suggestions":[{"messageId":"removeAsync","fix":{"range":[41919,41925],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1271,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1271,"endColumn":31,"fix":{"range":[41988,41989],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1274,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1274,"endColumn":31,"fix":{"range":[42080,42081],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1283,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1283,"endColumn":49,"fix":{"range":[42350,42351],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":1283,"column":88,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":1283,"endColumn":90,"suggestions":[{"messageId":"removeAsync","fix":{"range":[42381,42387],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1288,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1288,"endColumn":31,"fix":{"range":[42502,42503],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1291,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1291,"endColumn":31,"fix":{"range":[42594,42595],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1300,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1300,"endColumn":49,"fix":{"range":[42869,42870],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":1303,"column":18,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":1303,"endColumn":20,"suggestions":[{"messageId":"removeAsync","fix":{"range":[42935,42941],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1309,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1309,"endColumn":31,"fix":{"range":[43078,43079],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1312,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1312,"endColumn":31,"fix":{"range":[43170,43171],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1320,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1320,"endColumn":49,"fix":{"range":[43445,43446],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":1323,"column":18,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":1323,"endColumn":20,"suggestions":[{"messageId":"removeAsync","fix":{"range":[43512,43518],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1329,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1329,"endColumn":31,"fix":{"range":[43655,43656],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1332,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1332,"endColumn":31,"fix":{"range":[43747,43748],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1333,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1333,"endColumn":43,"fix":{"range":[43799,43800],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1340,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1340,"endColumn":42,"fix":{"range":[43993,43994],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1345,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1345,"endColumn":42,"fix":{"range":[44146,44147],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1359,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1359,"endColumn":44,"fix":{"range":[44487,44488],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1363,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1363,"endColumn":45,"fix":{"range":[44640,44641],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1367,"column":23,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1367,"endColumn":25,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[44765,44767],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1368,"column":24,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1368,"endColumn":26,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[44813,44815],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1372,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1372,"endColumn":42,"fix":{"range":[44932,44933],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1378,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1378,"endColumn":42,"fix":{"range":[45146,45147],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1385,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1385,"endColumn":39,"fix":{"range":[45325,45326],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1395,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1395,"endColumn":39,"fix":{"range":[45665,45666],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1408,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1408,"endColumn":39,"fix":{"range":[46039,46040],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1415,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1415,"endColumn":40,"fix":{"range":[46332,46333],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1422,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1422,"endColumn":40,"fix":{"range":[46586,46587],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1429,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1429,"endColumn":40,"fix":{"range":[46844,46845],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1435,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1435,"endColumn":39,"fix":{"range":[47049,47050],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1448,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1448,"endColumn":42,"fix":{"range":[47411,47412],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1467,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1467,"endColumn":39,"fix":{"range":[47925,47926],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1480,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1480,"endColumn":39,"fix":{"range":[48307,48308],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1494,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1494,"endColumn":35,"fix":{"range":[48662,48663],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1498,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1498,"endColumn":42,"fix":{"range":[48806,48807],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1502,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1502,"endColumn":41,"fix":{"range":[48927,48928],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1506,"column":21,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1506,"endColumn":23,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[49037,49039],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1506,"column":26,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1506,"endColumn":28,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[49042,49044],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1507,"column":21,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1507,"endColumn":23,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[49076,49078],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":1507,"column":28,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":1507,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .substr on an `any` value.","line":1507,"column":37,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":1507,"endColumn":43},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1510,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1510,"endColumn":42,"fix":{"range":[49173,49174],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1517,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1517,"endColumn":43,"fix":{"range":[49440,49441],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1524,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1524,"endColumn":43,"fix":{"range":[49641,49642],"text":""}},{"ruleId":"prefer-const","severity":2,"message":"'i' is never reassigned. Use 'const' instead.","line":1540,"column":11,"nodeType":"Identifier","messageId":"useConst","endLine":1540,"endColumn":12,"fix":{"range":[50059,50249],"text":"const i = await db.items4_pub.insert!(\n {\n name: \"abc123\",\n public: \"public data\",\n added: \"04 Dec 1995 00:12:00\",\n },\n returningParam,\n );"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1540,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1540,"endColumn":42,"fix":{"range":[50093,50094],"text":""}},{"ruleId":"prefer-const","severity":2,"message":"'u' is never reassigned. Use 'const' instead.","line":1556,"column":11,"nodeType":"Identifier","messageId":"useConst","endLine":1556,"endColumn":12,"fix":{"range":[50474,50607],"text":"const u = await db.items4_pub.update!(\n { name: \"abc123\" },\n { public: \"public data2\" },\n returningParam,\n );"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1556,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1556,"endColumn":42,"fix":{"range":[50508,50509],"text":""}},{"ruleId":"prefer-const","severity":2,"message":"'d' is never reassigned. Use 'const' instead.","line":1571,"column":11,"nodeType":"Identifier","messageId":"useConst","endLine":1571,"endColumn":12,"fix":{"range":[50844,50916],"text":"const d = await db.items4_pub.delete!({ name: \"abc123\" }, returningParam);"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1571,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1571,"endColumn":42,"fix":{"range":[50878,50879],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1587,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1587,"endColumn":45,"fix":{"range":[51341,51342],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1588,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1588,"endColumn":50,"fix":{"range":[51421,51422],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1589,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1589,"endColumn":51,"fix":{"range":[51482,51483],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1590,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1590,"endColumn":51,"fix":{"range":[51557,51558],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1591,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1591,"endColumn":46,"fix":{"range":[51622,51623],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1599,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1599,"endColumn":30,"fix":{"range":[51895,51896],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1602,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1602,"endColumn":30,"fix":{"range":[52048,52049],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1608,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1608,"endColumn":41,"fix":{"range":[52214,52215],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1632,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1632,"endColumn":44,"fix":{"range":[52812,52813],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'fo' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":1674,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":1674,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1674,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1674,"endColumn":40,"fix":{"range":[54018,54019],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1676,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1676,"endColumn":29,"fix":{"range":[54141,54142],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1681,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1681,"endColumn":31,"fix":{"range":[54260,54261],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'e' is defined but never used. Allowed unused caught errors must match /^_/u.","line":1683,"column":16,"nodeType":"Identifier","messageId":"unusedVar","endLine":1683,"endColumn":17},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1689,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1689,"endColumn":41,"fix":{"range":[54493,54494],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1690,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1690,"endColumn":37,"fix":{"range":[54533,54534],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1696,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1696,"endColumn":44,"fix":{"range":[54765,54766],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1701,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1701,"endColumn":44,"fix":{"range":[54957,54958],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1708,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1708,"endColumn":40,"fix":{"range":[55236,55237],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1719,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1719,"endColumn":43,"fix":{"range":[55644,55645],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1726,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1726,"endColumn":49,"fix":{"range":[55918,55919],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1736,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1736,"endColumn":44,"fix":{"range":[56278,56279],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1747,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1747,"endColumn":44,"fix":{"range":[56661,56662],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1755,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1755,"endColumn":29,"fix":{"range":[56913,56914],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1756,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1756,"endColumn":29,"fix":{"range":[56975,56976],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1757,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1757,"endColumn":41,"fix":{"range":[57049,57050],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1762,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1762,"endColumn":41,"fix":{"range":[57215,57216],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":1768,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":1768,"endColumn":49},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1784,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1784,"endColumn":42,"fix":{"range":[57760,57761],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1793,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1793,"endColumn":43,"fix":{"range":[57924,57925],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":1799,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":1799,"endColumn":49},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1819,"column":40,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1819,"endColumn":57,"fix":{"range":[58567,58568],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1820,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1820,"endColumn":48,"fix":{"range":[58648,58649],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1824,"column":40,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1824,"endColumn":57,"fix":{"range":[58862,58863],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1830,"column":41,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1830,"endColumn":62,"fix":{"range":[59084,59085],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":1838,"column":75,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":1838,"endColumn":77},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1839,"column":38,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1839,"endColumn":55,"fix":{"range":[59391,59392],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":1844,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":1854,"endColumn":14},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1862,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1862,"endColumn":30,"fix":{"range":[59958,59959],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":1862,"column":80,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":1862,"endColumn":82},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1867,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1867,"endColumn":46,"fix":{"range":[60250,60251],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":1868,"column":19,"nodeType":"Property","messageId":"anyAssignment","endLine":1868,"endColumn":46},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1868,"column":36,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1868,"endColumn":38,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[60329,60331],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1869,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1869,"endColumn":52,"fix":{"range":[60393,60394],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1870,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1870,"endColumn":42,"fix":{"range":[60469,60470],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1871,"column":28,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1871,"endColumn":30,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[60499,60501],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1874,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1874,"endColumn":47,"fix":{"range":[60604,60605],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1875,"column":32,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1875,"endColumn":34,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[60638,60640],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1880,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1880,"endColumn":29,"fix":{"range":[60764,60765],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1885,"column":23,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1885,"endColumn":25,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[60896,60898],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1886,"column":27,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1886,"endColumn":29,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[60949,60951],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1887,"column":33,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1887,"endColumn":35,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[61008,61010],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":1888,"column":40,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":1888,"endColumn":42,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[61061,61063],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1897,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1897,"endColumn":41,"fix":{"range":[61342,61343],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1899,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1899,"endColumn":45,"fix":{"range":[61448,61449],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1901,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1901,"endColumn":54,"fix":{"range":[61555,61556],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":1903,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":1903,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":1905,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":1905,"endColumn":34},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1910,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1910,"endColumn":40,"fix":{"range":[61791,61792],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1920,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1920,"endColumn":50,"fix":{"range":[62032,62033],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1949,"column":39,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1949,"endColumn":64,"fix":{"range":[62667,62668],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1983,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1983,"endColumn":54,"fix":{"range":[63443,63444],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":1995,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":1995,"endColumn":54,"fix":{"range":[63741,63742],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2016,"column":38,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2016,"endColumn":40,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[64414,64416],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2025,"column":19,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":2027,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2025,"column":35,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2025,"endColumn":37,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[64682,64684],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2028,"column":43,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2028,"endColumn":45,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[64816,64818],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2032,"column":43,"nodeType":"Property","messageId":"anyAssignment","endLine":2032,"endColumn":47},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2035,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2035,"endColumn":57,"fix":{"range":[65105,65106],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":2047,"column":15,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":2047,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":2047,"column":43,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":2047,"endColumn":62},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2050,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2050,"endColumn":48,"fix":{"range":[65518,65519],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":2057,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":2057,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":2059,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":2059,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `(reason: any) => PromiseLike<never>`.","line":2062,"column":18,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":2062,"endColumn":24},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'reject' is defined but never used. Allowed unused args must match /^_/u.","line":2067,"column":47,"nodeType":"Identifier","messageId":"unusedVar","endLine":2067,"endColumn":53},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2068,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2068,"endColumn":57,"fix":{"range":[66101,66102],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'items' is defined but never used. Allowed unused args must match /^_/u.","line":2071,"column":18,"nodeType":"Identifier","messageId":"unusedVar","endLine":2071,"endColumn":23},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":2071,"column":25,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":2071,"endColumn":27,"suggestions":[{"messageId":"removeAsync","fix":{"range":[66176,66182],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":2073,"column":19,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":2073,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":2075,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":2075,"endColumn":22},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'inserted' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":2083,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":2083,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2083,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2083,"endColumn":44,"fix":{"range":[66491,66492],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2090,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2090,"endColumn":44,"fix":{"range":[66681,66682],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2104,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2104,"endColumn":45,"fix":{"range":[66993,66994],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'reject' is defined but never used. Allowed unused args must match /^_/u.","line":2139,"column":64,"nodeType":"Identifier","messageId":"unusedVar","endLine":2139,"endColumn":70},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2141,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2141,"endColumn":44,"fix":{"range":[67942,67943],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2154,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2154,"endColumn":35,"fix":{"range":[68245,68246],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2154,"column":38,"nodeType":"Property","messageId":"anyAssignment","endLine":2154,"endColumn":58},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2154,"column":46,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2154,"endColumn":55,"fix":{"range":[68265,68266],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":2159,"column":15,"nodeType":"Identifier","messageId":"unsafeCall","endLine":2159,"endColumn":22},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2168,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2168,"endColumn":27,"fix":{"range":[68662,68663],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2169,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2169,"endColumn":27,"fix":{"range":[68709,68710],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2170,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2170,"endColumn":27,"fix":{"range":[68752,68753],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2173,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2173,"endColumn":42,"fix":{"range":[68879,68880],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":2188,"column":15,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":2188,"endColumn":21},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2195,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2195,"endColumn":27,"fix":{"range":[69374,69375],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2200,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2200,"endColumn":27,"fix":{"range":[69570,69571],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2201,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2201,"endColumn":27,"fix":{"range":[69617,69618],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2206,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2206,"endColumn":21,"fix":{"range":[69797,69798],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":2226,"column":23,"nodeType":"MemberExpression","messageId":"unsafeReturn","endLine":2226,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .maxId on an `any` value.","line":2226,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2226,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":2229,"column":31,"nodeType":"MemberExpression","messageId":"unsafeReturn","endLine":2229,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .maxId on an `any` value.","line":2229,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2229,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2233,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":2233,"endColumn":73},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":2233,"column":71,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":2233,"endColumn":72},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .message on an `any` value.","line":2235,"column":23,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2235,"endColumn":30},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2242,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2242,"endColumn":37,"fix":{"range":[71093,71094],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any[]`.","line":2257,"column":26,"nodeType":"ArrayExpression","messageId":"unsafeReturn","endLine":2257,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .sign on an `any` value.","line":2257,"column":47,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2257,"endColumn":51},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'pr' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":2266,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":2266,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2266,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2266,"endColumn":42,"fix":{"range":[71591,71592],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2274,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2274,"endColumn":47,"fix":{"range":[71821,71822],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2275,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2275,"endColumn":49,"fix":{"range":[71887,71888],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2276,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2276,"endColumn":51,"fix":{"range":[71956,71957],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2284,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2284,"endColumn":35,"fix":{"range":[72200,72201],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2294,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2294,"endColumn":47,"fix":{"range":[72496,72497],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2297,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2297,"endColumn":54,"fix":{"range":[72607,72608],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2301,"column":29,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":2301,"endColumn":31,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[72723,72725],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2303,"column":29,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":2303,"endColumn":31,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[72793,72795],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .name on an `any` value.","line":2303,"column":53,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2303,"endColumn":57},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2307,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2307,"endColumn":35,"fix":{"range":[72952,72953],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2316,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2316,"endColumn":45,"fix":{"range":[73169,73170],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2321,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":2323,"endColumn":15},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2324,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":2326,"endColumn":15},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":2327,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":2329,"endColumn":15},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [0] on an `any` value.","line":2337,"column":30,"nodeType":"Literal","messageId":"unsafeMemberExpression","endLine":2337,"endColumn":31},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2345,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2345,"endColumn":33,"fix":{"range":[74145,74146],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'a' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":2346,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":2346,"endColumn":14},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2346,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2346,"endColumn":43,"fix":{"range":[74191,74192],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'a1' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":2347,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":2347,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2347,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2347,"endColumn":44,"fix":{"range":[74251,74252],"text":""}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'a2' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":2351,"column":13,"nodeType":"Identifier","messageId":"unusedVar","endLine":2351,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2351,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2351,"endColumn":44,"fix":{"range":[74356,74357],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2356,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2356,"endColumn":43,"fix":{"range":[74463,74464],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .name on an `any` value.","line":2372,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2372,"endColumn":37},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2376,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2376,"endColumn":31,"fix":{"range":[75000,75001],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2390,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2390,"endColumn":41,"fix":{"range":[75310,75311],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .price on an `any` value.","line":2406,"column":36,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2406,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .symbol on an `any` value.","line":2407,"column":36,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":2407,"endColumn":42},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2414,"column":40,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2414,"endColumn":56,"fix":{"range":[75960,75961],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2440,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2440,"endColumn":46,"fix":{"range":[76734,76735],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":2443,"column":24,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":2443,"endColumn":26,"suggestions":[{"messageId":"removeAsync","fix":{"range":[76799,76805],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":2451,"column":16,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":2451,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2454,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2454,"endColumn":37,"fix":{"range":[77155,77156],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2458,"column":16,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2458,"endColumn":18,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[77279,77281],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":2459,"column":16,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":2459,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2462,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2462,"endColumn":13,"fix":{"range":[77442,77443],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2466,"column":16,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2466,"endColumn":18,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[77636,77638],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2476,"column":28,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2476,"endColumn":30,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[78038,78040],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2482,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2482,"endColumn":37,"fix":{"range":[78170,78171],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2500,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2500,"endColumn":37,"fix":{"range":[78507,78508],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":2517,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":2517,"endColumn":37,"fix":{"range":[78867,78868],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-function-type","severity":2,"message":"The `Function` type accepts any function-like value.\nPrefer explicitly defining any function parameters and return type.","line":2546,"column":67,"nodeType":"Identifier","messageId":"bannedFunctionType","endLine":2546,"endColumn":75},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a `Function` typed value.","line":2551,"column":5,"nodeType":"Identifier","messageId":"unsafeCall","endLine":2551,"endColumn":8},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2551,"column":8,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2551,"endColumn":10,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[79516,79518],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-function-type","severity":2,"message":"The `Function` type accepts any function-like value.\nPrefer explicitly defining any function parameters and return type.","line":2560,"column":18,"nodeType":"Identifier","messageId":"bannedFunctionType","endLine":2560,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2562,"column":25,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":2562,"endColumn":27,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[79760,79762],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a `Function` typed value.","line":2568,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":2568,"endColumn":20},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2568,"column":15,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":2568,"endColumn":17,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[80003,80005],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2568,"column":20,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2568,"endColumn":22,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[80008,80010],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":2569,"column":11,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":2569,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a `Function` typed value.","line":2576,"column":7,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":2576,"endColumn":16},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2576,"column":11,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":2576,"endColumn":13,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[80187,80189],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":2576,"column":16,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":2576,"endColumn":18,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[80192,80194],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":2577,"column":7,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":2577,"endColumn":14},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'reject' is defined but never used. Allowed unused args must match /^_/u.","line":2584,"column":38,"nodeType":"Identifier","messageId":"unusedVar","endLine":2584,"endColumn":44},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":2584,"column":46,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":2584,"endColumn":48,"suggestions":[{"messageId":"removeAsync","fix":{"range":[80356,80362],"text":""},"desc":"Remove 'async'."}]}],"suppressedMessages":[],"errorCount":335,"fatalErrorCount":0,"warningCount":120,"fixableErrorCount":256,"fixableWarningCount":0,"source":"import { strict as assert } from \"assert\";\nimport * as fs from \"fs\";\nimport {\n //@ts-ignore\n describe,\n test,\n} from \"node:test\";\nimport {\n ABORTABLE_METHODS,\n SubscriptionHandler,\n getSerialisableError,\n innerJoin,\n leftJoin,\n pickKeys,\n type AnyObject,\n type CaseSelect,\n type DBHandler,\n type SQLHandler,\n} from \"prostgles-types\";\nimport { DBOFullyTyped } from \"../dist/DBSchemaBuilder/DBSchemaBuilder\";\nimport type { DBHandlerClient } from \"./client\";\nimport type { DBGeneratedSchema } from \"./DBGeneratedSchema\";\nimport type { DBHandlerServer } from \"../dist\";\n\nexport const isomorphicQueries = async (\n db: DBOFullyTyped | DBHandlerClient,\n sql: SQLHandler | undefined,\n log: (msg: string, extra?: any) => void,\n token?: string,\n) => {\n log(\"Starting isomorphic queries\");\n\n const getTriggers = async () => {\n const currentTriggers = await sql!(\n `\n SELECT table_name, condition, columns_info, table_condition_id, inserted, id, condition_hash, app_id \n FROM prostgles.v_triggers\n `,\n {},\n { returnType: \"rows\" },\n );\n return currentTriggers as {\n table_name: string;\n condition: string;\n table_condition_id: number;\n columns_info: null | {\n tracked_columns: Record<string, 1 | 2>;\n };\n }[];\n };\n\n const expectNoTriggers = async () => {\n await tout(2500); // this should be higher than the 1k timeout in deleteOrphanedTriggers\n\n const currentTriggers = await getTriggers();\n assert.equal(\n currentTriggers.length,\n 0,\n `No triggers should be active but found ${JSON.stringify(currentTriggers)}`,\n );\n };\n\n const isServer = !!(db.items as any).dboBuilder;\n await describe(\"Isomorphic queries\", async () => {\n await test(\"Deleting stale data\", async () => {\n const itemsCount = await db.items.count?.();\n if (itemsCount) {\n log(\"DELETING items\");\n\n /* Access controlled */\n await db.items4.delete!({});\n\n await db.items4_pub.delete!({});\n await db.items3.delete!({});\n await db.items2.delete!({});\n await db.items.delete!({});\n }\n await sql!(`TRUNCATE items RESTART IDENTITY CASCADE;`);\n await sql!(`TRUNCATE users_public_info RESTART IDENTITY CASCADE;`);\n });\n\n await test(\"Error structure malformed array literal\", async () => {\n const errFind = await db.items.find?.({ h: \"a\" }).catch((err) => err);\n const errCount = await db.items.count?.({ h: \"a\" }).catch((err) => err);\n const errSize = await db.items.size?.({ h: \"a\" }).catch((err) => err);\n const errFindOne = await db.items.findOne?.({ h: \"a\" }).catch((err) => err);\n const errDelete = await db.items.delete?.({ h: \"a\" }).catch((err) => err);\n const errUpdate = await db.items.update?.({}, { h: \"a\" }).catch((err) => err);\n const errUpdateBatch = await db.items.updateBatch?.([[{}, { h: \"a\" }]]).catch((err) => err);\n const errUpsert = await db.items.upsert?.({}, { h: \"a\" }).catch((err) => err);\n const errInsert = await db.items.insert?.({ h: \"a\" }).catch((err) => err);\n const errSubscribe = await db.items\n .subscribe?.({ h: \"a\" }, {}, console.warn)\n .catch((err) => err);\n const errSubscribeOne = await db.items\n .subscribeOne?.({ h: \"a\" }, {}, console.warn)\n .catch((err) => err);\n\n for (const [index, err] of [\n errFind,\n errCount,\n errSize,\n errFindOne,\n errDelete,\n errInsert,\n errUpdate,\n errUpdateBatch,\n errUpsert,\n errSubscribe,\n errSubscribeOne,\n ].entries()) {\n const clientOnlyError = {\n message: 'malformed array literal: \"a\"',\n name: \"error\",\n code: \"22P02\",\n code_info: \"invalid_text_representation\",\n severity: \"ERROR\",\n };\n if (isServer || sql) {\n const allKeys = [\n \"message\",\n \"code\",\n \"name\",\n \"severity\",\n \"detail\",\n \"query\",\n \"length\",\n \"position\",\n \"file\",\n \"line\",\n \"routine\",\n \"code_info\",\n ];\n assert.deepStrictEqual(Object.keys(err ?? {}).sort(), allKeys.sort(), \"index: \" + index);\n assert.deepStrictEqual(pickKeys(err, Object.keys(clientOnlyError)), clientOnlyError);\n assert.equal(typeof err.detail, \"string\");\n assert.equal(typeof err.query, \"string\");\n assert.equal(typeof err.length, \"number\");\n assert.equal(typeof err.position, \"string\");\n assert.equal(typeof err.file, \"string\");\n assert.equal(typeof err.line, \"string\");\n assert.equal(typeof err.routine, \"string\");\n assert.equal(typeof err.code_info, \"string\");\n } else {\n // TODO: ensure this runs\n assert.deepStrictEqual(!!sql, false);\n assert.deepStrictEqual(err, clientOnlyError);\n }\n }\n });\n\n await test(\"Table info\", async () => {\n const {\n /** Excluded because their value may vary */\n oid,\n isFileTable,\n publishInfo,\n ...tableInfo\n } = (await db.items.getInfo?.()) ?? {};\n assert.deepStrictEqual(tableInfo, {\n clientSchemaTest: {\n sid: token,\n tableIndex: 0,\n },\n comment: null,\n label: \"items\",\n qualifiedNameParts: {\n name: \"items\",\n schema: \"public\",\n },\n isView: false,\n hasFiles: false,\n fileTableName: \"files\",\n dynamicRules: {\n update: false,\n },\n uniqueColumnGroups: [[\"id\"]],\n });\n });\n\n await test(\"Prepare data\", async () => {\n if (!sql) throw \"sql missing\";\n\n await db.items.delete!();\n await db.items2.delete!();\n\n const res = await db.items.insert!([{ name: \"a\" }, { name: \"a\" }, { name: \"b\" }], {\n returning: \"*\",\n });\n assert.equal(res.length, 3);\n const added1 = \"04 Dec 1995 00:12:00\";\n const added2 = \"04 Dec 1996 00:12:00\";\n const added3 = \"04 Dec 1997 00:12:00\";\n\n await db.items2.insert!([{ name: \"a\", items_id: res[0]!.id }]);\n await db.items3.insert!([{ name: \"a\" }, { name: \"za123\" }]);\n await db.items4.insert!([\n { name: \"abc1\", public: \"public data\", added: added1 },\n { name: \"abc2\", public: \"public data\", added: added1 },\n { name: \"abcd\", public: \"public data d\", added: added2 },\n ]);\n await db[`prostgles_test.basic1`].insert!({\n id_basic: { txt: \"basic\" },\n txt: \"basic1\",\n });\n await sql(`REFRESH MATERIALIZED VIEW prostgles_test.mv_basic1;`);\n assert.deepStrictEqual(\n await db[\"prostgles_test.mv_basic1\"].find!(),\n await db[\"prostgles_test.basic1\"].find!(),\n );\n\n /* Ensure */\n await db[`\"*\"`].insert!([{ \"*\": \"a\" }, { \"*\": \"a\" }, { \"*\": \"b\" }]);\n await db[`\"\"\"*\"\"\"`].insert!([{ [`\"*\"`]: \"a\" }, { [`\"*\"`]: \"a\" }, { [`\"*\"`]: \"b\" }]);\n\n await db.various.insert!([\n { name: \"abc9\", added: added1, jsn: { a: { b: 2 } } },\n { name: \"abc1\", added: added2, jsn: { a: { b: 3 } } },\n { name: \"abc81 here\", added: added3, jsn: { a: { b: 2 } } },\n ]);\n\n await sql(\"TRUNCATE files CASCADE\");\n });\n\n await test(\"Test bytea\", async () => {\n await db.bytea_test.delete!();\n\n const value = new Uint8Array([0, 1, 127, 255]).buffer;\n const inserted = await db.bytea_test.insert!({ value }, { returning: \"*\" });\n const newRow = await db.bytea_test.findOne!();\n\n // TODO: do not use cte and json in runInsertUpdateQuery.ts because it will convert the buffer to string\n assert.deepStrictEqual(new Uint8Array(inserted!.value), new Uint8Array(value));\n assert.deepStrictEqual(new Uint8Array(newRow!.value), new Uint8Array(value));\n });\n\n await test(\"abortSignal terminates a running query\", async () => {\n const tableHandler = db.slow_items;\n const firstStart = Date.now();\n await tableHandler.find?.();\n assert(Date.now() - firstStart > 4_000, \"slow_items.find should take more than 4 second\");\n\n for (const method of ABORTABLE_METHODS) {\n const start = Date.now();\n\n await assert.rejects(tableHandler[method]!({}, { abortSignal: AbortSignal.timeout(100) }));\n\n assert(\n Date.now() - start < 2_000,\n method + \" did not abort before the slow query completed\",\n );\n }\n\n const abortError = await tableHandler\n .find?.({}, { abortSignal: AbortSignal.timeout(100) })\n .catch((err) => err);\n assert.deepStrictEqual(\n { message: abortError.message },\n {\n message: \"canceling statement due to user request\",\n },\n \"abortSignal error message is not as expected\",\n );\n });\n\n await test(\"Client queries are aborted no more than after n seconds\", async () => {\n if (isServer) {\n return;\n }\n const tableHandler = db.very_slow_items;\n const start1 = Date.now();\n await assert.rejects(tableHandler.find!({}, { abortSignal: AbortSignal.timeout(12_000) }));\n assert(\n Date.now() - start1 < 9_000,\n \"very_slow_items.find should abort before the slow query completed\",\n );\n\n const start2 = Date.now();\n await assert.rejects(tableHandler.find!());\n assert(\n Date.now() - start2 < 9_000,\n \"very_slow_items.find should abort before the slow query completed\",\n );\n });\n\n await test(\"Subscription tracked_columns get merged correctly\", async () => {\n if (!isServer) {\n // Client forbids name select\n return;\n }\n const sub1 = await db.items4.subscribe!({}, { select: { name: 1 } }, () => {});\n const triggers1 = (await getTriggers()).filter((t) => t.table_name === \"items4\");\n assert.equal(triggers1.length, 1);\n assert.deepStrictEqual(triggers1[0].columns_info?.tracked_columns, { name: 1 });\n const sub2 = await db.items4.subscribe!({}, { select: { public: 1 } }, () => {});\n const triggers2 = (await getTriggers()).filter((t) => t.table_name === \"items4\");\n assert.equal(triggers2.length, 1);\n assert.deepStrictEqual(triggers2[0].columns_info?.tracked_columns, { name: 1, public: 1 });\n await sub1.unsubscribe();\n await sub2.unsubscribe();\n });\n\n await test(\"Aggregate subscription tracks FILTER and ORDER BY dependencies\", async () => {\n const ids = [501, 502];\n await db.various.delete!({ id: { $in: ids } });\n await db.various.insert!([\n { id: ids[0], name: \"included\", added: \"2020-01-01\" },\n { id: ids[1], name: \"excluded\", added: \"2021-01-01\" },\n ]);\n\n const results: AnyObject[] = [];\n const sub = await db.various.subscribe!(\n { id: { $in: ids } },\n {\n select: {\n ids: {\n $array_agg: [\"id\"],\n $filter: { $filter: [{ $upper: [\"name\"] }, \"=\", \"INCLUDED\"] },\n $orderBy: { added: 1 },\n },\n count: {\n $count: [],\n $filter: {\n $term_highlight: [[\"name\"], \"included\", { returnType: \"boolean\" }],\n },\n },\n },\n },\n ([result]) => {\n if (result) results.push(result);\n },\n );\n\n await tout(300);\n assert.deepStrictEqual(results.at(-1), { ids: [ids[0]], count: \"1\" });\n\n await db.various.update!({ id: ids[1] }, { name: \"included\" });\n await tout(300);\n assert.deepStrictEqual(results.at(-1), { ids, count: \"2\" });\n\n await db.various.update!({ id: ids[0] }, { added: \"2022-01-01\" });\n await tout(300);\n assert.deepStrictEqual(results.at(-1), {\n ids: ids.slice().reverse(),\n count: \"2\",\n });\n\n await sub.unsubscribe();\n await db.various.delete!({ id: { $in: ids } });\n });\n\n await test(\"CASE select and subscription dependencies\", async () => {\n const ids = [503, 504];\n await db.various.delete!({ id: { $in: ids } });\n await db.various.insert!([\n { id: ids[0], name: \"first\" },\n { id: ids[1], name: \"second\" },\n ]);\n\n const caseSelect = {\n label: {\n $case: [\n [{ name: \"first\" }, \"it's first\"],\n [{ name: \"second\" }, \"second\"],\n ],\n $else: \"other\",\n },\n nullable: {\n $case: [[{ name: \"missing\" }, \"found\"]],\n },\n } satisfies Record<string, CaseSelect>;\n const rows = await db.various.find!(\n { id: { $in: ids } },\n { select: caseSelect, orderBy: { id: 1 } },\n );\n assert.deepStrictEqual(rows, [\n { label: \"it's first\", nullable: null },\n { label: \"second\", nullable: null },\n ]);\n\n const results: AnyObject[] = [];\n const sub = await db.various.subscribe!(\n { id: ids[0] },\n { select: caseSelect },\n ([result]) => {\n if (result) results.push(result);\n },\n );\n await tout(300);\n assert.deepStrictEqual(results.at(-1), {\n label: \"it's first\",\n nullable: null,\n });\n\n await db.various.update!({ id: ids[0] }, { name: \"changed\" });\n await tout(300);\n assert.deepStrictEqual(results.at(-1), {\n label: \"other\",\n nullable: null,\n });\n\n await sub.unsubscribe();\n await db.various.delete!({ id: { $in: ids } });\n });\n\n await test(\"Subscription tracks non-selected ORDER BY columns\", async () => {\n const ids = [511, 512];\n await db.various.delete!({ id: { $in: ids } });\n await db.various.insert!([\n { id: ids[0], name: \"first\", added: \"2020-01-01\" },\n { id: ids[1], name: \"second\", added: \"2021-01-01\" },\n ]);\n\n const results: AnyObject[] = [];\n const sub = await db.various.subscribe!(\n { id: { $in: ids } },\n { select: { name: 1 }, orderBy: { added: 1 }, limit: 1 },\n ([result]) => {\n if (result) results.push(result);\n },\n );\n\n await tout(300);\n assert.deepStrictEqual(results.at(-1), { name: \"first\" });\n\n await db.various.update!({ id: ids[1] }, { added: \"2019-01-01\" });\n await tout(300);\n assert.deepStrictEqual(results.at(-1), { name: \"second\" });\n\n await sub.unsubscribe();\n await db.various.delete!({ id: { $in: ids } });\n });\n\n const json = {\n a: true,\n arr: \"2\",\n arr1: 3,\n arr2: [1],\n arrStr: [\"1123.string\"],\n };\n await test(\"merge json\", async () => {\n const inserted = await db.tjson.insert!({ colOneOf: \"a\", json }, { returning: \"*\" });\n const res = await db.tjson.update!(\n { colOneOf: \"a\" },\n { json: { $merge: [{ a: false }] } },\n { returning: \"*\" },\n );\n assert.deepStrictEqual(res?.[0].json, { ...json, a: false });\n });\n\n await test(\"json array converted to pg array filter bug\", async () => {\n const result = await db.tjson.find!({ json: [2] });\n assert.deepStrictEqual(result, []);\n });\n\n await test(\"onConflict do update\", async () => {\n const initial = await db.items4.insert!(\n { id: -99, name: \"onConflict\", public: \"onConflict\" },\n { returning: \"*\" },\n );\n const updated = await db.items4.insert!(\n { id: -99, name: \"onConflict\", public: \"onConflict2\" },\n { onConflict: \"DoUpdate\", returning: \"*\" },\n );\n assert.equal(initial.id, -99);\n assert.equal(initial.public, \"onConflict\");\n assert.equal(updated.id, -99);\n assert.equal(updated.public, \"onConflict2\");\n await db.items4.delete!({ id: -99 });\n });\n\n const fileFolder = `${__dirname}/../../server/dist/server/media/`;\n const fileName = \"sample_file.txt\";\n await test(\"Local file upload\", async () => {\n let str = \"This is a string\",\n data = Buffer.from(str, \"utf-8\"),\n mediaFile = { data, original_name: fileName };\n\n /** Ensure the types are ok */\n const file = await (\n db as DBOFullyTyped<DBGeneratedSchema> | DBHandlerClient<DBGeneratedSchema>\n ).files.insert!(mediaFile, { returning: \"*\" });\n const _data = fs.readFileSync(fileFolder + file.storage_key);\n assert.equal(str, _data.toString(\"utf8\"));\n assert.deepStrictEqual((await db.files.findOne!())!.metadata, {\n description: \"Updated by afterEach hook\",\n });\n await tryRun(\"Nested insert\", async () => {\n const nestedInsert = await db.users_public_info.insert!(\n { name: \"some_user\", avatar: mediaFile },\n { returning: \"*\" },\n );\n const { name, avatar } = nestedInsert;\n const { extension, content_type, original_name } = avatar;\n assert.deepStrictEqual(\n { extension, content_type, original_name },\n {\n extension: \"txt\",\n content_type: \"text/plain\",\n original_name: \"sample_file.txt\",\n },\n );\n\n assert.equal(name, \"some_user\");\n });\n });\n\n await test(\"Local file delete\", async () => {\n const file = {\n data: Buffer.from(\"str\", \"utf-8\"),\n original_name: \"will delete.txt\",\n };\n await db.files.insert!(file);\n\n const files = await db.files.find!({ original_name: file.original_name });\n assert.equal(files.length, 1);\n const exists0 = fs.existsSync(fileFolder + files[0].storage_key);\n assert.equal(exists0, true);\n await db.files.delete!({ original_name: file.original_name }, { returning: \"*\" });\n const exists = fs.existsSync(fileFolder + files[0].storage_key);\n assert.equal(exists, false);\n });\n\n await test(\"Local file update\", async () => {\n const initialStr = \"str\";\n const newStr = \"str new\";\n const file = {\n data: Buffer.from(initialStr, \"utf-8\"),\n original_name: \"will update.txt\",\n };\n const newFile = {\n data: Buffer.from(newStr, \"utf-8\"),\n original_name: \"will update new.txt\",\n original_last_modified: new Date().toISOString(),\n };\n await db.files.insert!(file);\n const originals = await db.files.find!({ original_name: file.original_name });\n assert.equal(originals.length, 1);\n const [original] = originals;\n const initialFileStr = fs.readFileSync(fileFolder + original.storage_key).toString(\"utf8\");\n assert.equal(initialStr, initialFileStr);\n assert.equal(original.url, [\"/files\", original.id].join(\"/\"));\n\n if (token) {\n const headers = new Headers({\n Authorization: `Bearer ${Buffer.from(token, \"utf-8\").toString(\"base64\")}`,\n });\n const fileText = await fetch(\"http://localhost:3001\" + original.url, { headers }).then(\n (r) => r.text(),\n );\n assert.equal(initialStr, fileText);\n }\n\n await db.files.update!({ id: original.id }, newFile);\n\n const newF = await db.files.findOne!({ id: original.id });\n const newFileStr = fs.readFileSync(fileFolder + newF?.storage_key).toString(\"utf8\");\n assert.equal(newStr, newFileStr);\n\n assert.equal(newF?.original_name, newFile.original_name);\n });\n\n await test(\"getColumns definition\", async () => {\n const res = await db.tr2.getColumns!(\"fr\");\n const expected = [\n {\n label: \"Id\",\n name: \"id\",\n data_type: \"integer\",\n udt_name: \"int4\",\n element_type: null,\n is_updatable: true,\n element_udt_name: null,\n is_pkey: true,\n column_default: null,\n comment: null,\n ordinal_position: 1,\n is_generated: false,\n is_nullable: false,\n references: null,\n has_default: true,\n tsDataType: \"number\",\n insert: true,\n select: true,\n numeric_precision: 32,\n numeric_scale: 0,\n orderBy: true,\n filter: true,\n update: true,\n delete: true,\n },\n {\n label: \"Tr1 id\",\n name: \"tr1_id\",\n data_type: \"integer\",\n udt_name: \"int4\",\n element_type: null,\n is_updatable: true,\n element_udt_name: null,\n is_pkey: false,\n column_default: null,\n comment: null,\n ordinal_position: 2,\n is_generated: false,\n is_nullable: true,\n references: [\n {\n ftable: \"tr1\",\n fcols: [\"id\"],\n cols: [\"tr1_id\"],\n },\n ],\n has_default: false,\n tsDataType: \"number\",\n insert: true,\n select: true,\n numeric_precision: 32,\n numeric_scale: 0,\n orderBy: true,\n filter: true,\n update: true,\n delete: true,\n },\n {\n label: \"fr_t1\",\n hint: \"hint...\",\n min: \"a\",\n max: \"b\",\n name: \"t1\",\n data_type: \"text\",\n udt_name: \"text\",\n element_type: null,\n is_updatable: true,\n element_udt_name: null,\n is_pkey: false,\n column_default: null,\n comment: null,\n ordinal_position: 3,\n is_generated: false,\n is_nullable: true,\n references: null,\n has_default: false,\n tsDataType: \"string\",\n insert: true,\n select: true,\n orderBy: true,\n filter: true,\n update: true,\n delete: true,\n },\n {\n label: \"en_t2\",\n name: \"t2\",\n data_type: \"text\",\n udt_name: \"text\",\n element_type: null,\n is_updatable: true,\n element_udt_name: null,\n is_pkey: false,\n column_default: null,\n comment: null,\n ordinal_position: 4,\n is_generated: false,\n is_nullable: true,\n references: null,\n has_default: false,\n tsDataType: \"string\",\n insert: true,\n select: true,\n orderBy: true,\n filter: true,\n update: true,\n delete: true,\n },\n ];\n\n assert.deepStrictEqual(res, expected);\n const resDynamic = await db.tr2.getColumns!(\"fr\", {\n rule: \"update\",\n filter: {},\n });\n assert.deepStrictEqual(resDynamic, expected);\n });\n\n await test(\"returnType\", async () => {\n const whereStatement = await db.tr1.find!({ t1: \"a\" }, { returnType: \"statement-where\" });\n\n assert.equal(whereStatement, `\"t1\" = 'a'`);\n });\n\n await test(\"Table config triggers\", async () => {\n const tr1 = await db.tr1.insert!({});\n const tr2 = await db.tr2.insert!({\n tr1_id: 1,\n t1: \"a\",\n t2: \"b\",\n });\n try {\n await db.tr2.delete!();\n } catch (e) {}\n const one = await db.tr2.findOne!({\n t1: \"a\",\n t2: \"b\",\n });\n if (!one) {\n throw \"Row missing\";\n }\n });\n\n await test(\"$unnest_words\", async () => {\n const res = await db.various.find!(\n {},\n { returnType: \"values\", select: { name: \"$unnest_words\" } },\n );\n\n assert.deepStrictEqual(res, [\"abc9\", \"abc1\", \"abc81\", \"here\"]);\n });\n\n /**\n * Group by/Distinct\n */\n await test(\"Group by/Distinct\", async () => {\n const res = await db.items.find!({}, { select: { name: 1 }, groupBy: true });\n const resV = await db.items.find!(\n {},\n { select: { name: 1 }, groupBy: true, returnType: \"values\" },\n );\n\n assert.deepStrictEqual(res, [{ name: \"a\" }, { name: \"b\" }]);\n assert.deepStrictEqual(resV, [\"a\", \"b\"]);\n });\n\n await test(\"sql returntype default-with-rollback\", async () => {\n const item = { name: \"a\" };\n const res = await sql!(\n \"delete from items2 returning name; \",\n {},\n { returnType: \"default-with-rollback\" },\n );\n assert.deepEqual(res.rows, [item]);\n const count = await db.items2.count!();\n assert.equal(count, 1);\n\n const testCreateTable = async (\n createTableQuery: string,\n commited: boolean,\n expectExist?: boolean,\n ) => {\n const commitedTableName = \"__rb_test_commit\";\n await sql!(`DROP TABLE IF EXISTS public.\\${commitedTableName:raw}`, { commitedTableName });\n\n const expectTableToExist = async (exists: boolean) => {\n const probeCount = await sql!(\n `SELECT to_regclass('public.\\${commitedTableName:raw}')::text AS \\${commitedTableName:raw};`,\n {\n commitedTableName,\n },\n { returnType: \"rows\" },\n );\n assert.deepEqual(probeCount, [\n { [commitedTableName]: exists ? commitedTableName : null },\n ]);\n };\n\n await expectTableToExist(false);\n await sql!(\n createTableQuery,\n {\n commitedTableName,\n },\n { returnType: commited ? undefined : \"default-with-rollback\" },\n );\n\n await expectTableToExist(expectExist ?? commited);\n\n if (commited) {\n await sql!(`DROP TABLE IF EXISTS public.${commitedTableName}`);\n }\n };\n\n const nonNestedTransaction = `CREATE TABLE public.\\${commitedTableName:raw}(id int);`;\n await testCreateTable(nonNestedTransaction, true);\n await testCreateTable(nonNestedTransaction, false);\n\n const nestedTransaction = `\n BEGIN; \n CREATE TABLE public.\\${commitedTableName:raw}(id int); \n COMMIT;\n `;\n await testCreateTable(nestedTransaction, true);\n await testCreateTable(nestedTransaction, false, true);\n });\n\n /**\n * returnType \"value\"\n */\n await test(\"returnType: value\", async () => {\n const resVl = await db.items.find!(\n {},\n { select: { name: { $array_agg: [\"name\"] } }, returnType: \"value\" },\n );\n\n assert.deepStrictEqual(resVl, [\"a\", \"a\", \"b\"]);\n });\n\n await test(\"PostgreSQL array element\", async () => {\n const id = -100;\n await db.items.insert!({ id, name: \"array element\", h: [\"a1\", \"a2\"] });\n const result = await (async () => {\n try {\n return await db.items.findOne!(\n { id },\n { select: { second: { $array_element: [\"h\", 2] } } },\n );\n } finally {\n await db.items.delete!({ id });\n }\n })();\n\n assert.deepStrictEqual(result, { second: \"a2\" });\n });\n\n /**\n * TODO -> ADD ALL FILTER TYPES\n */\n await test(\"FTS filtering\", async () => {\n const res = await db.various.count!({ \"tsv.@@.to_tsquery\": [\"a\"] });\n assert.equal(res, 0);\n\n const d = await db.various.findOne!(\n { \"name.@@.to_tsquery\": [\"abc81\"] },\n {\n select: {\n h: { $ts_headline_simple: [\"name\", { plainto_tsquery: \"abc81\" }] },\n hh: { $ts_headline: [\"name\", \"abc81\"] },\n added: \"$year\" as \"$max\",\n addedY: { $date: [\"added\"] },\n },\n },\n );\n // console.log(d);\n await db.various.findOne!(\n {},\n {\n select: {\n h: { $ts_headline_simple: [\"name\", { plainto_tsquery: \"abc81\" }] },\n hh: { $ts_headline: [\"name\", \"abc81\"] },\n added: \"$year\" as \"$max\",\n addedY: { $date: [\"added\"] },\n },\n },\n );\n\n /*\n * Dates become strings after reaching client.\n * Serialize col dataTypes and then recast ??\n */\n assert.deepStrictEqual(JSON.parse(JSON.stringify(d)), {\n h: \"<b>abc81</b> here\",\n hh: \"<b>abc81</b> here\",\n added: \"1997\",\n addedY: \"1997-12-04\",\n });\n });\n\n await test(\"$term_highlight\", async () => {\n const term = \"abc81\";\n const res = await db.various.find!(\n { \"hIdx.>\": -2 },\n {\n select: {\n h: { $term_highlight: [[\"name\"], term, {}] },\n hFull: { $term_highlight: [\"*\", \"81\", {}] },\n hOrdered: { $term_highlight: [[\"name\", \"id\"], \"81\", {}] },\n hIdx: {\n $term_highlight: [[\"name\"], term, { returnType: \"index\" }],\n },\n hBool: {\n $term_highlight: [[\"name\"], term, { returnType: \"boolean\" }],\n },\n hObj: {\n $term_highlight: [[\"name\"], term, { returnType: \"object\" }],\n },\n hObjAll: { $term_highlight: [\"*\", term, { returnType: \"object\" }] },\n },\n orderBy: { hIdx: -1 },\n },\n );\n\n assert.deepStrictEqual(res[0], {\n h: [\"name: \", [\"abc81\"], \" here\"],\n\n /* Search all allowed fields using \"*\" */\n hFull: [\n \"id: 3, h: , name: abc\",\n [\"81\"],\n ' here, tsv: , jsn: {\"a\":{\"b\":2}}, added: 1997-12-04 00:12:00',\n ],\n\n /* Search specific fields in specific order */\n hOrdered: [\"name: abc\", [\"81\"], \" here, id: 3\"],\n hIdx: 6,\n hBool: true,\n hObj: {\n name: [\"\", [\"abc81\"], \" here\"],\n },\n hObjAll: {\n name: [\"\", [\"abc81\"], \" here\"],\n },\n });\n });\n\n await test(\"funcFilters: $term_highlight\", async () => {\n const term = \"abc81\";\n const res = await db.various.count!({\n $term_highlight: [[\"*\"], term, { returnType: \"boolean\" }],\n });\n assert.equal(+res, 1);\n });\n\n const testToEnsureTriggersAreDisabled = async (\n sub: SubscriptionHandler,\n table_name: string,\n ) => {\n const getTableTriggers = async (table_name: string) => {\n return (await sql?.(\n `\n SELECT tgname, tgenabled = 'O' as enabled \n FROM pg_catalog.pg_trigger \n WHERE tgname like format('prostgles_triggers_%s_', \\${table_name}) || '%'\n `,\n { table_name },\n { returnType: \"rows\" },\n )) as { tgname: string; enabled: boolean }[];\n };\n let validTriggers = await getTableTriggers(table_name);\n console.log(\"unsubscribe start - \" + table_name);\n await sub.unsubscribe();\n console.log(\"unsubscribe end - \" + table_name);\n assert.equal(\n validTriggers.filter((t) => t.enabled).length,\n 3,\n `3 Triggers should be enabled: \\n${JSON.stringify(\n {\n table_name,\n filter: sub.filter,\n validTriggers,\n },\n null,\n 2,\n )}`,\n );\n await sql?.(`DELETE FROM prostgles.app_triggers`, []);\n validTriggers = await getTableTriggers(table_name);\n assert.equal(validTriggers.length, 3, \"3 Triggers should exist but be disabled\");\n assert.equal(validTriggers.filter((t) => t.enabled).length, 0);\n };\n\n const variousId99 = { id: 99 };\n await test(\"subscribe skipChangedColumnsCheck false by default = sub should not fire if selected data did not change\", async () => {\n await db.various.delete!(variousId99);\n await db.various.insert!(variousId99);\n let runs = 0;\n const sub = await db.various.subscribe!(variousId99, { select: { name: 1 } }, async (d) => {\n log(JSON.stringify(d));\n runs++;\n });\n await db.various.update!(variousId99, { name: \"zz3zz1\" });\n await tout(200);\n assert.equal(runs, 2, \"First update!\");\n await db.various.update!(variousId99, { name: \"zz3zz1\" });\n await tout(200);\n assert.equal(runs, 2, \"Updating to same value\"); // No change\n await db.various.update!(variousId99, { tsv: \"hehe\" });\n await tout(200);\n assert.equal(runs, 2, \"Updating other col\"); // Still no change to the selected data\n await db.various.delete!(variousId99);\n await tout(200);\n assert.equal(runs, 3, \"Delete should trigger\");\n await sub.unsubscribe();\n });\n\n await test(\"subscribe skipChangedColumnsCheck true\", async () => {\n await db.various.delete!(variousId99);\n await db.various.insert!(variousId99);\n await expectNoTriggers();\n let runs = 0;\n const sub = await db.various.subscribe!(\n variousId99,\n { select: { name: 1 }, skipChangedColumnsCheck: true },\n async (d) => {\n log(JSON.stringify(d));\n runs++;\n },\n );\n await db.various.update!(variousId99, { name: \"zz3zz1\" });\n // const trgs = await sql!(\n // `SELECT * FROM prostgles.v_triggers WHERE table_name = 'various'`,\n // {},\n // { returnType: \"rows\" },\n // );\n // assert.deepStrictEqual(trgs, {}, \"There should be no triggers before starting the test\");\n await tout(200);\n assert.equal(runs, 2);\n await db.various.update!(variousId99, { name: \"zz3zz1\" });\n await tout(200);\n assert.equal(runs, 3);\n await db.various.update!(variousId99, { tsv: \"hehe\" });\n await tout(200);\n assert.equal(runs, 4);\n await db.various.delete!(variousId99);\n await tout(200);\n assert.equal(runs, 5);\n await sub.unsubscribe();\n });\n\n await test(\"subscribe\", async () => {\n await tryRunP(\n \"subscribe\",\n async (resolve, reject) => {\n await db.various.insert!(variousId99);\n const sub = await db.various.subscribe!(variousId99, {}, async ([item]) => {\n if (item?.name === \"zz3zz3\") {\n await db.various.delete!({ name: \"zz3zz3\" });\n await testToEnsureTriggersAreDisabled(sub, \"various\");\n resolve(true);\n }\n });\n await db.various.update!(variousId99, { name: \"zz3zz1\" });\n await db.various.update!(variousId99, { name: \"zz3zz2\" });\n await db.various.update!(variousId99, { name: \"zz3zz3\" });\n },\n { timeout: 4000 },\n );\n });\n\n await test(\"subscribe to schema.table\", async () => {\n await tryRunP(\"subscribe to schema.table\", async (resolve, reject) => {\n let runs = 0;\n const sub = await db[`prostgles_test.basic1`].subscribe!({}, {}, async (items) => {\n runs++;\n if (runs === 1) {\n if (items.length !== 1) {\n reject(\"Should have 1 item\");\n } else {\n await db[`prostgles_test.basic1`].insert!({\n txt: \"basic12\",\n });\n }\n } else if (runs === 2) {\n if (items.length !== 2) {\n reject(\"Should have 2 items\");\n } else {\n await sub.unsubscribe();\n resolve(true);\n }\n } else {\n reject(\"Expecting only 2 runs\");\n }\n });\n });\n });\n\n await test(\"parallel subscriptions\", async () => {\n await tryRunP(\"parallel subscriptions\", async (resolve, reject) => {\n let callbacksFired: Record<string, true> = {};\n const subscriptions = await Promise.all(\n [1, 2, 3, 4, 5].map(async (subId) => {\n const handler = await db.various.subscribe!(variousId99, {}, async (items) => {\n callbacksFired[subId] = true;\n });\n\n return {\n handler,\n };\n }),\n ).catch(reject);\n\n await tout(2000);\n await Promise.all(\n Object.values(subscriptions).map(async ({ handler }) => handler.unsubscribe()),\n );\n assert.equal(Object.keys(callbacksFired).length, 5);\n resolve(true);\n });\n });\n\n /**\n * LISTEN/NOTIFY does this:\n * \"AccessExclusiveLock on object 0 of class 1262 of database 0\" lock is acquired\n * during COMMIT queries when a transaction has previously issued a NOTIFY\n *\n * Source code comment:\n * Serialize writers by acquiring a special lock that we hold till\n * after commit. This ensures that queue entries appear in commit\n * order, and in particular that there are never uncommitted queue\n * entries ahead of committed ones, so an uncommitted transaction\n * can't block delivery of deliverable notifications.\n *\n * We use a heavyweight lock so that it'll automatically be released\n * after either commit or abort. This also allows deadlocks to be\n * detected, though really a deadlock shouldn't be possible here.\n */\n await test(\"subscriptions do not serialize transactions\", async () => {\n if (process.env.CI) {\n return;\n }\n await expectNoTriggers();\n const checkLocks = async () => {\n const locks = await sql!(\n `\n WITH locks AS (\n SELECT pid, pg_blocking_pids(pid) as blocking_pids, wait_event, wait_event_type, query, \n (\n SELECT query FROM pg_stat_activity pa\n WHERE pa.pid = ANY(pg_blocking_pids(l.pid))\n LIMIT 1\n ) as blocking_query\n FROM pg_stat_activity l\n WHERE cardinality(pg_blocking_pids(pid)) > 0\n )\n SELECT *\n FROM locks l \n `,\n {},\n { returnType: \"rows\" },\n );\n if (locks.length) {\n log(\"Locks: \" + JSON.stringify(locks));\n }\n return locks;\n };\n const updateInTx = async (id: number) => {\n await db.various.insert!({ id, name: `slowtx${id}` }, { returning: \"*\" });\n checkLocks();\n await sql!(\n `\n BEGIN;\n UPDATE various\n SET name = 'slowtx${id}'\n WHERE id = \\${id};\n SELECT pg_sleep(0.01);\n COMMIT;\n\n `,\n { id },\n );\n };\n const expectedDuration = 4000;\n const UPDATE_COUNT = 1_000;\n const updateAll = async () => {\n const start = Date.now();\n await Promise.all(Array.from({ length: UPDATE_COUNT }, (_, i) => i + 1000).map(updateInTx));\n const duration = Date.now() - start;\n log(\"updateAll done in \" + duration);\n await db.various.delete!({ id: { \">\": 100 } });\n return duration;\n };\n const duration1 = await updateAll();\n const duration11 = await updateAll();\n assert.equal(\n duration1 < expectedDuration,\n true,\n `Update should take less than ${expectedDuration} seconds but took ${duration1}`,\n );\n const callOffsets: number[] = [];\n const start = Date.now();\n const sub = await db.various.subscribe!({ id: { \">\": -1 } }, {}, async (_items) => {\n callOffsets.push(Date.now() - start);\n });\n const duration2 = await updateAll();\n await tout(2000);\n assert.equal(\n duration2 < expectedDuration,\n true,\n `Update should take less than ${expectedDuration} seconds but took ${duration2}`,\n );\n\n const callLimit = 100;\n assert.equal(\n callOffsets.length < callLimit,\n true,\n // Gets throttled due to out of order pushSubData rejections\n `Expecting callOffsets.length to be less than ${callLimit} but got ${callOffsets.length}`,\n );\n const allowedPercentage = 1;\n assert.equal(\n duration2 < duration1 + duration1 * allowedPercentage,\n true,\n `duration2 should be within ${allowedPercentage * 100}% of duration1 but got ` +\n duration2 +\n \" vs \" +\n duration1 +\n \" duration11: \" +\n duration11,\n );\n // const offetsHigherThanExpected = callOffsets.filter((offset) => offset > expectedDuration);\n // assert.equal(\n // offetsHigherThanExpected.length,\n // 0,\n // `Offsets should not be higher than ${expectedDuration}ms but found: ${offetsHigherThanExpected}`\n // );\n await sub.unsubscribe();\n });\n\n await test(\"subscribeOne with throttle\", async () => {\n await tryRunP(\n \"subscribeOne with throttle\",\n async (resolve, reject) => {\n await db.various.insert!(variousId99);\n const start = Date.now();\n const pushed: number[] = [];\n const sub = await db.various.subscribeOne!(\n variousId99,\n { throttle: 1700 },\n async (item) => {\n const now = Date.now();\n pushed.push(now - start);\n if (pushed.length && pushed[0] > 400) {\n reject(\"First item run should not be throttled\", pushed);\n return;\n }\n if (item && item.name === \"zz3zz2\" && now - start > 1600 && now - start < 1800) {\n await db.various.delete!({ name: \"zz3zz2\" });\n sub.unsubscribe();\n resolve(true);\n }\n },\n );\n await db.various.update!(variousId99, { name: \"zz3zz1\" });\n await db.various.update!(variousId99, { name: \"zz3zz2\" });\n },\n { timeout: 4000 },\n );\n });\n\n await test(\"subscribeOne with throttle skipFirst: true\", async () => {\n await tryRunP(\n \"subscribeOne with throttle skipFirst: true\",\n async (resolve, reject) => {\n const start = Date.now();\n const pushed: number[] = [];\n const sub = await db.various.subscribeOne!(\n variousId99,\n { throttle: 1700, throttleOpts: { skipFirst: true } },\n async (item) => {\n const now = Date.now();\n pushed.push(now - start);\n if (pushed.length) {\n if (pushed[0] < 1700) {\n reject(\"First item run should be throttled\" + pushed[0], pushed);\n } else {\n await sub.unsubscribe();\n resolve(true);\n }\n }\n },\n );\n await db.various.insert!(variousId99);\n },\n { timeout: 4000 },\n );\n });\n\n await test(\"subscribeOne without skipFirst\", async () => {\n let runs = 0;\n const filter = { id: 199 };\n const sub = await db.various.subscribeOne!(filter, { skipFirst: true }, async () => {\n runs++;\n });\n await db.various.insert!(filter);\n await tout(500);\n assert.equal(runs, 1);\n await db.various.delete!(filter);\n await tout(500);\n assert.equal(runs, 2);\n await sub.unsubscribe();\n });\n\n await test(\"subscribeOne with skipFirst: true\", async () => {\n let runs = 0;\n const filter = { id: 199 };\n const sub = await db.various.subscribeOne!(filter, { skipFirst: true }, async () => {\n runs++;\n });\n await tout(500);\n assert.equal(runs, 0);\n await db.various.insert!(filter);\n await tout(500);\n assert.equal(runs, 1);\n await db.various.delete!(filter);\n await tout(500);\n assert.equal(runs, 2);\n await sub.unsubscribe();\n });\n\n await test(\"subscribeOne actions: { insert: true }\", async () => {\n let runs = 0;\n const filter = { id: 199 };\n const sub = await db.various.subscribeOne!(\n filter,\n { actions: { insert: true } },\n async () => {\n runs++;\n },\n );\n await tout(500);\n assert.deepStrictEqual(runs, 1);\n await db.various.insert!(filter);\n await tout(500);\n assert.equal(runs, 2);\n await db.various.delete!(filter);\n await tout(500);\n assert.equal(runs, 2);\n await sub.unsubscribe();\n });\n await test(\"subscribeOne actions: { insert: false }\", async () => {\n let runs = 0;\n const filter = { id: 199 };\n const sub = await db.various.subscribeOne!(\n filter,\n { actions: { insert: false } },\n async () => {\n runs++;\n },\n );\n await tout(500);\n assert.deepStrictEqual(runs, 1);\n await db.various.insert!(filter);\n await tout(500);\n assert.equal(runs, 1);\n await db.various.delete!(filter);\n assert.equal(await db.various.count!(filter), 0);\n await tout(500);\n assert.equal(runs, 2);\n await sub.unsubscribe();\n });\n\n await test(\"JSON filtering\", async () => {\n const res = await db.various.count!({ \"jsn->a->>b\": \"3\" });\n assert.equal(res, 1);\n });\n\n await test(\"Complex filtering\", async () => {\n const res = await db.various.count!({\n $and: [\n {\n $filter: [{ $year: [\"added\"] }, \"=\", \"1996\"],\n },\n {\n $filter: [{ $Mon: [\"added\"] }, \"=\", \"Dec\"],\n },\n ],\n });\n assert.equal(res, 1);\n });\n\n await test(\"template_string function\", async () => {\n const res = await db.various.findOne!(\n { name: \"abc9\" },\n { select: { tstr: { $template_string: [\"{name} is hehe\"] } } },\n );\n const res2 = await db.various.findOne!(\n { name: \"abc9\" },\n { select: { tstr: { $template_string: [\"is hehe\"] } } },\n );\n assert.equal(res?.tstr, \"abc9 is hehe\");\n assert.equal(res2?.tstr, \"is hehe\");\n });\n\n await test(\"Between filtering\", async () => {\n const res = await db.various.count!({\n added: { $between: [\"06 Dec 1995 00:12:00\", \"03 Dec 1997 00:12:00\"] },\n });\n assert.equal(res, 1);\n });\n await test(\"In filtering\", async () => {\n const res = await db.various.count!({\n added: { $in: [\"04 Dec 1996 00:12:00\"] },\n });\n assert.equal(res, 1);\n });\n\n await test(\"Order by\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: { name: 1 },\n orderBy: [{ key: \"name\", asc: false, nulls: \"first\", nullEmpty: true }],\n },\n );\n assert.deepStrictEqual(res, [{ name: \"b\" }, { name: \"a\" }, { name: \"a\" }]);\n });\n await test(\"Order by aliased func\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: { uname: { $upper: [\"name\"] }, count: { $countAll: [] } },\n orderBy: { uname: -1 },\n },\n );\n assert.deepStrictEqual(res, [\n { uname: \"B\", count: \"1\" },\n { uname: \"A\", count: \"2\" },\n ]);\n });\n await test(\"Filter by aliased func\", async () => {\n const res = await db.items.find!(\n { uname: \"B\" },\n { select: { uname: { $upper: [\"name\"] }, count: { $countAll: [] } } },\n );\n assert.deepStrictEqual(res, [{ uname: \"B\", count: \"1\" }]);\n });\n await test(\"Count with Filter by aliased func \", async () => {\n const res = await db.items.count!(\n { uname: \"A\" },\n { select: { uname: { $upper: [\"name\"] } } },\n );\n assert.deepStrictEqual(res, 2);\n });\n await test(\"Count with Aggregate and Filter by aliased func \", async () => {\n const res = await db.items.count!(\n { uname: \"A\" },\n { select: { uname: { $upper: [\"name\"] }, count: { $countAll: [] } } },\n );\n assert.deepStrictEqual(res, 1);\n });\n await test(\"Count with complex filter \", async () => {\n const res = await db.items.count!({\n $filter: [{ $upper: [\"name\"] }, \"$in\", [\"A\"]],\n });\n assert.deepStrictEqual(res, 2);\n });\n await test(\"Order by aggregation\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: { name: 1, count: { $countAll: [] } },\n orderBy: { count: -1 },\n },\n );\n assert.deepStrictEqual(res, [\n { name: \"a\", count: \"2\" },\n { name: \"b\", count: \"1\" },\n ]);\n });\n await test(\"Aggregate FILTER and ORDER BY\", async () => {\n const res = await db.items.findOne!(\n {},\n {\n select: {\n count: { $count: [], $filter: { name: \"a\" }, $orderBy: { id: -1 } },\n names: {\n $array_agg: [\"name\"],\n $filter: { name: { $in: [\"a\", \"b\"] } },\n $orderBy: { id: -1 },\n },\n },\n },\n );\n assert.deepStrictEqual(res, {\n count: \"2\",\n names: [\"b\", \"a\", \"a\"],\n });\n });\n await test(\"Column alias func\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: { label: { $column: [\"name\"] }, count: { $countAll: [] } },\n orderBy: { count: -1 },\n },\n );\n assert.deepStrictEqual(res, [\n { label: \"a\", count: \"2\" },\n { label: \"b\", count: \"1\" },\n ]);\n });\n await test(\"Order by colliding alias name\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: { name: { $countAll: [] }, n: { $left: [\"name\", 1] } },\n orderBy: { name: -1 },\n },\n );\n assert.deepStrictEqual(res, [\n { name: \"2\", n: \"a\" },\n { name: \"1\", n: \"b\" },\n ]);\n });\n\n await test(\"Update batch example\", async () => {\n await db.items4.updateBatch!([\n [{ name: \"abc1\" }, { name: \"abc\" }],\n [{ name: \"abc2\" }, { name: \"abc\" }],\n ]);\n assert.equal(await db.items4.count!({ name: \"abc\" }), 2);\n });\n\n await test(\"Function example\", async () => {\n const f = await db.items4.findOne!(\n {},\n { select: { public: 1, p_5: { $left: [\"public\", 3] } } },\n );\n assert.equal(f?.p_5?.length, 3);\n assert.equal(f?.p_5, f.public.substr(0, 3));\n\n // Nested function\n const fg = await db.items2.findOne!(\n {},\n { select: { id: 1, name: 1, items3: { name: \"$upper\" } } },\n ); // { $upper: [\"public\"] } } });\n assert.deepStrictEqual(fg, { id: 1, name: \"a\", items3: [{ name: \"A\" }] });\n\n // Date utils\n const Mon = await db.items4.findOne!(\n { name: \"abc\" },\n { select: { added: \"$Mon\" as \"$max\" } },\n );\n assert.deepStrictEqual(Mon, { added: \"Dec\" });\n\n // Date + agg\n const MonAgg = await db.items4.find!(\n { name: \"abc\" },\n { select: { added: \"$Mon\" as \"$max\", public: \"$count\" } },\n );\n assert.deepStrictEqual(MonAgg, [{ added: \"Dec\", public: \"2\" }]);\n\n // Returning\n const returningParam = {\n returning: {\n id: 1,\n name: 1,\n public: 1,\n $rowhash: 1,\n added_day: { $day: [\"added\"] },\n },\n } as const; // ctid: 1,\n let i = await db.items4_pub.insert!(\n {\n name: \"abc123\",\n public: \"public data\",\n added: \"04 Dec 1995 00:12:00\",\n },\n returningParam,\n );\n assert.deepStrictEqual(i, {\n id: 1,\n name: \"abc123\",\n public: \"public data\",\n $rowhash: \"347c26babad535aa697a794af89195fe\",\n added_day: \"monday\",\n }); // , ctid: '(0,1)'\n\n let u = await db.items4_pub.update!(\n { name: \"abc123\" },\n { public: \"public data2\" },\n returningParam,\n );\n assert.deepStrictEqual(u, [\n {\n id: 1,\n name: \"abc123\",\n public: \"public data2\",\n $rowhash: \"9d18ddfbff9e13411d13f82d414644de\",\n added_day: \"monday\",\n },\n ]);\n\n let d = await db.items4_pub.delete!({ name: \"abc123\" }, returningParam);\n assert.deepStrictEqual(d, [\n {\n id: 1,\n name: \"abc123\",\n public: \"public data2\",\n $rowhash: \"9d18ddfbff9e13411d13f82d414644de\",\n added_day: \"monday\",\n },\n ]);\n\n console.log(\"TODO: socket.io stringifies dates\");\n });\n\n await test(\"JSONB filtering\", async () => {\n const obj = { propName: 3232 };\n const row = await db.obj_table.insert!({ obj }, { returning: \"*\" });\n const sameRow = await db.obj_table.findOne!({ obj });\n const sameRow1 = await db.obj_table.findOne!({ obj: { \"=\": obj } });\n const sameRow2 = await db.obj_table.findOne!({ \"obj.=\": obj });\n const count = await db.obj_table.count!({ obj });\n assert.deepStrictEqual(row, sameRow);\n assert.deepStrictEqual(row, sameRow1);\n assert.deepStrictEqual(row, sameRow2);\n assert.deepStrictEqual(+count, 1);\n });\n\n await test(\"Postgis examples\", async () => {\n await db.shapes.delete!();\n const p1 = { $ST_GeomFromText: [\"POINT(-1 1)\", 4326] },\n p2 = { $ST_GeomFromText: [\"POINT(-2 2)\", 4326] };\n await db.shapes.insert!([\n { geom: p1, geog: p1 },\n { geom: p2, geog: p2 },\n ]);\n\n /** Basic functions and extent filters */\n const f = await db.shapes.findOne!(\n {\n $and: [\n { \"geom.&&.st_makeenvelope\": [-3, 2, -2, 2] },\n { \"geog.&&.st_makeenvelope\": [-3, 2, -2, 2] },\n ],\n },\n {\n select: {\n geomTxt: { $ST_AsText: [\"geom\"] },\n geomGeo: { $ST_AsGeoJSON: [\"geom\"] },\n },\n orderBy: \"geom\",\n },\n );\n assert.deepStrictEqual(f, {\n geomGeo: {\n coordinates: [-2, 2],\n type: \"Point\",\n },\n geomTxt: \"POINT(-2 2)\",\n });\n\n /**Aggregate functions */\n const aggs = await db.shapes.findOne!(\n {},\n {\n select: {\n xMin: { $ST_XMin_Agg: [\"geom\"] },\n xMax: { $ST_XMax_Agg: [\"geom\"] },\n yMin: { $ST_YMin_Agg: [\"geom\"] },\n yMax: { $ST_YMax_Agg: [\"geom\"] },\n zMin: { $ST_ZMin_Agg: [\"geom\"] },\n zMax: { $ST_ZMax_Agg: [\"geom\"] },\n extent: { $ST_Extent: [\"geom\"] },\n // extent3D: { \"$ST_3DExtent\": [\"geom\"] },\n },\n },\n );\n assert.deepStrictEqual(aggs, {\n xMax: -1,\n xMin: -2,\n yMax: 2,\n yMin: 1,\n zMax: 0,\n zMin: 0,\n extent: \"BOX(-2 1,-1 2)\",\n // extent3D: 'BOX3D(-2 1 0,-1 2 6.952908662134e-310)' <-- looks like a value that will fail tests at some point\n });\n });\n\n await test(\"jsonbSchema validation\", async () => {\n /**\n * \n tjson: {\n json: { jsonbSchema: { \n a: { type: \"boolean\" },\n arr: { enum: [\"1\", \"2\", \"3\"] },\n arr1: { enum: [1, 2, 3] },\n arr2: { type: \"integer[]\" },\n o: { oneOf: [{ o1: { type: \"integer\" } }, { o2: { type: \"boolean\" } }], optional: true },\n } \n }\n },\n */\n\n const fo = await db.tjson.insert!({ colOneOf: \"a\", json }, { returning: \"*\" });\n // assert.deepStrictEqual(fo.json, json);\n await db.tjson.insert!({\n colOneOf: \"a\",\n json: { ...json, o: { o1: 2 } },\n });\n try {\n await db.tjson.insert!({ colOneOf: \"a\", json: { a: true, arr: \"22\" } });\n throw \"Should have failed\";\n } catch (e) {\n // Expected\n }\n });\n\n await test(\"find and findOne\", async () => {\n const fo = await db.items.findOne!();\n const f = await db.items.find!();\n assert.deepStrictEqual(fo, { h: null, id: 1, name: \"a\" });\n assert.deepStrictEqual(f[0], { h: null, id: 1, name: \"a\" });\n });\n\n await test(\"Result size\", async () => {\n const is75bits = await db.items.size!({}, { select: { name: 1 } });\n assert.equal(is75bits, \"75\", \"Result size query failed\");\n });\n\n await test(\"Basic exists\", async () => {\n const expect0 = await db.items.count!({\n $and: [{ $exists: { items2: { name: \"a\" } } }, { $exists: { items3: { name: \"b\" } } }],\n });\n assert.equal(expect0, 0, \"$exists query failed\");\n });\n\n await test(\"Basic fts with shorthand notation\", async () => {\n const res = await db.items.count!({\n $and: [\n { $exists: { items2: { \"name.@@.to_tsquery\": [\"a\"] } } },\n { $exists: { items3: { \"name.@@.to_tsquery\": [\"b\"] } } },\n ],\n });\n // assert.deepStrictEqual(res, { name: 'a'})\n assert.equal(res, 0, \"FTS query failed\");\n });\n\n await test(\"Exists with shortest path wildcard filter example\", async () => {\n const expect2 = await db.items.find!({\n $and: [\n { $existsJoined: { \"**.items3\": { name: \"a\" } } },\n { $existsJoined: { items2: { name: \"a\" } } },\n ],\n });\n assert.equal(expect2.length, 2, \"$existsJoined query failed\");\n const expectNothing = await db.items.find!({\n $and: [\n { $existsJoined: { \"**.items3\": { name: \"nothing\" } } },\n { $existsJoined: { items2: { name: \"a\" } } },\n ],\n });\n assert.equal(expectNothing.length, 0, \"$existsJoined query failed\");\n });\n\n await test(\"Exists with exact path filter example\", async () => {\n const _expect2 = await db.items.find!({\n $and: [\n // { \"items2\": { name: \"a\" } },\n // { \"items2.items3\": { name: \"a\" } },\n { $existsJoined: { items2: { name: \"a\" } } },\n ],\n });\n assert.equal(_expect2.length, 2, \"$existsJoined query failed\");\n });\n\n await test(\"Not Exists with exact path filter example\", async () => {\n const _expect1 = await db.items.find!({\n $and: [{ $notExistsJoined: { items2: { name: \"a\" } } }],\n });\n assert.equal(_expect1.length, 1, \"$notExistsJoined query failed\");\n });\n\n /* Upsert */\n await test(\"Upsert example\", async () => {\n await db.items.upsert!({ name: \"tx\" }, { name: \"tx\" });\n await db.items.upsert!({ name: \"tx\" }, { name: \"tx\" });\n assert.equal(await db.items.count!({ name: \"tx\" }), 1, \"upsert command failed\");\n });\n\n /* Joins example */\n await test(\"Joins example\", async () => {\n const items = await db.items.find!(\n {},\n {\n select: {\n \"*\": 1,\n items3: \"*\",\n items22: leftJoin(\"items2\", {}, \"*\"),\n },\n },\n );\n\n if (\n !items.length ||\n !items.every((it) => Array.isArray(it.items3) && Array.isArray(it.items22))\n ) {\n console.log(items[0].items3);\n throw \"Joined select query failed\";\n }\n });\n\n /* Joins duplicate table example */\n await test(\"Joins repeating table example\", async () => {\n const items2 = await db.items.find!(\n {},\n {\n select: {\n \"*\": 1,\n items2: \"*\",\n },\n },\n );\n const items2j = await db.items.find!(\n {},\n {\n select: {\n \"*\": 1,\n items2: \"*\",\n items2j: leftJoin(\"items2\", {}, \"*\"),\n },\n },\n );\n\n items2.forEach((d, i) => {\n assert.deepStrictEqual(\n d.items2,\n items2j[i].items2,\n \"Joins duplicate aliased table query failed\",\n );\n assert.deepStrictEqual(\n d.items2,\n items2j[i].items2j,\n \"Joins duplicate aliased table query failed\",\n );\n });\n });\n\n await test(\"Join aggregate functions example\", async () => {\n const singleShortHandAgg = await db.items.findOne!({}, { select: { id: \"$max\" } });\n const singleAgg = await db.items.findOne!({}, { select: { id: { $max: [\"id\"] } } });\n assert.deepStrictEqual(singleShortHandAgg, { id: 4 });\n assert.deepStrictEqual(singleAgg, { id: 4 });\n\n const shortHandAggJoined = await db.items.findOne!(\n { id: 4 },\n { select: { id: 1, items2: { name: \"$max\" } } },\n );\n assert.deepStrictEqual(shortHandAggJoined, { id: 4, items2: [] });\n\n const nestedAggregateRows = await db.items2.insertMany!(\n [\n { items_id: 1, name: \"a\" },\n { items_id: 1, name: \"a\" },\n { items_id: 1, name: \"a\" },\n ],\n { returning: \"*\" },\n );\n const includedIds = nestedAggregateRows.slice(0, 2).map(({ id }) => id);\n const aggOptionsJoined = await db.items.findOne!(\n { id: 1 },\n {\n select: {\n id: 1,\n items2Agg: leftJoin(\n \"items2\",\n {},\n {\n ids: {\n $array_agg: [\"id\"],\n $filter: { id: { $in: includedIds } },\n $orderBy: { id: -1 },\n },\n },\n ),\n },\n },\n );\n assert.deepStrictEqual(aggOptionsJoined, {\n id: 1,\n items2Agg: [{ ids: includedIds.slice().reverse() }],\n });\n await db.items2.delete!({ id: { $in: nestedAggregateRows.map(({ id }) => id) } });\n });\n\n /* $rowhash -> Custom column that returns md5(ctid + allowed select columns). Used in joins & CRUD to bypass PKey details */\n await test(\"$rowhash example\", async () => {\n const rowhash = await db.items.findOne!({}, { select: { $rowhash: 1, \"*\": 1 } });\n const f = { $rowhash: rowhash?.$rowhash };\n const rowhashView = await db.v_items.findOne!({}, { select: { $rowhash: 1 } });\n const rh1 = await db.items.findOne!(\n { $rowhash: rowhash?.$rowhash },\n { select: { $rowhash: 1 } },\n );\n const rhView = await db.v_items.findOne!(\n { $rowhash: rowhashView?.$rowhash },\n { select: { $rowhash: 1 } },\n );\n // console.log({ rowhash, f });\n\n await db.items.update!(f, { name: \"a\" });\n\n // console.log(rowhash, rh1)\n // console.log(rowhashView, rhView)\n if (\n typeof rowhash?.$rowhash !== \"string\" ||\n typeof rowhashView?.$rowhash !== \"string\" ||\n rowhash.$rowhash !== rh1?.$rowhash ||\n rowhashView.$rowhash !== rhView?.$rowhash\n ) {\n throw \"$rowhash query failed\";\n }\n });\n\n await test(\"Reference column nested insert\", async () => {\n const nestedRow = { name: \"nested_insert\" };\n const parentRow = { name: \"parent insert\" };\n const pr = await db.items2.insert!({ items_id: nestedRow, ...parentRow }, { returning: \"*\" });\n\n const childRows = await db.items.find!(nestedRow);\n assert.equal(childRows.length, 1);\n assert.deepStrictEqual(await db.items2.findOne!(parentRow), {\n hh: null,\n id: pr.id,\n ...parentRow,\n items_id: childRows[0].id,\n });\n });\n\n await test(\"Join escaped table names with quotes\", async () => {\n await db[`\"\"\"quoted0\"\"\"`].insert!({\n [`\"text_col0\"`]: \"0\",\n [`\"quoted1_id\"`]: {\n [`\"text_col1\"`]: \"1\",\n [`\"quoted2_id\"`]: {\n [`\"text_col2\"`]: \"2\",\n },\n },\n });\n\n const res = await db[`\"\"\"quoted0\"\"\"`].find!(\n {\n [`\"text_col0\"`]: \"0\",\n },\n {\n select: {\n \"*\": 1,\n [`\"\"\"quoted2\"\"\"`]: {\n [`\"text_col2\"`]: 1,\n [`\"id2\"`]: \"$min\",\n [`id2 max`]: { $max: [`\"id2\"`] },\n },\n },\n },\n );\n\n assert.deepStrictEqual(res[0], {\n '\"\"\"quoted2\"\"\"': [\n {\n '\"text_col2\"': \"2\",\n \"id2 max\": 1,\n '\"id2\"': 1,\n },\n ],\n '\"id0\"': 1,\n '\"quoted1_id\"': 1,\n '\"text_col0\"': \"0\",\n });\n\n const aliasedQuotedJoin = await db[`\"\"\"quoted0\"\"\"`].find!(\n {\n [`\"text_col0\"`]: \"0\",\n },\n {\n select: {\n \"*\": 1,\n '\"ali as\"': {\n $leftJoin: '\"\"\"quoted2\"\"\"',\n select: {\n '\"text_col2\"': { $left: ['\"text_col2\"', 2] },\n '\"id2\"': \"$min\",\n \"id2 max\": { $max: [`\"id2\"`] },\n },\n },\n },\n },\n );\n\n assert.deepStrictEqual(aliasedQuotedJoin, [\n {\n '\"id0\"': 1,\n '\"quoted1_id\"': 1,\n '\"text_col0\"': \"0\",\n '\"ali as\"': [\n {\n '\"text_col2\"': \"2\",\n '\"id2\"': 1,\n \"id2 max\": 1,\n },\n ],\n },\n ]);\n\n const exists1 = await db[`\"\"\"quoted0\"\"\"`].find!(\n {\n $existsJoined: {\n path: ['\"\"\"quoted1\"\"\"', '\"\"\"quoted2\"\"\"'],\n filter: {\n '\"id2\"': 1,\n },\n },\n },\n { select: \"*\" },\n );\n /** Duplicated tables */\n const exists2 = await db[`\"\"\"quoted0\"\"\"`].find!(\n {\n $existsJoined: {\n path: ['\"\"\"quoted1\"\"\"', '\"\"\"quoted2\"\"\"', '\"\"\"quoted1\"\"\"', '\"\"\"quoted2\"\"\"'],\n filter: {\n '\"id2\"': 1,\n },\n },\n },\n { select: \"*\" },\n );\n assert.deepStrictEqual(exists1, exists2);\n });\n\n await test(\"subscribe to escaped table name\", async () => {\n await tryRunP(\"subscribe to escaped table name\", async (resolve, reject) => {\n const filter = { [`\"text_col0\"`]: { $in: [\"0\", \"1\"] } };\n let runs = 0;\n setTimeout(async () => {\n /** Used for debugging */\n if (runs < 2) {\n const appName = await sql?.(\n `\n SELECT application_name\n FROM pg_catalog.pg_stat_activity\n WHERE pid = pg_backend_pid()\n `,\n [],\n { returnType: \"rows\" },\n );\n const apps = await sql?.(`SELECT * FROM prostgles.apps`, [], {\n returnType: \"value\",\n });\n const app_triggers = await sql?.(`SELECT * FROM prostgles.app_triggers`, [], {\n returnType: \"rows\",\n });\n log(\"show-logs\");\n log(JSON.stringify({ appName, apps, app_triggers }, null, 2));\n }\n }, 2000);\n const sub = await db[`\"\"\"quoted0\"\"\"`].subscribe!(filter, {}, async (items) => {\n const item = items[0];\n log(\n JSON.stringify(\n {\n item,\n runs,\n },\n null,\n 2,\n ),\n );\n if (item && [\"0\", \"1\"].includes(item[`\"text_col0\"`])) {\n runs++;\n if (runs === 1) {\n await db[`\"\"\"quoted0\"\"\"`].update!(filter, { [`\"text_col0\"`]: \"1\" });\n }\n if (runs < 2) {\n return;\n }\n try {\n await testToEnsureTriggersAreDisabled(sub, `\"\"\"quoted0\"\"\"`);\n resolve(true);\n } catch (e) {\n reject(e);\n }\n }\n }).catch(reject);\n });\n });\n const testName = \"subscribe using a filter bigger than block_size\";\n await test(testName, async () => {\n await tryRunP(testName, async (resolve, reject) => {\n const sub = await db[`\"\"\"quoted0\"\"\"`].subscribe!(\n { [`\"text_col0\"`]: \"0\".repeat(2e3) },\n {},\n async (items) => {\n setTimeout(async () => {\n if (!sub) return;\n await sub.unsubscribe();\n resolve(true);\n }, 10);\n },\n );\n });\n });\n\n await test(\"Reverse join with agg\", async () => {\n const inserted = await db.tr1.insert!({ tr2: { t1: \"a\", t2: \"b\" } }, { returning: \"*\" });\n\n const idAggSelect = {\n ids: {\n $array_agg: [\"id\"],\n },\n };\n const normalJoin = await db.tr1.find!(\n {},\n {\n orderBy: { id: true },\n select: {\n \"*\": 1,\n trD2: {\n $innerJoin: \"tr2\",\n filter: { t1: \"a\" },\n select: idAggSelect,\n },\n },\n },\n );\n const reverseJoin = await db.tr2.find!(\n { t1: \"a\" },\n {\n orderBy: { id: true },\n select: { \"*\": 1, tr1: { $innerJoin: \"tr1\", select: idAggSelect } },\n },\n );\n assert.deepStrictEqual(normalJoin[0], {\n id: 1,\n t1: null,\n trD2: [{ ids: [1] }],\n });\n assert.deepStrictEqual(normalJoin[1], {\n id: 2,\n t1: null,\n trD2: [{ ids: [2] }],\n });\n assert.deepStrictEqual(reverseJoin[0], {\n id: 1,\n tr1_id: 1,\n t1: \"a\",\n t2: \"b\",\n tr1: [{ ids: [1] }],\n });\n assert.deepStrictEqual(reverseJoin[1], {\n id: 2,\n tr1_id: 2,\n t1: \"a\",\n t2: \"b\",\n tr1: [{ ids: [2] }],\n });\n });\n\n await test(\"Related table subscribe\", async () => {\n await expectNoTriggers();\n await tryRunP(\"Related table subscribe\", async (resolve, reject) => {\n let runs = 0;\n const sub = await db.tr1.subscribe!(\n {},\n {\n select: {\n \"*\": 1,\n tr2: \"*\",\n tr3: \"*\",\n },\n },\n async (_rows) => {\n runs++;\n console.log({ _rows, runs });\n if (runs === 1) {\n await db.tr2.insert!({ tr1_id: _rows[0]!.id, t1: \"a\", t2: \"b\" });\n } else if (runs === 2) {\n await sub.unsubscribe();\n await tout(4000);\n await expectNoTriggers();\n resolve(true);\n }\n },\n );\n });\n });\n\n await test(\"Aggregate FILTER registers joined dependency triggers\", async () => {\n const tr1Id = 701;\n await db.tr2.delete!({ tr1_id: tr1Id });\n await db.tr1.delete!({ id: tr1Id });\n await db.tr1.insert!({ id: tr1Id, t1: \"aggregate-filter-root\" });\n\n const results: AnyObject[] = [];\n const sub = await db.tr1.subscribe!(\n { id: tr1Id },\n {\n select: {\n count: {\n $count: [],\n $filter: {\n $existsJoined: {\n tr2: { t1: \"aggregate-filter-related\" },\n },\n },\n },\n },\n },\n ([result]) => {\n if (result) results.push(result);\n },\n );\n\n await tout(300);\n assert.deepStrictEqual(results.at(-1), { count: \"0\" });\n\n await db.tr2.insert!({ tr1_id: tr1Id, t1: \"aggregate-filter-related\" });\n await tout(300);\n assert.deepStrictEqual(results.at(-1), { count: \"1\" });\n\n await sub.unsubscribe();\n await db.tr2.delete!({ tr1_id: tr1Id });\n await db.tr1.delete!({ id: tr1Id });\n });\n\n await test(\"Nested sort by computed col\", async () => {\n const getSorted = (asc = false, badKey = false, limited = false) =>\n db.tr1.find!(\n {},\n {\n select: {\n \"*\": 1,\n tr2: {\n $leftJoin: \"tr2\",\n select: { maxId: { $max: [\"id\"] } },\n ...(limited && { limit: 1, orderBy: [{ key: \"maxId\", asc, nulls: \"last\" }] }),\n },\n },\n orderBy: {\n [`${badKey ? \"T\\n--select 1\" : \"tr2\"}.maxId`]: asc,\n },\n },\n );\n const sortedAsc = await getSorted(true);\n const sortedDesc = await getSorted(false);\n assert.deepStrictEqual(\n sortedAsc\n .map((d) => d.tr2[0].maxId)\n .slice(0)\n .reverse(),\n sortedDesc.map((d) => d.tr2[0].maxId),\n );\n assert.deepStrictEqual(await getSorted(true, false, true), sortedAsc);\n assert.deepStrictEqual(await getSorted(false, false, true), sortedDesc);\n const sortedDescBad = await getSorted(false, true).catch((e) => e);\n assert.equal(\n sortedDescBad.message,\n \"Invalid/disallowed orderBy fields or params: T\\n--select 1.maxId\",\n \"Bad column name should have been rejected by database\",\n );\n });\n\n await test(\"Nested function on different than source column getNewQuery name bug fix\", async () => {\n const res = await db.tr1.find!(\n {},\n {\n select: {\n \"*\": 1,\n tr2: {\n sign: { $sign: [\"tr1_id\"] },\n },\n },\n orderBy: {\n id: true,\n },\n },\n );\n assert.deepStrictEqual(\n res.map((row) => [row.id, row.tr2[0]!.sign]),\n [\n [1, 1],\n [2, 1],\n ],\n );\n });\n\n await test(\"Reference column deep nested insert\", async () => {\n const pr = await db.items4a.insert!(\n {\n items_id: { name: \"it\" },\n items2_id: { name: \"it2\", items_id: { name: \"it\" } },\n name: \"it4a\",\n },\n { returning: \"*\" },\n );\n const itemsCount = await db.items.count!({ name: \"it\" });\n const items2Count = await db.items2.count!({ name: \"it2\" });\n const items4aCount = await db.items4a.count!({ name: \"it4a\" });\n\n assert.equal(+itemsCount, 2);\n assert.equal(+items2Count, 1);\n assert.equal(+items4aCount, 1);\n });\n\n await test(\"Multi reference column nested insert\", async () => {\n await db.items_multi.insert!(\n {\n items0_id: { name: \"multi\" },\n items1_id: { name: \"multi\" },\n items2_id: { name: \"multi\" },\n items3_id: { name: \"multi\" },\n name: \"root_multi\",\n },\n { returning: \"*\" },\n );\n const itemsCount = await db.items.count!({ name: \"multi\" });\n assert.equal(+itemsCount, 4);\n\n const multiItem = await db.items_multi.findOne!(\n { name: \"root_multi\" },\n { select: { \"*\": 1, items: \"*\" } },\n );\n assert.equal(multiItem?.name, \"root_multi\");\n //@ts-ignore\n assert.equal(multiItem?.items.filter((d) => d.name === \"multi\").length, 4);\n });\n\n await test(\"Join path with order by nested\", async () => {\n await db.items_multi.insert!(\n {\n items0_id: { name: \"multi0\" },\n items1_id: { name: \"multi1\" },\n name: \"root_multi\",\n },\n { returning: \"*\" },\n );\n\n const res = await db.items_multi.find!(\n {},\n {\n select: {\n \"*\": 1,\n i0: innerJoin(\"items_multi\", { name: \"multi0\" }, \"*\", {\n path: [{ table: \"items\", on: [{ items0_id: \"id\" }] }],\n }),\n i1: innerJoin(\"items_multi\", { name: \"multi0\" }, \"*\", {\n path: [{ table: \"items\", on: [{ items0_id: \"id\" }] }],\n }),\n i2: innerJoin(\"items_multi\", { name: \"multi0\" }, \"*\", {\n path: [{ table: \"items\", on: [{ items0_id: \"id\" }] }],\n }),\n },\n orderBy: {\n \"i0.name\": -1,\n },\n },\n );\n assert.equal(res.length, 1);\n assert.equal(res[0].i0[0].name, \"multi0\");\n assert.equal(res[0].items2_id, null);\n assert.equal(res[0].items2_id, null);\n assert.deepStrictEqual(res[0].i0, res[0].i1);\n assert.deepStrictEqual(res[0].i1, res[0].i2);\n });\n\n await test(\"Self join\", async () => {\n await db.self_join.delete!();\n const a = await db.self_join.insert!({ name: \"a\" });\n const a1 = await db.self_join.insert!({\n name: \"a\",\n my_id: { name: \"b\" },\n });\n const a2 = await db.self_join.insert!({\n name: \"a\",\n my_id1: { name: \"b1\" },\n });\n\n const one = await db.self_join.find!(\n {},\n {\n select: {\n name: 1,\n my: {\n $innerJoin: [{ table: \"self_join\", on: [{ my_id: \"id\" }] }],\n filter: { name: \"b\" },\n select: \"*\",\n orderBy: \"name\",\n },\n },\n },\n );\n assert.equal(one.length, 1);\n assert.equal(one[0].my.length, 1);\n assert.equal(one[0].my[0].name, \"b\");\n });\n\n await test(\"One to many multi join duplicate row bug fix\", async () => {\n await db.symbols.insert!([\n {\n id: \"btc\",\n trades: [{ price: 1 }, { price: 3 }, { price: 2 }],\n },\n {\n id: \"eth\",\n trades: [{ price: 0.1 }, { price: 0.3 }, { price: 0.2 }],\n },\n {\n id: \"abc\",\n },\n ]);\n\n const res = await db.symbols.find!(\n {},\n {\n select: {\n id: 1,\n trades: \"*\",\n tradesAlso: {\n $leftJoin: \"trades\",\n select: \"*\",\n },\n },\n },\n );\n assert.equal(res.length, 3);\n res.forEach((row) => {\n assert(typeof row.id, \"number\");\n assert(typeof (row as any).price, \"number\");\n assert(typeof (row as any).symbol, \"string\");\n assert.deepStrictEqual(row.trades, row.tradesAlso);\n if (row.id !== \"abc\") {\n assert.equal(row.trades.length, 3);\n }\n });\n\n const resSortedInnerJoin = await db.symbols.find!(\n {},\n {\n select: {\n id: 1,\n trades: {\n $innerJoin: \"trades\",\n select: \"*\",\n orderBy: { price: -1 },\n },\n tradesAlso: {\n $innerJoin: \"trades\",\n select: \"*\",\n orderBy: { price: 1 },\n },\n },\n },\n );\n assert.equal(resSortedInnerJoin.length, 2);\n resSortedInnerJoin.forEach((row) => {\n assert.deepStrictEqual(row.trades.slice(0).reverse(), row.tradesAlso);\n assert.notEqual(row.id, \"abc\");\n });\n });\n\n await test(\"subscribe triggers with stale schema should fail gracefully and never block other queries\", async () => {\n const sub = await db.various.subscribe!(\n variousId99,\n { select: { name: 1 } },\n async (d, err) => {\n log(\"various id=99 count\", d.length);\n if (err) {\n log(\"Error in subscription callback: \" + JSON.stringify(err));\n }\n },\n ).catch((e) => {\n log(\"subscribe failed with error: \" + JSON.stringify(e));\n return Promise.reject(e);\n });\n\n const deleteItems = () => sql!(`DELETE FROM various WHERE id = \\${id}`, variousId99);\n await deleteItems();\n\n await tout(2000);\n await sql?.(`ALTER TABLE various RENAME COLUMN name TO name_old`).catch((e) => {\n return Promise.reject(e);\n });\n const getVariousCount = () =>\n sql!(`SELECT COUNT(*) FROM various WHERE id = \\${id}`, variousId99, {\n returnType: \"value\",\n }).then(Number);\n const variousId99Count = await getVariousCount();\n await sql?.(`INSERT INTO various (id, name_old) VALUES (\\${id}, 'test')`, {\n id: variousId99.id,\n name_old: \"test\",\n }).catch(console.error);\n console.log(\"ok\");\n await tout(2000);\n console.log(\"ok\");\n const newVariousId99Count = await getVariousCount();\n assert.equal(variousId99Count + 1, newVariousId99Count);\n await deleteItems();\n await sub.unsubscribe?.();\n await expectNoTriggers();\n });\n });\n\n await test(\"Having clause\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: { name: 1, c: { $countAll: [] } },\n having: {\n c: 4,\n },\n },\n );\n assert.deepStrictEqual(res, [\n {\n c: \"4\",\n name: \"multi\",\n },\n ]);\n });\n\n await test(\"Having clause with complex filter\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: { name: 1, c: { $countAll: [] } },\n having: {\n $filter: [{ $countAll: [] }, \"=\", 4],\n },\n },\n );\n assert.deepStrictEqual(res, [\n {\n c: \"4\",\n name: \"multi\",\n },\n ]);\n });\n await test(\"Nested join having clause\", async () => {\n const res = await db.items.find!(\n {},\n {\n select: {\n name: 1,\n itms2: {\n $innerJoin: \"items2\",\n select: {\n name: 1,\n c: { $countAll: [] },\n },\n having: { c: 1 },\n },\n },\n },\n );\n assert.deepStrictEqual(res, [\n {\n name: \"a\",\n itms2: [{ c: 1, name: \"a\" }],\n },\n {\n name: \"a\",\n itms2: [{ c: 1, name: \"a\" }],\n },\n ]);\n });\n};\n\nexport async function tryRun(desc: string, func: () => any, log?: Function) {\n try {\n await func();\n } catch (err) {\n console.error(desc + \" FAILED:\", err);\n log?.(\"FAIL: \", err);\n console.trace(err);\n await tout(50);\n throw err;\n }\n}\nexport function tryRunP(\n desc: string,\n func: (resolve: any, reject: any) => any,\n opts?: { log?: Function; timeout?: number },\n) {\n const timeoutMs = opts?.timeout || 7000;\n return new Promise(async (rv, rj) => {\n const testTimeout =\n Number.isFinite(timeoutMs) ?\n setTimeout(() => {\n const errMsg = `${desc} failed. Reason: Timout reached: ${timeoutMs}ms`;\n opts?.log?.(errMsg);\n rj(errMsg);\n }, timeoutMs)\n : undefined;\n try {\n await func(rv, rj);\n clearTimeout(testTimeout);\n } catch (err: any) {\n opts?.log?.(`${desc} failed: ` + JSON.stringify(err));\n rj(err);\n await tout(50);\n throw err;\n }\n });\n}\nconst tout = (t = 3000) => {\n return new Promise(async (resolve, reject) => {\n setTimeout(() => {\n resolve(true);\n }, t);\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/isomorphicQueriesTyped.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":2,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":2,"endColumn":73,"fix":{"range":[50,50],"text":" type"}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":11,"column":45,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":11,"endColumn":47,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[530,532],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":12,"column":11,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":12,"endColumn":14},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'col2' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":13,"column":23,"nodeType":"Identifier","messageId":"unusedVar","endLine":13,"endColumn":27},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":29,"column":45,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":29,"endColumn":47,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1045,1047],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":30,"column":11,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":30,"endColumn":14},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":47,"column":39,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":47,"endColumn":41,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1527,1529],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":47,"column":48,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":47,"endColumn":50,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1536,1538],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":48,"column":11,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":48,"endColumn":14}],"suppressedMessages":[],"errorCount":9,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":1,"fixableWarningCount":0,"source":"import test, { describe } from \"node:test\";\nimport { DBOFullyTyped } from \"../dist/DBSchemaBuilder/DBSchemaBuilder\";\nimport type { DBHandlerClient } from \"./client\";\nimport type { DBGeneratedSchema } from \"./DBGeneratedSchema\";\n\nexport const isomorphicQueriesTyped = async (\n db: DBOFullyTyped<DBGeneratedSchema> | DBHandlerClient<DBGeneratedSchema>,\n) => {\n await describe(\"isomorphic typed queries\", async () => {\n await test(\"isLookupTable DB Types from colConf\", async () => {\n const row = await db.uuid_text.findOne?.({});\n if (row) {\n const { col1, col2 } = row;\n //@ts-expect-error\n if (col1 !== \"z\") {\n // col1 is typed to ftable values\n }\n //@ts-expect-error\n if (col1 === 2) {\n // col1 is typed to ftable values\n }\n if (col1 === \"a\") {\n // col1 is typed to ftable values\n }\n }\n });\n\n await test(\"isLookupTable DB Types from reference column actual definition\", async () => {\n const row = await db.uuid_text.findOne?.({});\n if (row) {\n const { col3 } = row;\n //@ts-expect-error\n if (col3 !== \"z\") {\n // col3 is typed to ftable values\n }\n //@ts-expect-error\n if (col3 === 2) {\n // col3 is typed to ftable values\n }\n if (col3 === \"a\") {\n // col3 is typed to ftable values\n }\n }\n });\n\n await test(\"isLookupTable pkey column itself is typed\", async () => {\n const row = await db.lookup_col1?.findOne?.({});\n if (row) {\n const { id } = row;\n //@ts-expect-error\n if (id !== \"z\") {\n // col3 is typed to ftable values\n }\n //@ts-expect-error\n if (id === 2) {\n // col3 is typed to ftable values\n }\n if (id === \"a\") {\n // col3 is typed to ftable values\n }\n }\n });\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/DEMO_SERVER.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/DEMO_SERVER.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import path from \"path\";\nimport prostgles from \"prostgles-server\";\nimport { DBGeneratedSchema } from \"../DBGeneratedSchema\";\n\nprostgles<DBGeneratedSchema>({\n dbConnection: {\n connectionString: process.env.DB_CONNECTION,\n },\n tsGeneratedTypesDir: path.join(__dirname + \"/\"),\n tableConfig: {\n user: {\n columns: {\n id: \"SERIAL PRIMARY KEY\",\n email: \"TEXT NOT NULL\",\n status: { enum: [\"active\", \"disabled\", \"pending\"] },\n preferences: {\n jsonbSchemaType: {\n showIntro: { type: \"boolean\", optional: true },\n theme: { enum: [\"light\", \"dark\", \"auto\"], optional: true },\n two_factor_auth: { oneOf: [{ enum: [\"app\"] }] },\n },\n },\n },\n },\n },\n onReady: async ({ dbo }) => {\n const user = await dbo.users.findOne({ id: 123 });\n\n user?.preferences.theme === \"dark\";\n //@ts-expect-error\n user?.status === \"actived\";\n },\n});\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/VALIDATE_SCHEMA_FUNCTION_SQL_TEST.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"const VALIDATE_SCHEMA_FUNCNAME = \"prostgles.validate_jsonb_schema\";\n\nexport const VALIDATE_SCHEMA_FUNCTION_SQL_TEST = `\n\n/* TESTS */\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"enum\": [\"a\", \"b\", 2] }', \n '\"a\"'::JSONB\n);\n\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"record\": { \"keysEnum\": [\"a\", \"b\"] , \"values\": { \"enum\": [1, 2] } } }', \n '{\"a\": 1, \"b\": 2 }'::JSONB\n);\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"record\": { \"keysEnum\": [\"a\", \"b\"] , \"values\": { \"enum\": [1, 2] } } }', \n '{\"a\": 1 }'::JSONB\n);\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"record\": { \"keysEnum\": [\"a\", \"b\"] , \"values\": { \"enum\": [1, 2] } } }', \n '{ }'::JSONB\n);\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"record\": { \"keysEnum\": [\"a\", \"b\"] } }', \n '{\"a\": 1, \"b\": 2 }'::JSONB\n);\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"enum\": [\"a\", \"b\", 2] }', \n '2'::JSONB\n);\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \n \"oneOfType\": [\n { \"a\": \"string\" } , \n {\n \"a\": {\n \"type\": \"boolean\", \n \"allowedValues\": [false], \n \"optional\": true \n }\n }\n ] \n }', \n '{ \"a\": false }'\n);\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"arrayOfType\": { \"a\": \"string\", \"narr\": { \"arrayOfType\": { \"a\": { \"type\": \"string\", \"optional\": false, \"nullable\": true } } } } }', \n '[{ \"a\": \"ddd\", \"narr\": [{ \"a\": null }] }]'::JSONB\n);\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"type\": { \"a\": { \"type\": \"integer[]\", \"allowedValues\": [2] } } }'::TEXT, \n '{ \"a\": [2, 2] }'\n); \n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}(\n '{ \"type\": { \"a\": { \"type\": \"string[]\", \"allowedValues\": [\"2\"] } } }'::TEXT, \n '{ \"a\": [\"2\"] }'\n);\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"any\"}', '{}');\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": { \"a\": { \"enum\": [\"a\"] } } }', '{ \"a\": \"a\"}');\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"arrayOfType\": { \"a\": { \"enum\": [\"a\"] } } }', '[{ \"a\": \"a\"}]');\n\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"RowLookup\", \"table\": \"tblName\" }', '{}');\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"RowLookup[]\", \"table\": \"tblName\" }', '[{}]');\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"ValueLookup\", \"table\": \"tblName\", \"column\": \"colName\" }', '1');\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"ValueLookup[]\", \"table\": \"tblName\", \"column\": \"colName\" }', '[1, 2]');\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"TableLookup\" }', '\"tblName\"'::JSONB);\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"TableLookup[]\" }', '[\"tblName\"]');\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"ColumnLookup\" }', '{ \"table\": \"tblName\", \"column\": \"colName\" }');\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"ColumnLookup[]\" }', '[{ \"table\": \"tblName\", \"column\": \"colName\" }]');\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"time\"}', '\"22:22\"');\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"type\": \"Date\"}', '\"2222-22-22\"');\n\n\nSELECT ${VALIDATE_SCHEMA_FUNCNAME}('{ \"oneOf\": [\"number\"]}','2');\n`;\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/audit.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'typedAudit' is assigned a value but only used as a type. Allowed unused vars must match /^_/u.","line":25,"column":7,"nodeType":"Identifier","messageId":"usedOnlyAsType","endLine":25,"endColumn":17},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":97,"column":23,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":97,"endColumn":98,"fix":{"range":[3916,3956],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":129,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":129,"endColumn":51,"fix":{"range":[4982,4983],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":129,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":129,"endColumn":43,"fix":{"range":[4974,4975],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":150,"column":26,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":150,"endColumn":28,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[5576,5578],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":161,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":161,"endColumn":52,"fix":{"range":[5941,5942],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":162,"column":13,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":162,"endColumn":35},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":171,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":171,"endColumn":33,"fix":{"range":[6480,6481],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":171,"column":42,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":171,"endColumn":64,"fix":{"range":[6511,6512],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":173,"column":18,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":173,"endColumn":40,"fix":{"range":[6658,6659],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":181,"column":46,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":181,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7221,7223],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":182,"column":50,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":182,"endColumn":52,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7301,7303],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":186,"column":50,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":186,"endColumn":52,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7463,7465],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":190,"column":46,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":190,"endColumn":48,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[7616,7618],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":191,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":191,"endColumn":64,"fix":{"range":[7717,7718],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":199,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":199,"endColumn":30,"fix":{"range":[8107,8108],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":200,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":200,"endColumn":33,"fix":{"range":[8143,8144],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":203,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":203,"endColumn":95,"fix":{"range":[8349,8350],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":203,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":203,"endColumn":67,"fix":{"range":[8321,8322],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .new_row on an `any` value.","line":208,"column":43,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":208,"endColumn":50},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{}`.","line":209,"column":38,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":209,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":212,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":212,"endColumn":61},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":214,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":214,"endColumn":69,"fix":{"range":[9096,9097],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":219,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":219,"endColumn":29,"fix":{"range":[9497,9498],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":225,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":225,"endColumn":29,"fix":{"range":[9637,9638],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":227,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":227,"endColumn":29,"fix":{"range":[9757,9758],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":228,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":228,"endColumn":29,"fix":{"range":[9823,9824],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .old_id on an `any` value.","line":230,"column":34,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":230,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .new_id on an `any` value.","line":231,"column":34,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":231,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .table_name on an `any` value.","line":232,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":232,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .operation on an `any` value.","line":233,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":233,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .new_row on an `any` value.","line":234,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":234,"endColumn":37},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":238,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":238,"endColumn":48,"fix":{"range":[10339,10340],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":238,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":238,"endColumn":40,"fix":{"range":[10331,10332],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .operation on an `any` value.","line":247,"column":56,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":247,"endColumn":65},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .actor on an `any` value.","line":251,"column":51,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":251,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":255,"column":17,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":259,"endColumn":70},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":261,"column":19,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":265,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":266,"column":19,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":269,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .db_context on an `any` value.","line":270,"column":34,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":270,"endColumn":44},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":270,"column":61,"nodeType":"Property","messageId":"anyAssignment","endLine":270,"endColumn":81},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":293,"column":27,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":295,"endColumn":11,"fix":{"range":[13077,13078],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":302,"column":21,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":302,"endColumn":23,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[13328,13330],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":303,"column":16,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":303,"endColumn":30},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":303,"column":22,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":303,"endColumn":24,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[13360,13362],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":303,"column":34,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":303,"endColumn":48},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":303,"column":40,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":303,"endColumn":42,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[13378,13380],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":303,"column":58,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":303,"endColumn":60,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[13396,13398],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":330,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":330,"endColumn":62,"fix":{"range":[14502,14503],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":331,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":331,"endColumn":53,"fix":{"range":[14556,14557],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":332,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":332,"endColumn":53,"fix":{"range":[14615,14616],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":334,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":334,"endColumn":28,"fix":{"range":[14709,14710],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":340,"column":38,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":340,"endColumn":55,"fix":{"range":[14961,14962],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":345,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":345,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":346,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":346,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":347,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":347,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":348,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":348,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":349,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":349,"endColumn":20},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":377,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":377,"endColumn":36,"fix":{"range":[15930,15931],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":380,"column":36,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":380,"endColumn":45},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":387,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":387,"endColumn":50,"fix":{"range":[16270,16271],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":398,"column":20,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":398,"endColumn":37,"fix":{"range":[16700,16701],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":398,"column":76,"nodeType":"Identifier","messageId":"unsafeReturn","endLine":398,"endColumn":85},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":401,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":401,"endColumn":51,"fix":{"range":[16885,16886],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":404,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":404,"endColumn":34,"fix":{"range":[16975,16976],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":416,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":416,"endColumn":70,"fix":{"range":[17315,17316],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":418,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":418,"endColumn":29,"fix":{"range":[17380,17381],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":422,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":422,"endColumn":29,"fix":{"range":[17499,17500],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":424,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":424,"endColumn":35,"fix":{"range":[17581,17582],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":438,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":438,"endColumn":48,"fix":{"range":[18044,18045],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":438,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":438,"endColumn":40,"fix":{"range":[18036,18037],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":447,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":447,"endColumn":72,"fix":{"range":[18508,18509],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":447,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":447,"endColumn":66,"fix":{"range":[18502,18503],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":452,"column":22,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":452,"endColumn":37,"fix":{"range":[18679,18680],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":452,"column":46,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":452,"endColumn":48},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":485,"column":49,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":485,"endColumn":51,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[19973,19975],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":510,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":510,"endColumn":46,"fix":{"range":[21185,21186],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":510,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":510,"endColumn":38,"fix":{"range":[21177,21178],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":523,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":523,"endColumn":46,"fix":{"range":[21634,21635],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .value on an `any` value.","line":523,"column":73,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":523,"endColumn":78},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":524,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":524,"endColumn":34,"fix":{"range":[21705,21706],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":541,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":541,"endColumn":39,"fix":{"range":[22413,22414],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":547,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":547,"endColumn":19,"fix":{"range":[22650,22651],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":551,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":551,"endColumn":23,"fix":{"range":[22775,22776],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .new_id on an `any` value.","line":556,"column":48,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":556,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":565,"column":41,"nodeType":"Property","messageId":"anyAssignment","endLine":565,"endColumn":62},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":567,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":567,"endColumn":44,"fix":{"range":[23422,23423],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":570,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":570,"endColumn":44,"fix":{"range":[23581,23582],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .operation on an `any` value.","line":581,"column":36,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":581,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .new_id on an `any` value.","line":582,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":582,"endColumn":46},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":595,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":595,"endColumn":29,"fix":{"range":[24758,24759],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .count on an `any` value.","line":644,"column":84,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":644,"endColumn":89},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":654,"column":22,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":654,"endColumn":24,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[27427,27429],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":655,"column":13,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":655,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":657,"column":24,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":657,"endColumn":26,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[27515,27517],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":658,"column":33,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":658,"endColumn":35,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[27562,27564],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":67,"fatalErrorCount":0,"warningCount":30,"fixableErrorCount":49,"fixableWarningCount":0,"source":"import { strict as assert } from \"node:assert\";\nimport { test } from \"node:test\";\nimport pgPromise from \"pg-promise\";\nimport { mkdtemp, writeFile, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport express from \"express\";\nimport {\n AUDIT_TABLE_COLUMNS,\n AUDIT_TABLE_COLUMN_DEFINITIONS,\n AUDIT_TABLE_COLUMN_NAMES,\n getLocalStorageClient,\n type AuditTableRow,\n} from \"prostgles-server\";\nimport { Prostgles, type DB } from \"prostgles-server/dist/Prostgles\";\nimport { getConnectionDetails } from \"prostgles-server/dist/DboBuilder/runSql/getAdminClient\";\nimport { PublishParser } from \"prostgles-server/dist/PublishParser/PublishParser\";\nimport {\n AUDIT_TRIGGER_PREFIX,\n TABLE_CONFIG_TRIGGER_PREFIX,\n} from \"prostgles-server/dist/TableConfig/managedTriggerNames\";\nimport type { SchemaConfigAudit, TableDefinition, ProstglesInitOptions } from \"prostgles-server\";\n\n// Keep the public schema and column inference checked alongside the integration tests.\nconst typedAudit: SchemaConfigAudit<{\n items: { columns: { id: {}; secret: {} } };\n}> = {\n tableName: \"events\",\n tables: { items: { idColumns: [\"id\"], excludeColumns: [\"secret\"] } },\n};\nconst invalidColumn: typeof typedAudit = {\n tableName: \"events\",\n tables: {\n items: {\n // @ts-expect-error Unknown column\n idColumns: [\"missing\"],\n },\n },\n};\nvoid invalidColumn;\n\nexport async function testAudit(parentDb: DB) {\n await test(\n \"Managed audit setup, row history, protection, access and query readiness\",\n { timeout: 60000 },\n async () => {\n await parentDb.none(\"DROP SCHEMA IF EXISTS audit_test_main CASCADE\");\n await parentDb.none(\"CREATE SCHEMA audit_test_main\");\n const pgp = pgPromise();\n const dbConnection = {\n ...getConnectionDetails(parentDb),\n options: \"-c search_path=audit_test_main,public\",\n };\n const db = pgp(dbConnection as unknown as Parameters<typeof pgp>[0]);\n const dir = await mkdtemp(join(tmpdir(), \"prostgles-audit-\"));\n const sqlFilePath = join(dir, \"init.sql\");\n const fileTable = \"audit_test_files\";\n const documentTable = \"audit_test_documents\";\n const maskedTable = \"audit_test_masked\";\n await writeFile(\n sqlFilePath,\n `\n DROP SCHEMA IF EXISTS audit_test CASCADE;\n CREATE SCHEMA IF NOT EXISTS audit_test;\n CREATE TABLE IF NOT EXISTS audit_test_existing (id int PRIMARY KEY, value text);\n CREATE TABLE IF NOT EXISTS audit_test_child (id int PRIMARY KEY, parent int REFERENCES audit_test_existing ON DELETE CASCADE);\n CREATE TABLE IF NOT EXISTS audit_test_nopk (key text, secret text);\n CREATE TABLE IF NOT EXISTS audit_test_partitioned (id int PRIMARY KEY) PARTITION BY RANGE (id);\n CREATE TABLE IF NOT EXISTS audit_test_partition PARTITION OF audit_test_partitioned FOR VALUES FROM (0) TO (100);\n CREATE TABLE IF NOT EXISTS ${maskedTable} (id int, secret text, PRIMARY KEY (id, secret));\n CREATE OR REPLACE VIEW audit_test_view AS SELECT * FROM audit_test_existing;\n `,\n );\n const audit: SchemaConfigAudit = {\n tableName: `audit_events`,\n tables: {\n audit_test_source: {\n excludeColumns: [\"secret\"],\n },\n audit_test_existing: 1,\n audit_test_child: 1,\n audit_test_nopk: { idColumns: [\"key\"], excludeColumns: [\"secret\"] },\n [fileTable]: 1,\n [maskedTable]: 1,\n },\n };\n const sourcePublish = {\n audit_test_source: {\n select: { fields: { a: 1 }, forcedFilter: { b: \"one\" } },\n },\n [maskedTable]: { select: { fields: { id: 1 } } },\n } as const;\n let pauseSchema = false;\n let releaseSchema: (() => void) | undefined;\n let schemaStarted: (() => void) | undefined;\n const prgl = new Prostgles({\n dbConnection: getConnectionDetails(db) as unknown as ProstglesInitOptions[\"dbConnection\"],\n sqlFilePath,\n audit,\n publish: sourcePublish,\n transactions: true,\n joins: \"inferred\",\n schemaFilter: { audit_test_main: 1, audit_test: 1 },\n fileTable: {\n tableName: fileTable,\n expressApp: express(),\n storageClient: getLocalStorageClient({\n localFolderPath: join(process.cwd(), \"debug\", \"audit-access-files\"),\n }),\n },\n tableConfig: {\n audit_test_source: {\n columns: {\n a: \"int NOT NULL\",\n b: \"text NOT NULL\",\n value: \"text\",\n secret: \"text\",\n },\n constraints: [\"PRIMARY KEY (a, b)\"],\n triggers: {\n audit_test_custom: {\n type: \"after\",\n actions: [\"insert\"],\n forEach: \"row\",\n query: \"BEGIN RETURN NULL; END;\",\n },\n },\n onMount: async ({ dbo }) => {\n await dbo.audit_test_source!.insert!({\n a: 100,\n b: \"mount\",\n value: \"mounted\",\n });\n },\n },\n [documentTable]: {\n columns: {\n id: \"serial PRIMARY KEY\",\n file_id: `uuid NOT NULL REFERENCES ${fileTable}(id)`,\n },\n },\n },\n onLog: async (event) => {\n if (\n pauseSchema &&\n event.type === \"debug\" &&\n event.command === \"DboBuilder.getTablesForSchemaPostgresSQL\"\n ) {\n pauseSchema = false;\n schemaStarted?.();\n await new Promise<void>((resolve) => {\n releaseSchema = resolve;\n });\n }\n },\n onReady: () => {},\n });\n let result: Awaited<ReturnType<typeof prgl.init>> | undefined;\n try {\n result = await prgl.init(() => {}, { type: \"init\" });\n const source = result.db.audit_test_source!;\n if (!prgl.opts.tableConfig) {\n throw new Error(\"tableConfig is not defined\");\n }\n prgl.opts.tableConfig.audit_events = {};\n assert.throws(() => prgl.mergedTableConfig, /cannot also be defined/);\n delete prgl.opts.tableConfig.audit_events;\n const sourceConfig = prgl.opts.tableConfig.audit_test_source as TableDefinition;\n for (const prefix of [AUDIT_TRIGGER_PREFIX, TABLE_CONFIG_TRIGGER_PREFIX]) {\n const name = prefix + \"user_trigger\";\n sourceConfig.triggers![name] = sourceConfig.triggers!.audit_test_custom;\n assert.throws(() => prgl.mergedTableConfig, /prefix reserved for prostgles/);\n delete sourceConfig.triggers![name];\n }\n await result.sql(`CREATE OR REPLACE FUNCTION audit_test_manual() RETURNS trigger LANGUAGE plpgsql AS 'BEGIN RETURN NULL; END;';\n CREATE TRIGGER audit_test_manual AFTER INSERT ON audit_test_source FOR EACH ROW EXECUTE FUNCTION audit_test_manual();`);\n const originalAudit = prgl.opts.audit;\n prgl.opts.audit = { ...audit, tableName: '\"audit_events\"' };\n assert.throws(() => prgl.mergedTableConfig, /must exactly match/);\n prgl.opts.audit = originalAudit;\n assert.equal(prgl.resolvedAuditConfig?.tableName, audit.tableName);\n assert.deepEqual(prgl.resolvedAuditConfig?.tables.audit_test_source, {\n idColumns: [\"a\", \"b\"],\n excludeColumns: [\"secret\"],\n });\n assert.deepEqual(prgl.resolvedAuditConfig?.tables.audit_test_nopk, {\n idColumns: [\"key\"],\n excludeColumns: [\"secret\"],\n });\n assert.equal(prgl.resolvedAuditConfig?.tables[audit.tableName], undefined);\n assert(!(\"audit\" in prgl.mergedTableConfig.tableConfig!.audit_test_source));\n const originalModifyClientSchema = prgl.opts.modifyClientSchema;\n let auditCallbacks = 0;\n prgl.opts.modifyClientSchema = (table, tableConfig, userData, resolvedAuditConfig) => {\n assert.deepEqual(resolvedAuditConfig, prgl.resolvedAuditConfig);\n auditCallbacks++;\n return table;\n };\n await source.getInfo!();\n await source.getColumns!();\n assert.equal(auditCallbacks, 2);\n prgl.opts.modifyClientSchema = originalModifyClientSchema;\n const mergedTriggers = prgl.mergedTableConfig.tableConfig!.audit_test_source.triggers!;\n assert(mergedTriggers.audit_test_custom);\n assert(Object.keys(mergedTriggers).some((name) => name.startsWith(AUDIT_TRIGGER_PREFIX)));\n\n const history = () => db.any(`SELECT * FROM \"audit_events\" ORDER BY id`);\n assert.equal((await history())[0].new_row.value, \"mounted\");\n assert.deepEqual(Object.keys((await history())[0]), AUDIT_TABLE_COLUMNS);\n assert.deepEqual(Object.keys(AUDIT_TABLE_COLUMN_DEFINITIONS), AUDIT_TABLE_COLUMNS);\n assert.deepEqual(Object.values(AUDIT_TABLE_COLUMN_NAMES), AUDIT_TABLE_COLUMNS);\n const auditRow: AuditTableRow = (await history())[0];\n assert.equal(auditRow.operation, \"INSERT\");\n assert.equal(Object.keys(prgl.mergedTableConfig.tableConfig!)[0], audit.tableName);\n // Comments are ordinary metadata and have no role in reconciliation or publishing.\n await result.sql(`COMMENT ON TABLE \"audit_events\" IS 'History shown in the UI'`);\n // Avoid duplicate bootstrap rows on subsequent initialization.\n (prgl.opts.tableConfig.audit_test_source as TableDefinition).onMount = async () => {};\n await source.insert!({\n a: 1,\n b: \"one\",\n value: \"before\",\n secret: \"never stored\",\n });\n await source.update!({ a: 1 }, { secret: \"also excluded\" });\n assert.equal((await history()).length, 2);\n await source.update!({ a: 1 }, { a: 2, value: \"after\" });\n await source.delete!({ a: 2 });\n const rows = await history();\n assert.deepEqual(rows[2].old_id, { a: 1, b: \"one\" });\n assert.deepEqual(rows[2].new_id, { a: 2, b: \"one\" });\n assert.equal(rows[2].table_name, \"audit_test_source\");\n assert.equal(rows[3].operation, \"DELETE\");\n assert.equal(rows[3].new_row, null);\n assert(!JSON.stringify(rows).includes(\"secret\"));\n await assert.rejects(\n prgl.dboBuilder.getTX(async (tx) => {\n await tx.audit_test_source!.insert!({ a: 5, b: \"rollback\" });\n throw new Error(\"rollback\");\n }),\n /rollback/,\n );\n assert.equal((await history()).length, 4);\n await result.sql(\n `INSERT INTO audit_test_existing VALUES (1, 'raw'); INSERT INTO audit_test_child VALUES (1, 1); DELETE FROM audit_test_existing WHERE id = 1;`,\n );\n assert.equal((await history()).filter((r) => r.operation === \"DELETE\").length, 3);\n await result.sql(\n `BEGIN; SET LOCAL \"prostgles.user\" = '{\"id\":\"actor\"}'; INSERT INTO audit_test_nopk VALUES ('k', 'hidden'); COMMIT;`,\n );\n assert.deepEqual((await history()).at(-1).actor, { id: \"actor\" });\n // Database context captures transaction identity, statement times, roles and application name.\n await db.tx(async (tx) => {\n await tx.none(\"SET LOCAL application_name = 'audit context test'\");\n const expected = await tx.one(`SELECT\n pg_current_xact_id()::text AS transaction_id,\n to_jsonb(transaction_timestamp()) AS transaction_started_at,\n current_role, session_user,\n current_setting('application_name') AS application_name`);\n for (const key of [\"context1\", \"context2\"]) {\n const { statement_started_at } = await tx.one(\n `INSERT INTO audit_test_nopk VALUES ($1, 'hidden')\n RETURNING to_jsonb(statement_timestamp()) AS statement_started_at`,\n [key],\n );\n const row = await tx.one(\n \"SELECT db_context FROM audit_events WHERE new_id = $1::jsonb\",\n [{ key }],\n );\n assert.deepEqual(row.db_context, { ...expected, statement_started_at });\n }\n });\n await result.sql(\n `INSERT INTO ${maskedTable} VALUES (1, 'mySecret'); DELETE FROM ${maskedTable} WHERE id = 1`,\n );\n const storedMaskedHistory = await db.any<AuditTableRow>(\n `SELECT * FROM \"audit_events\" WHERE table_name = $1 ORDER BY id`,\n [maskedTable],\n );\n assert.equal(storedMaskedHistory[0]?.new_row.secret, \"mySecret\");\n assert.equal(storedMaskedHistory[1]?.old_row.secret, \"mySecret\");\n for (const sql of [\n `UPDATE \"audit_events\" SET table_name = 'tampered'`,\n `DELETE FROM \"audit_events\"`,\n `TRUNCATE \"audit_events\"`,\n \"TRUNCATE audit_test_source\",\n ]) {\n await assert.rejects(result.sql(sql), {\n message: /Audit protection/,\n });\n }\n const parser = new PublishParser(prgl);\n const auditName = prgl.dboBuilder.tables.find(\n (t) => t.qualifiedNameParts.name === audit.tableName,\n )!.name;\n const rules = await parser.getParsedPublishTable({\n tableName: auditName,\n clientReq: undefined,\n clientInfo: undefined,\n resolvedPublishObject: { [auditName]: \"*\" },\n });\n assert(rules?.select);\n assert(!rules?.insert && !rules?.update && !rules?.delete);\n\n const clientRequest = {\n httpReq: {\n ip: \"127.0.0.1\",\n headers: { authorization: \"Bearer dGVzdA==\" },\n connection: { remoteAddress: \"127.0.0.1\" },\n },\n res: {},\n } as never;\n // Excluded columns are absent from stored snapshots, so they cannot safely be used to enforce inferred audit access.\n await assert.rejects(\n parser.getTableRules({\n tableName: auditName,\n clientReq: clientRequest,\n clientInfo: undefined,\n scope: undefined,\n resolvedPublishObject: {\n audit_test_source: {\n select: { fields: { a: 1 }, forcedFilter: { secret: null } },\n },\n },\n }),\n /secret.*invalid\\/disallowed|invalid\\/disallowed.*secret/,\n );\n const sourceClient = await result.getClientDBHandlers(clientRequest, undefined);\n assert(sourceClient.clientSchema.tableSchema.some(({ name }) => name === auditName));\n const clientAudit = sourceClient.clientDb[auditName]!;\n await assert.rejects(() => clientAudit.find!({}));\n await assert.rejects(() => clientAudit.find!({ invalid_audit_column: 1 }));\n await assert.rejects(() =>\n clientAudit.find!({}, { select: { invalid_audit_column: 1 } as never }),\n );\n const auditTableFilter = {\n schema_name: \"audit_test_main\",\n table_name: \"audit_test_source\",\n };\n const visibleHistory = await clientAudit.find!(auditTableFilter, {\n orderBy: { id: 1 },\n });\n assert.deepEqual(\n visibleHistory.map(({ operation, old_id, new_id, old_row, new_row }) => ({\n operation,\n old_id,\n new_id,\n old_row,\n new_row,\n })),\n [\n {\n operation: \"INSERT\",\n old_id: null,\n new_id: { a: 1 },\n old_row: null,\n new_row: { a: 1 },\n },\n {\n operation: \"UPDATE\",\n old_id: { a: 1 },\n new_id: { a: 2 },\n old_row: { a: 1 },\n new_row: { a: 2 },\n },\n {\n operation: \"DELETE\",\n old_id: { a: 2 },\n new_id: null,\n old_row: { a: 2 },\n new_row: null,\n },\n ],\n );\n assert.deepEqual(\n (\n await clientAudit.find!({\n $and: [auditTableFilter, { \"new_row->>a\": \"1\" }],\n })\n ).map(({ operation }) => operation),\n [\"INSERT\"],\n );\n const maskedAuditTableFilter = {\n schema_name: \"audit_test_main\",\n table_name: maskedTable,\n };\n const serverAudit = result.db[auditName]!;\n for (const snapshotColumn of [\n AUDIT_TABLE_COLUMN_NAMES.old_id,\n AUDIT_TABLE_COLUMN_NAMES.new_id,\n AUDIT_TABLE_COLUMN_NAMES.old_row,\n AUDIT_TABLE_COLUMN_NAMES.new_row,\n ]) {\n const secretFilter = {\n $and: [maskedAuditTableFilter, { [`${snapshotColumn}->>secret`]: \"mySecret\" }],\n };\n assert.deepEqual(\n (await serverAudit.find!(secretFilter)).map(({ operation }) => operation),\n [snapshotColumn.startsWith(\"old_\") ? \"DELETE\" : \"INSERT\"],\n );\n assert.deepEqual(await clientAudit.find!(secretFilter), []);\n }\n assert.deepEqual(\n await clientAudit.find!(\n {\n $and: [\n { schema_name: \"audit_test_main\" },\n { table_name: { $eq: \"audit_test_source\" } },\n ],\n },\n { orderBy: { id: 1 } },\n ),\n visibleHistory,\n );\n\n const clientSource = sourceClient.clientDb.audit_test_source!;\n await assert.rejects(() =>\n clientSource.find!({\n $exists: { [auditName]: { operation: \"INSERT\" } },\n }),\n );\n await source.insert!({ a: 3, b: \"one\" });\n assert.deepEqual(\n await clientSource.find!({\n $exists: {\n [auditName]: {\n schema_name: \"audit_test_main\",\n table_name: \"audit_test_source\",\n },\n },\n }),\n [{ a: 3 }],\n );\n\n const file = await result._db.one<{ id: string }>(\n `INSERT INTO ${fileTable} (original_name, data) VALUES ('test.txt', decode('01', 'hex')) RETURNING id`,\n );\n await result.db[documentTable]!.insert!({ file_id: file.id });\n await result.update({\n publish: { [documentTable]: { select: { fields: \"*\" } } },\n });\n const fileClient = await result.getClientDBHandlers(clientRequest, undefined);\n assert.deepEqual(\n fileClient.clientSchema.tableSchema.map(({ name }) => name).sort(),\n [auditName, documentTable, fileTable].sort(),\n );\n const fileHistory = await fileClient.clientDb[auditName]!.find!({\n schema_name: \"audit_test_main\",\n table_name: fileTable,\n });\n assert.equal(fileHistory.length, 1);\n assert.equal(fileHistory[0]!.new_row.id, file.id);\n\n const triggerOids = () =>\n db.any(\"SELECT oid FROM pg_trigger WHERE left(tgname, length($1)) = $1 ORDER BY oid\", [\n AUDIT_TRIGGER_PREFIX,\n ]);\n const beforeTriggers = await triggerOids();\n await result.sql(`CREATE TRIGGER audit_test_custom_insert AFTER INSERT ON audit_test_source\n FOR EACH ROW EXECUTE FUNCTION audit_test_custom();`);\n await result.restart();\n assert.deepEqual(await triggerOids(), beforeTriggers);\n assert.equal(\n await db.oneOrNone(\n \"SELECT oid FROM pg_trigger WHERE tgrelid = 'audit_test_source'::regclass AND tgname = 'audit_test_custom_insert'\",\n ),\n null,\n );\n // A fresh instance derives deselected trigger names from config, without saved state.\n const fresh = new Prostgles({\n ...prgl.opts,\n fileTable: undefined,\n tableConfig: undefined,\n audit: {\n ...audit,\n tables: {\n audit_test_source: {\n excludeColumns: [\"secret\"],\n },\n },\n },\n });\n const freshResult = await fresh.init(() => {}, { type: \"init\" });\n try {\n assert.equal(fresh.resolvedAuditConfig?.tables.audit_test_existing, undefined);\n const sourceTriggers = await db.any<{ tgname: string }>(\n \"SELECT tgname FROM pg_trigger WHERE tgrelid = 'audit_test_source'::regclass\",\n );\n assert(sourceTriggers.some((t) => t.tgname === \"audit_test_manual\"));\n assert(!sourceTriggers.some((t) => t.tgname.startsWith(TABLE_CONFIG_TRIGGER_PREFIX)));\n const count = (await history()).length;\n await freshResult.sql(\"INSERT INTO audit_test_existing VALUES (10, 'deselected')\");\n assert.equal((await history()).length, count);\n } finally {\n await freshResult.destroy();\n }\n await result.restart();\n // Existing transaction contexts remain usable while new database calls wait.\n let releaseTx: () => void;\n let startedTx: () => void;\n const txStarted = new Promise<void>((resolve) => {\n startedTx = resolve;\n });\n const txRelease = new Promise<void>((resolve) => {\n releaseTx = resolve;\n });\n const transaction = prgl.dboBuilder.getTX(async (tx) => {\n startedTx();\n await txRelease;\n await tx.audit_test_source!.insert!({\n a: 6,\n b: \"existing_transaction\",\n });\n });\n await txStarted;\n pauseSchema = true;\n const schemaPaused = new Promise<void>((resolve) => {\n schemaStarted = resolve;\n });\n const restart = result.restart();\n await schemaPaused;\n // Schema queries explicitly use the original database and must pass through.\n assert.equal((await prgl.dbForSchema!.one(\"SELECT 1 AS value\")).value, 1);\n const sharedDb = prgl.db!;\n const finished: string[] = [];\n const waitingDbQueries = Promise.all([\n sharedDb.any(\"SELECT 1\").then(() => finished.push(\"any\")),\n sharedDb.result(\"SELECT 1\").then(() => finished.push(\"result\")),\n sharedDb.task(async (t) => {\n await t.one(\"SELECT 1\");\n // Nested use of the root database must not wait on its own task.\n await sharedDb.one(\"SELECT 1\");\n finished.push(\"task\");\n }),\n sharedDb.tx(async (t) => {\n await t.tx((nested) => nested.one(\"SELECT 1\"));\n finished.push(\"tx\");\n }),\n ]);\n let queryFinished = false;\n const waiting = source.insert!({ a: 7, b: \"waiting\" }).then(() => {\n queryFinished = true;\n });\n await new Promise((resolve) => setTimeout(resolve, 25));\n assert(!queryFinished);\n assert.deepEqual(finished, []);\n releaseTx!();\n await transaction;\n assert(!queryFinished);\n assert.deepEqual(finished, []);\n releaseSchema!();\n await restart;\n await waiting;\n await waitingDbQueries;\n assert.deepEqual(finished.sort(), [\"any\", \"result\", \"task\", \"tx\"]);\n assert((await history()).some((r) => r.new_id?.a === 7));\n\n for (const tables of [\n { audit_test_source: 1, audit_test_existing: 0 },\n { missing_table: 1 },\n { audit_test_nopk: 1 },\n { audit_test_view: 1 },\n { audit_test_source: { excludeColumns: [\"a\"] } },\n ]) {\n prgl.opts.audit = { ...audit, tables: tables as any };\n await assert.rejects(result.restart());\n await assert.rejects(source.find!({}));\n await assert.rejects(sharedDb.one(\"SELECT 1\"));\n await assert.rejects(result.update({}));\n await assert.rejects(source.find!({}));\n }\n for (const [tableName, id] of [\n [\"audit_test_partitioned\", 91],\n [\"audit_test_partition\", 92],\n ] as const) {\n await result.update({ audit: { ...audit, tables: { [tableName]: 1 } } });\n const count = (await history()).length;\n await result.sql(`INSERT INTO ${tableName} VALUES (${id})`);\n const rows = await history();\n assert.equal(rows.length, count + 1);\n assert.equal(rows.at(-1).operation, \"INSERT\");\n assert.deepEqual(rows.at(-1).new_id, { id });\n }\n prgl.opts.audit = audit;\n await result.restart();\n // Removing a target removes only managed triggers and preserves existing history.\n const countBefore = (await history()).length;\n await result.update({\n audit: { ...audit, tables: { audit_test_source: 1 } },\n });\n await result.sql(\"INSERT INTO audit_test_existing VALUES (2, 'excluded')\");\n assert.equal((await history()).length, countBefore);\n await result.update({ audit: undefined });\n assert.equal(prgl.resolvedAuditConfig, undefined);\n await source.insert!({ a: 8, b: \"disabled\" });\n assert.equal((await history()).length, countBefore);\n await result.sql(`UPDATE \"audit_events\" SET actor = NULL WHERE false;\n DELETE FROM \"audit_events\" WHERE false`);\n prgl.opts.sqlFilePath = undefined;\n await result.sql(`CREATE TABLE audit_test.selected (id int PRIMARY KEY);\n CREATE TABLE audit_test.ignored (value text);\n CREATE VIEW audit_test.selected_view AS SELECT * FROM audit_test.selected;`);\n await result.update({\n tableConfig: undefined,\n schemaFilter: { audit_test_main: 1, audit_test: 1 },\n });\n const excludedTables = Object.fromEntries(\n prgl.dboBuilder.tables\n .filter(\n (t) =>\n t.qualifiedNameParts.schema !== \"audit_test\" ||\n t.qualifiedNameParts.name === \"ignored\",\n )\n .map((t) => [t.name, 0 as const]),\n );\n await result.update({ audit: { ...audit, tables: excludedTables } });\n await result.sql(\n \"INSERT INTO audit_test.selected VALUES (1); INSERT INTO audit_test.ignored VALUES ('not audited')\",\n );\n assert.equal((await history()).length, countBefore + 1);\n await result.sql(\"DROP TABLE audit_test.ignored\");\n // Default inclusion must reject the remaining unkeyed source table.\n await assert.rejects(result.update({ audit: { tableName: audit.tableName } }));\n await result.update({\n audit: {\n ...audit,\n tables: Object.fromEntries(\n Object.entries(excludedTables).filter(([name]) => !name.includes(\"ignored\")),\n ),\n },\n });\n await result.sql(\"INSERT INTO audit_test.selected VALUES (2)\");\n assert.equal((await history()).length, countBefore + 2);\n await result.update({\n audit: {\n tableName: \"audit_next_events\",\n tables: Object.fromEntries(\n Object.entries(excludedTables).filter(([name]) => !name.includes(\"ignored\")),\n ),\n },\n });\n await result.sql(\"INSERT INTO audit_test.selected VALUES (3)\");\n assert.equal(\n (await db.one(`SELECT count(*)::int AS count FROM \"audit_next_events\"`)).count,\n 1,\n );\n assert.equal((await history()).length, countBefore + 2);\n await result.sql(`UPDATE \"audit_events\" SET actor = NULL WHERE false;\n DELETE FROM \"audit_events\" WHERE false`);\n await assert.rejects(result.sql(`TRUNCATE \"audit_next_events\"`), {\n message: /Audit protection/,\n });\n } finally {\n releaseSchema?.();\n if (result) await result.destroy();\n else {\n await prgl.db?.$pool.end();\n await prgl.adminClient?.end();\n }\n await db.none(\n `DROP TABLE IF EXISTS audit_test_source, audit_test_existing, audit_test_child, audit_test_nopk, audit_test_partitioned, ${maskedTable} CASCADE; DROP TABLE IF EXISTS \"audit_events\", \"audit_next_events\" CASCADE; DROP SCHEMA IF EXISTS audit_test CASCADE;`,\n );\n await parentDb.none(\"DROP SCHEMA audit_test_main CASCADE\");\n await db.$pool.end();\n await rm(dir, { recursive: true, force: true });\n }\n },\n );\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/clientSchemaTypes.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":60,"column":25,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":63,"endColumn":63,"fix":{"range":[2561,2601],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'getUser' has no 'await' expression.","line":82,"column":13,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":82,"endColumn":28,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3213,3219],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'findUser' has no 'await' expression.","line":89,"column":13,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":89,"endColumn":29,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3457,3463],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":90,"column":35,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":90,"endColumn":53},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .every on an `any` value.","line":90,"column":48,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":90,"endColumn":53},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":90,"column":79,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":90,"endColumn":81},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":102,"column":41,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":102,"endColumn":63,"fix":{"range":[4052,4053],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":102,"column":41,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":102,"endColumn":55,"fix":{"range":[4044,4045],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":107,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":107,"endColumn":53,"fix":{"range":[4291,4292],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":107,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":107,"endColumn":45,"fix":{"range":[4283,4284],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":125,"column":35,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":125,"endColumn":74,"fix":{"range":[4894,4904],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":137,"column":35,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":137,"endColumn":74,"fix":{"range":[5412,5451],"text":"userIdContextValue"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":144,"column":35,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":144,"endColumn":74,"fix":{"range":[5716,5755],"text":"userIdContextValue"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":334,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":334,"endColumn":52,"fix":{"range":[16776,16777],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":338,"column":72,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":338,"endColumn":74,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[17004,17006],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":339,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":339,"endColumn":50,"fix":{"range":[17070,17071],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":340,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":340,"endColumn":51,"fix":{"range":[17160,17161],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":341,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":341,"endColumn":53,"fix":{"range":[17231,17232],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":342,"column":53,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":342,"endColumn":68,"fix":{"range":[17317,17318],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":342,"column":53,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":342,"endColumn":64,"fix":{"range":[17313,17314],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":346,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":346,"endColumn":63,"fix":{"range":[17578,17579],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":347,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":347,"endColumn":58,"fix":{"range":[17645,17646],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":348,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":348,"endColumn":58,"fix":{"range":[17724,17725],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":349,"column":39,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":349,"endColumn":68,"fix":{"range":[17817,17818],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":350,"column":53,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":350,"endColumn":68,"fix":{"range":[17894,17895],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":350,"column":53,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":350,"endColumn":64,"fix":{"range":[17890,17891],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":357,"column":38,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":357,"endColumn":73,"fix":{"range":[18224,18225],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":367,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":370,"endColumn":10},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":367,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":367,"endColumn":90,"fix":{"range":[18507,18508],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":367,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":367,"endColumn":82,"fix":{"range":[18499,18500],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .created_by on an `any` value.","line":371,"column":31,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":371,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .synced on an `any` value.","line":372,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":372,"endColumn":38},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":373,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":373,"endColumn":68,"fix":{"range":[18748,18749],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":373,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":373,"endColumn":60,"fix":{"range":[18740,18741],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":374,"column":26,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":374,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":378,"column":22,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":378,"endColumn":30,"fix":{"range":[18882,18883],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":379,"column":22,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":379,"endColumn":30,"fix":{"range":[18933,18934],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":382,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":382,"endColumn":78,"fix":{"range":[19075,19076],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":382,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":382,"endColumn":69,"fix":{"range":[19066,19067],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":383,"column":15,"nodeType":"Property","messageId":"anyAssignment","endLine":383,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":383,"column":28,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":383,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .created_by on an `any` value.","line":385,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":385,"endColumn":23},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":389,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":389,"endColumn":69,"fix":{"range":[19281,19282],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":389,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":389,"endColumn":61,"fix":{"range":[19273,19274],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":390,"column":15,"nodeType":"Property","messageId":"anyAssignment","endLine":390,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":390,"column":28,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":390,"endColumn":30},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":399,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":399,"endColumn":46,"fix":{"range":[19644,19645],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":402,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":402,"endColumn":51,"fix":{"range":[19826,19827],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":402,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":402,"endColumn":43,"fix":{"range":[19818,19819],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":407,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":407,"endColumn":51,"fix":{"range":[20035,20036],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":407,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":407,"endColumn":44,"fix":{"range":[20028,20029],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":408,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":408,"endColumn":66,"fix":{"range":[20122,20123],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":408,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":408,"endColumn":59,"fix":{"range":[20115,20116],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":409,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":409,"endColumn":39,"fix":{"range":[20182,20183],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":409,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":409,"endColumn":31,"fix":{"range":[20174,20175],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":410,"column":18,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":410,"endColumn":41,"fix":{"range":[20263,20264],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":410,"column":18,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":410,"endColumn":32,"fix":{"range":[20254,20255],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":412,"column":22,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":412,"endColumn":37,"fix":{"range":[20329,20330],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":413,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":413,"endColumn":64,"fix":{"range":[20413,20414],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":413,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":413,"endColumn":57,"fix":{"range":[20406,20407],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":413,"column":71,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":413,"endColumn":86,"fix":{"range":[20435,20436],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":414,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":414,"endColumn":46,"fix":{"range":[20492,20493],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":414,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":414,"endColumn":38,"fix":{"range":[20484,20485],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":416,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":416,"endColumn":51,"fix":{"range":[20639,20640],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":416,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":416,"endColumn":44,"fix":{"range":[20632,20633],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":418,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":418,"endColumn":50,"fix":{"range":[20769,20770],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":419,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":419,"endColumn":46,"fix":{"range":[20824,20825],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":420,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":420,"endColumn":46,"fix":{"range":[20879,20880],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":427,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":427,"endColumn":43,"fix":{"range":[21241,21242],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":427,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":427,"endColumn":35,"fix":{"range":[21233,21234],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":428,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":428,"endColumn":61,"fix":{"range":[21308,21309],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":428,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":428,"endColumn":50,"fix":{"range":[21297,21298],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":432,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":432,"endColumn":66,"fix":{"range":[21450,21451],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":432,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":432,"endColumn":59,"fix":{"range":[21443,21444],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":438,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":438,"endColumn":43,"fix":{"range":[21723,21724],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":438,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":438,"endColumn":35,"fix":{"range":[21715,21716],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":440,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":440,"endColumn":45,"fix":{"range":[21825,21826],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":440,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":440,"endColumn":37,"fix":{"range":[21817,21818],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":442,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":442,"endColumn":45,"fix":{"range":[21953,21954],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":442,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":442,"endColumn":37,"fix":{"range":[21945,21946],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":442,"column":48,"nodeType":"Property","messageId":"anyAssignment","endLine":442,"endColumn":70},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":442,"column":52,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":442,"endColumn":67,"fix":{"range":[21975,21976],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":448,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":448,"endColumn":66,"fix":{"range":[22167,22168],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":448,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":448,"endColumn":59,"fix":{"range":[22160,22161],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":453,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":453,"endColumn":69,"fix":{"range":[22486,22487],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":453,"column":32,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":453,"endColumn":61,"fix":{"range":[22478,22479],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":454,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":454,"endColumn":66,"fix":{"range":[22566,22567],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":454,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":454,"endColumn":59,"fix":{"range":[22559,22560],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":458,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":458,"endColumn":43,"fix":{"range":[22704,22705],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":458,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":458,"endColumn":35,"fix":{"range":[22696,22697],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":459,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":459,"endColumn":58,"fix":{"range":[22804,22805],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":459,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":459,"endColumn":50,"fix":{"range":[22796,22797],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":460,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":460,"endColumn":58,"fix":{"range":[22876,22877],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":460,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":460,"endColumn":50,"fix":{"range":[22868,22869],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":464,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":464,"endColumn":66,"fix":{"range":[23023,23024],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":464,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":464,"endColumn":59,"fix":{"range":[23016,23017],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":466,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":466,"endColumn":55,"fix":{"range":[23112,23113],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":466,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":466,"endColumn":48,"fix":{"range":[23105,23106],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":475,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":475,"endColumn":39,"fix":{"range":[23526,23527],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":475,"column":17,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":475,"endColumn":31,"fix":{"range":[23518,23519],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":476,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":476,"endColumn":40,"fix":{"range":[23567,23568],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":484,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":484,"endColumn":67,"fix":{"range":[23802,23803],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":484,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":484,"endColumn":58,"fix":{"range":[23793,23794],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":484,"column":74,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":484,"endColumn":89,"fix":{"range":[23824,23825],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":485,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":485,"endColumn":28,"fix":{"range":[23859,23860],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":492,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":492,"endColumn":69,"fix":{"range":[24256,24257],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":493,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":493,"endColumn":69,"fix":{"range":[24334,24335],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":494,"column":34,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":494,"endColumn":69,"fix":{"range":[24412,24413],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":496,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":496,"endColumn":51,"fix":{"range":[24532,24533],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":496,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":496,"endColumn":44,"fix":{"range":[24525,24526],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":499,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":499,"endColumn":39,"fix":{"range":[24703,24704],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":500,"column":25,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":500,"endColumn":60,"fix":{"range":[24765,24766],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":503,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":503,"endColumn":74,"fix":{"range":[24866,24867],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":504,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":504,"endColumn":74,"fix":{"range":[24962,24963],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":504,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":504,"endColumn":65,"fix":{"range":[24953,24954],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":507,"column":22,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":507,"endColumn":35,"fix":{"range":[25046,25047],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":509,"column":39,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":509,"endColumn":41,"suggestions":[{"messageId":"removeAsync","fix":{"range":[25157,25163],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":510,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":510,"endColumn":50,"fix":{"range":[25217,25218],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":512,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":512,"endColumn":64,"fix":{"range":[25313,25314],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":512,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":512,"endColumn":57,"fix":{"range":[25306,25307],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":570,"column":23,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":570,"endColumn":25,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[27843,27845],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/unbound-method","severity":2,"message":"A method that is not declared with `this: void` may cause unintentional scoping of `this` when separated from its object.\nConsider using an arrow function or explicitly `.bind()`ing the method to avoid calling the method with an unintended `this` value. \nIf a function does not access `this`, it can be annotated with `this: void`.","line":589,"column":25,"nodeType":"MemberExpression","messageId":"unboundWithoutThisAnnotation","endLine":589,"endColumn":43}],"suppressedMessages":[],"errorCount":110,"fatalErrorCount":0,"warningCount":13,"fixableErrorCount":103,"fixableWarningCount":0,"source":"import { DB_GENERATED_NAMES } from \"prostgles-server/dist/DBSchemaBuilder/constants\";\nimport { strict as assert } from \"node:assert\";\nimport { randomUUID } from \"node:crypto\";\nimport { once } from \"node:events\";\nimport { createServer } from \"node:http\";\nimport path from \"node:path\";\nimport { readFileSync } from \"node:fs\";\nimport { test } from \"node:test\";\nimport prostgles, {\n type DBHandlerServer,\n defineFunction,\n getLocalStorageClient,\n type ProstglesInitOptions,\n type PublishContextValue,\n} from \"prostgles-server\";\nimport type { DB } from \"prostgles-server/dist/Prostgles\";\nimport { getConnectionDetails } from \"prostgles-server/dist/DboBuilder/runSql/getAdminClient\";\nimport { CHANNELS, type ClientSchema } from \"prostgles-types\";\nimport { Server } from \"socket.io\";\nimport { io as createClient, type Socket } from \"socket.io-client\";\nimport ts from \"typescript\";\nimport express from \"express\";\n\nexport const testClientSchemaTypes = async (db: DB) => {\n await test(\n \"client publish profiles compile at startup and follow user types\",\n { timeout: 30000 },\n async (t) => {\n const http = createServer();\n const io = new Server(http);\n const sockets: Socket[] = [];\n let instance: Awaited<ReturnType<typeof prostgles>> | undefined;\n const suffix = randomUUID().slice(0, 8);\n const schemaName = `client_schema_types_${suffix}`;\n const tableName = \"correspondence\";\n const privateTableName = \"private_table\";\n const fileTableName = \"files\";\n const generatedTypesDir = path.resolve(\"debug/client-schema-types\", suffix);\n try {\n await db.none(`\n CREATE SCHEMA ${schemaName};\n CREATE TABLE ${schemaName}.${tableName} (\n id SERIAL PRIMARY KEY,\n body TEXT NOT NULL,\n created_by TEXT NOT NULL,\n note TEXT,\n internal TEXT NOT NULL DEFAULT 'default',\n synced BIGINT NOT NULL\n );\n CREATE TABLE ${schemaName}.${privateTableName} (id SERIAL PRIMARY KEY);\n `);\n http.listen(0, \"127.0.0.1\");\n await once(http, \"listening\");\n const address = http.address();\n assert(address && typeof address === \"object\");\n const userIdContextValue = {\n $prostglesContext: { objectName: \"user\", objectPropertyName: \"id\" },\n } as const satisfies PublishContextValue<{ user: { id: string } }>;\n instance = await prostgles({\n dbConnection: {\n ...getConnectionDetails(db),\n options: `-c search_path=${schemaName}`,\n } as unknown as ProstglesInitOptions[\"dbConnection\"],\n tsGeneratedTypesDir: generatedTypesDir,\n transactions: true,\n schemaFilter: { [schemaName]: 1 },\n tableConfig: {\n [tableName]: {\n syncConfig: { id_fields: [\"id\"], synced_field: \"synced\" },\n },\n },\n fileTable: {\n tableName: fileTableName,\n expressApp: express(),\n storageClient: getLocalStorageClient({\n localFolderPath: path.join(generatedTypesDir, \"files\"),\n }),\n },\n io,\n auth: {\n sidKeyName: \"token\",\n getUser: async (sid) => {\n if (!sid) return undefined;\n return {\n user: { id: `user-${sid}`, type: sid },\n clientUser: { id: sid, type: sid },\n };\n },\n findUser: async (filter) =>\n \"$and\" in filter && filter.$and?.every((condition) => condition.id === \"user-guest\") ?\n { id: \"user-guest\", type: \"guest\" }\n : undefined,\n },\n functions: {\n guest: {\n userFilter: { id: \"user-guest\" },\n functions: {\n transactionTest: defineFunction({\n input: { fail: \"boolean\" },\n run: ({ fail }, { withClientDbTx }) =>\n withClientDbTx(async (tx) => {\n const row = await tx[tableName]!.insert!(\n { body: fail ? \"function-rollback\" : \"function-commit\" },\n { returning: \"*\" },\n );\n if (fail) {\n await tx[tableName]!.update!({ id: row.id }, { internal: \"forbidden\" });\n }\n return row;\n }),\n }),\n },\n },\n },\n publish: [\n {\n name: \"GuestDBSchema\",\n userTypes: [\"guest\", \"member\"],\n publish: {\n [fileTableName]: { select: \"*\", insert: \"*\", update: \"*\" },\n [tableName]: {\n select: {\n fields: \"*\",\n forcedFilter: {\n created_by: userIdContextValue as unknown as string,\n },\n },\n update: {\n fields: [\"body\", \"note\", \"created_by\", \"synced\"],\n disableMethods: { updateBatch: 1 },\n postValidate: ({ row }) => {\n if (row.body === \"denied-by-post-validate\") {\n throw new Error(\"Update rejected by postValidate\");\n }\n },\n forcedData: {\n created_by: userIdContextValue as unknown as string,\n },\n },\n insert: {\n fields: { internal: 0 },\n checkFilter: { body: { $ne: \"denied-by-check-filter\" } },\n forcedData: {\n created_by: userIdContextValue as unknown as string,\n },\n },\n },\n },\n },\n {\n name: \"AdminDBSchema\",\n userTypes: [\"admin\"],\n publish: {\n [tableName]: { select: \"*\", insert: \"*\", update: \"*\" },\n [privateTableName]: { select: \"*\" },\n },\n },\n {\n name: \"ViewerDBSchema\",\n userTypes: [\"viewer\"],\n publish: { [tableName]: { select: \"*\" } },\n },\n ],\n onReady: () => {},\n });\n const { tsSchema } = await instance.getTSSchema();\n assert.doesNotMatch(tsSchema, /\\bimport(?:\\s|\\()/);\n assert.equal(\n readFileSync(path.join(generatedTypesDir, `${DB_GENERATED_NAMES.SCHEMA}.ts`), \"utf8\"),\n tsSchema,\n );\n await instance.reWriteDBSchema();\n assert.equal((await instance.getTSSchema()).tsSchema, tsSchema);\n assert.equal(io.sockets.sockets.size, 0);\n checkTypes(\n tsSchema,\n `\n import type { TableHandler, InsertDataWithNested, ClientSchemaFor } from \"prostgles-types\";\n import type { DBHandlerClient } from \"prostgles-client\";\n import type { DBOFullyTypedClient, InitResult, SessionUser } from \"../server/node_modules/prostgles-server\";\n import type { RestrictedFunctionContext, UnrestrictedFunctionContext } from \"../server/node_modules/prostgles-server/dist/PublishParser/defineServerFunction\";\n import type { getClientHandlers } from \"../server/node_modules/prostgles-server/dist/WebsocketAPI/getClientHandlers\";\n type Name = \"${tableName}\";\n type FileName = \"${fileTableName}\";\n declare const guest: TableHandler<GuestDBSchema, Name>;\n declare const files: TableHandler<GuestDBSchema, FileName>;\n declare const admin: TableHandler<AdminDBSchema, Name>;\n declare const combined: TableHandler<ClientDBSchema, Name>;\n declare const server: TableHandler<${DB_GENERATED_NAMES.SCHEMA}, Name>;\n declare const viewer: TableHandler<ViewerDBSchema, Name>;\n declare const client: DBHandlerClient<ClientDBSchema>;\n declare const adminClient: DBHandlerClient<AdminDBSchema>;\n declare const restricted: RestrictedFunctionContext<GuestDBSchema>;\n declare const unrestricted: UnrestrictedFunctionContext<DBGeneratedSchema>;\n declare const serverClient: DBOFullyTypedClient<ClientDBSchema>;\n declare const handlers: Awaited<ReturnType<typeof getClientHandlers<GuestDBSchema>>>;\n declare const instance: InitResult<DBGeneratedSchema, SessionUser, undefined, ClientDBSchema>;\n declare const guestClientSchema: ClientSchemaFor<ClientSchemas, \"guest\">;\n guestClientSchema satisfies GuestDBSchema;\n async () => {\n const combinedHandlers = await instance.getClientDBHandlers(null as never, undefined);\n const guestHandlers = await instance.getClientDBHandlers<GuestDBSchema>(null as never, undefined);\n await combinedHandlers.clientDb[\"${privateTableName}\"]?.find();\n // @ts-expect-error the guest profile does not publish private_table\n await guestHandlers.clientDb[\"${privateTableName}\"].find();\n const restrictedRow = await restricted.dbo[\"${tableName}\"].insert({ body: \"hello\" }, { returning: \"*\" });\n restrictedRow.created_by satisfies string;\n await handlers.clientDb[\"${tableName}\"].update({}, { body: \"changed\" });\n const transactionResult = await handlers.withClientDbTx(async (tx) => {\n const row = await tx[\"${tableName}\"].insert({ body: \"transaction\" }, { returning: \"*\" });\n row.created_by satisfies string;\n // @ts-expect-error transactions preserve profile field restrictions\n await tx[\"${tableName}\"].update({}, { internal: \"private\" });\n // @ts-expect-error transactions do not expose unpublished tables\n await tx[\"${privateTableName}\"].find();\n // @ts-expect-error transactions do not expose raw SQL\n tx.sql(\"SELECT 1\");\n // @ts-expect-error transactions do not expose nested transactions\n tx.tx(() => {});\n return row.id;\n });\n transactionResult satisfies number;\n restricted.withClientDbTx satisfies typeof handlers.withClientDbTx;\n // @ts-expect-error callbacks do not receive the unrestricted SQL transaction\n handlers.withClientDbTx((tx, rawTx) => rawTx.any(\"SELECT 1\"));\n // @ts-expect-error getClientHandlers preserves profile field restrictions\n await handlers.clientDb[\"${tableName}\"].update({}, { internal: \"private\" });\n // @ts-expect-error restricted functions respect forced insert fields\n await restricted.dbo[\"${tableName}\"].insert({ body: \"hello\", created_by: \"other\" });\n // @ts-expect-error restricted functions cannot start transactions\n restricted.dbo.tx(() => {});\n // @ts-expect-error client wrappers do not expose isView\n restricted.dbo[\"${tableName}\"].isView;\n // @ts-expect-error table is absent for some profiles\n await serverClient[\"${privateTableName}\"].find();\n await serverClient[\"${privateTableName}\"]?.find();\n await unrestricted.dbo.tx(async (tx) => {\n await tx[\"${tableName}\"].update({}, { internal: \"private\" });\n });\n\n await client[\"${tableName}\"].update({}, { body: \"changed\" });\n await guest.update({}, { body: 123 });\n // @ts-expect-error table is absent for guests and viewers\n await client[\"${privateTableName}\"].find();\n await client[\"${privateTableName}\"]?.find();\n await adminClient[\"${privateTableName}\"].find();\n const updated = await guest.update({}, { body: \"changed\", note: null }, { returning: \"*\" });\n updated?.[0]?.created_by satisfies string | undefined;\n await guest.updateBatch([[{}, { body: \"changed\" }]]);\n // @ts-expect-error excluded update field\n await guest.update({}, { internal: \"private\" });\n const forcedUpdate = { body: \"changed\", created_by: \"other\" };\n // @ts-expect-error forced update field through a variable\n await guest.update({}, forcedUpdate);\n // @ts-expect-error casts must not bypass excluded fields\n await guest.update({}, { created_by: { $merge: [] } });\n // @ts-expect-error updateBatch respects allowed fields\n await guest.updateBatch([[{}, { internal: \"private\" }]]);\n // @ts-expect-error read-only profiles cannot update\n await viewer.update({}, {});\n await admin.update({}, { internal: \"private\" });\n await combined.update({}, { internal: \"private\" });\n await server.update({}, { internal: \"private\" });\n const row = await guest.insert({ body: \"hello\", note: null }, { returning: \"*\" });\n row.created_by satisfies string;\n row.synced satisfies string;\n await guest.insertMany([{ body: \"hello\" }]);\n // @ts-expect-error excluded fields cannot be inserted\n await guest.insert({ body: \"hello\", internal: \"private\" });\n // @ts-expect-error a read-only profile cannot insert\n await viewer.insert({ body: \"hello\" });\n // @ts-expect-error body remains required\n await guest.insert({});\n // @ts-expect-error forced values are forbidden\n await guest.insert({ body: \"hello\", created_by: \"other\" });\n const supplied = { body: \"hello\", created_by: \"other\" };\n // @ts-expect-error also reject forced fields through variables\n await guest.insert(supplied);\n await admin.insert({ body: \"hello\", created_by: \"admin\" });\n // @ts-expect-error admin must supply created_by\n await admin.insert({ body: \"hello\" });\n await combined.insert({ body: \"hello\" });\n await combined.insert({ body: \"hello\", created_by: \"admin\" });\n // @ts-expect-error read-only profiles do not relax required insert fields\n await combined.insert({});\n // @ts-expect-error server insert defaults are unchanged\n await server.insert({ body: \"hello\", created_by: \"admin\" });\n await server.insert({ body: \"hello\", created_by: \"admin\", synced: 1 });\n await files.insert({ original_name: \"hello.txt\", data: new Uint8Array() });\n await files.insert({ id: \"file-id\", original_name: \"hello.txt\", original_last_modified: null, data: new Uint8Array() });\n // @ts-expect-error file metadata is generated by the server\n await files.insert({ original_name: \"hello.txt\", data: new Uint8Array(), content_type: \"text/plain\" });\n const fileWithGeneratedMetadata = { original_name: \"hello.txt\", data: new Uint8Array(), content_type: \"text/plain\" };\n // @ts-expect-error file metadata is also rejected through variables\n await files.insert(fileWithGeneratedMetadata);\n // @ts-expect-error original_name is required\n await files.insert({ data: new Uint8Array() });\n await files.update({}, { original_name: \"updated.txt\", data: new Uint8Array() });\n // @ts-expect-error file metadata cannot be updated directly\n await files.update({}, { content_type: \"text/plain\" });\n // @ts-expect-error file metadata updates are also rejected through variables\n await files.update({}, fileWithGeneratedMetadata);\n // @ts-expect-error unpublished tables are absent\n type Private = GuestDBSchema[\"${privateTableName}\"];\n type Nested = InsertDataWithNested<{}, GuestDBSchema, \"parent\">;\n const nested: Nested = { \"${tableName}\": [{ body: \"hello\" }] };\n // @ts-expect-error nested inputs also exclude forced fields\n const badNested: Nested = { \"${tableName}\": [{ created_by: \"other\" }] };\n };\n `,\n );\n const originalPublish = instance.options.publish;\n // await instance.update({ publish: originalPublish });\n const profiles: Record<string, ClientSchema> = {};\n for (const [role, name] of [\n [\"guest\", \"GuestDBSchema\"],\n [\"admin\", \"AdminDBSchema\"],\n [\"viewer\", \"ViewerDBSchema\"],\n [\"member\", \"MemberDBSchema\"],\n [\"unknown\", \"UnknownDBSchema\"],\n [\"\", \"AnonymousDBSchema\"],\n ]) {\n const socket = createClient(`http://127.0.0.1:${address.port}`, {\n transports: [\"websocket\"],\n reconnection: false,\n query: role ? { token: role } : {},\n });\n sockets.push(socket);\n profiles[name] = await new Promise<ClientSchema>((resolve, reject) => {\n socket.once(\"connect_error\", reject);\n socket.once(CHANNELS.SCHEMA, resolve);\n });\n }\n const guestSchema = profiles.GuestDBSchema!;\n assert.equal(guestSchema.err, undefined);\n const table = guestSchema.tableSchema.find((t) => t.name === tableName);\n assert(table);\n assert.equal(table.columns.find((c) => c.name === \"created_by\")?.insert, false);\n assert.deepEqual(profiles.MemberDBSchema!.tableSchema, guestSchema.tableSchema);\n assert.deepEqual(profiles.UnknownDBSchema!.tableSchema, []);\n assert.deepEqual(profiles.AnonymousDBSchema!.tableSchema, []);\n const serverSocket = io.sockets.sockets.get(sockets[0]!.id!);\n assert(serverSocket);\n const handlers = await instance.getClientDBHandlers({ socket: serverSocket }, undefined);\n assert.equal(privateTableName in handlers.clientDb, false);\n assert.equal(\"delete\" in handlers.clientDb[tableName]!, false);\n assert.equal(typeof handlers.clientDb[tableName]!.upsert, \"function\");\n assert.equal(typeof handlers.clientDb[tableName]!.insertMany, \"function\");\n assert.equal(\"updateBatch\" in handlers.clientDb[tableName]!, false);\n const viewerSocket = io.sockets.sockets.get(sockets[2]!.id!);\n assert(viewerSocket);\n const viewerHandlers = await instance.getClientDBHandlers(\n { socket: viewerSocket },\n undefined,\n );\n assert.deepEqual(Object.keys(viewerHandlers.clientDb).sort(), [tableName, \"tx\"]);\n assert.deepEqual(Object.keys(viewerHandlers.clientDb[tableName]!).sort(), [\n \"count\",\n \"find\",\n \"findOne\",\n \"getColumns\",\n \"getInfo\",\n \"size\",\n \"subscribe\",\n \"subscribeOne\",\n ]);\n const inserted = await (handlers.clientDb as DBHandlerServer)[tableName]!.insert!(\n { body: \"hello\" },\n { returning: \"*\" },\n );\n assert.equal(inserted.created_by, \"user-guest\");\n assert(Number(inserted.synced) > 0);\n const updated = await handlers.clientDb[tableName]!.update!(\n { id: inserted.id },\n { body: \"updated\" },\n { returning: \"*\" },\n );\n assert.equal(updated![0].body, \"updated\");\n assert.equal(updated![0].created_by, \"user-guest\");\n assert.equal(\n (\n await (handlers.clientDb as DBHandlerServer)[tableName]!.findOne!({\n id: inserted.id,\n })\n ).created_by,\n \"user-guest\",\n );\n await assert.rejects(\n (handlers.clientDb as DBHandlerServer)[tableName]!.update!(\n { id: inserted.id },\n { internal: \"forbidden\" },\n ),\n );\n const transactionRow = await handlers.withClientDbTx(async (...args) => {\n assert.equal(args.length, 1);\n const [tx] = args;\n assert.equal(\"sql\" in tx, false);\n assert.throws(\n () => (tx as DBHandlerServer).tx!(() => assert.fail(\"Nested transaction callback ran\")),\n /Transactions are not allowed in client handlers/,\n );\n const row = await tx[tableName]!.insert!(\n { body: \"transaction\", created_by: \"other\" },\n { returning: \"*\" },\n );\n assert.equal(row.created_by, \"user-guest\");\n assert.equal(await tx[tableName]!.count!({ id: row.id }), 1);\n assert.equal(await handlers.clientDb[tableName]!.count!({ id: row.id }), 0);\n await tx[tableName]!.update!({ id: row.id }, { body: \"committed\" });\n return tx[tableName]!.findOne!({ id: row.id });\n });\n assert.equal(transactionRow!.body, \"committed\");\n assert.equal(await handlers.clientDb[tableName]!.count!({ id: transactionRow!.id }), 1);\n await instance.db[tableName]!.insert!({ body: \"hidden\", created_by: \"other\" });\n await handlers.withClientDbTx(async (tx) => {\n assert.equal(await tx[tableName]!.count!({ body: \"hidden\" }), 0);\n assert.equal(privateTableName in tx, false);\n assert.equal(\"delete\" in tx[tableName]!, false);\n assert.equal(\"db\" in tx[tableName]!, false);\n assert.equal(\"tx\" in tx[tableName]!, false);\n });\n await t.test(\"caught subscription errors still roll back client transactions\", async () => {\n const row = { body: \"before-subscription-failure\" };\n const error = { message: /subscribe/ };\n await assert.rejects(\n handlers.withClientDbTx(async (tx) => {\n await tx[tableName]!.insert!(row);\n await assert.rejects(tx[tableName]!.subscribe!({}, {}, undefined), error);\n }),\n error,\n );\n assert.equal(await handlers.clientDb[tableName]!.count!(row), 0);\n });\n for (const failure of [\"throw\", \"permission\", \"database\"] as const) {\n const body = `rollback-${failure}`;\n await assert.rejects(\n handlers.withClientDbTx(async (tx) => {\n await tx[tableName]!.insert!({ body });\n if (failure === \"permission\") {\n await tx[tableName]!.update!({}, { internal: \"forbidden\" });\n } else if (failure === \"database\") {\n await tx[tableName]!.insert!({ id: transactionRow!.id, body });\n } else {\n throw new Error(\"rollback\");\n }\n }),\n );\n assert.equal(await handlers.clientDb[tableName]!.count!({ body }), 0);\n }\n await t.test(\"caught checkFilter errors still roll back client transactions\", async () => {\n const row = { body: \"denied-by-check-filter\" };\n const error = { message: /failed the check condition/ };\n await assert.rejects(handlers.clientDb[tableName]!.insert!(row), error);\n assert.equal(await handlers.clientDb[tableName]!.count!(row), 0);\n\n await assert.rejects(\n handlers.withClientDbTx(async (tx) => {\n await tx[tableName]!.insert!({ body: \"before-check-filter-failure\" });\n await assert.rejects(tx[tableName]!.insert!(row), error);\n await assert.rejects(tx[tableName]!.update!({}, { internal: \"forbidden\" }));\n }),\n error,\n );\n assert.equal(await handlers.clientDb[tableName]!.count!(row), 0);\n assert.equal(\n await handlers.clientDb[tableName]!.count!({ body: \"before-check-filter-failure\" }),\n 0,\n );\n });\n await t.test(\"caught postValidate errors still roll back client transactions\", async () => {\n const error = { message: \"Update rejected by postValidate\" };\n await assert.rejects(\n handlers.withClientDbTx(async (tx) => {\n await assert.rejects(\n tx[tableName]!.update!(\n { id: transactionRow!.id },\n { body: \"denied-by-post-validate\" },\n ),\n error,\n );\n }),\n error,\n );\n const row = await handlers.clientDb[tableName]!.findOne!({ id: transactionRow!.id });\n assert.equal(row!.body, \"committed\");\n });\n const scopedHandlers = await instance.getClientDBHandlers(\n { socket: serverSocket },\n { tables: { [tableName]: { select: { forcedFilter: { body: \"committed\" } } } } },\n );\n assert.deepEqual(Object.keys(scopedHandlers.clientDb).sort(), [tableName, \"tx\"]);\n assert.equal(\"insert\" in scopedHandlers.clientDb[tableName]!, false);\n assert.equal(\"update\" in scopedHandlers.clientDb[tableName]!, false);\n assert.equal(\"upsert\" in scopedHandlers.clientDb[tableName]!, false);\n await scopedHandlers.withClientDbTx(async (tx) => {\n assert.equal(await tx[tableName]!.count!(), 1);\n assert.deepEqual(Object.keys(tx).sort(), Object.keys(scopedHandlers.clientDb).sort());\n assert.deepEqual(\n Object.keys(tx[tableName]!),\n Object.keys(scopedHandlers.clientDb[tableName]!),\n );\n });\n const functionRow = await handlers.clientMethods.transactionTest!.run({ fail: false });\n const committedRow = await handlers.clientDb[tableName]!.findOne!({\n body: \"function-commit\",\n });\n assert.equal(committedRow!.created_by, \"user-guest\");\n assert.deepEqual(functionRow, committedRow);\n await assert.rejects(async () =>\n handlers.clientMethods.transactionTest!.run({ fail: true }),\n );\n assert.equal(await handlers.clientDb[tableName]!.count!({ body: \"function-rollback\" }), 0);\n sockets.forEach((socket) => socket.disconnect());\n io.disconnectSockets(true);\n await instance.update({ publish: originalPublish });\n await instance.update({\n publish: [{ name: \"EmptyDBSchema\", userTypes: [\"empty\"], publish: null }],\n });\n assert(\n (await instance.getTSSchema()).tsSchema.includes(\n \"export type EmptyDBSchema = Record<string, never>;\",\n ),\n );\n await instance.update({ publish: originalPublish });\n for (const [publish, error] of [\n [[{ userTypes: [], publish: null }], /userTypes must not be empty/],\n [\n [\n { userTypes: [\"guest\"], publish: null },\n { userTypes: [\"guest\"], publish: null },\n ],\n /Duplicate publish user type/,\n ],\n [\n [{ name: \"ClientDBSchema\", userTypes: [\"guest\"], publish: null }],\n /Invalid client schema name/,\n ],\n [\n [{ name: \"ClientSchemas\", userTypes: [\"guest\"], publish: null }],\n /Invalid client schema name/,\n ],\n [\n [\n { name: \"SameSchema\", userTypes: [\"a\"], publish: null },\n { name: \"SameSchema\", userTypes: [\"b\"], publish: null },\n ],\n /Duplicate publish schema name/,\n ],\n ] as const) {\n // await instance.update({ publish: publish });\n // await assert.rejects((handlers.clientDb as DBHandlerServer)[tableName]!.find!(), error);\n // await instance.update({ publish: originalPublish });\n await assert.rejects(instance.update({ publish }), error);\n assert.equal((await instance.getTSSchema()).tsSchema, tsSchema);\n }\n await instance.update({\n publish: [{ userTypes: [\"guest\"], publish: { [tableName]: { select: \"*\" } } }],\n });\n const updatedSchema = (await instance.getTSSchema()).tsSchema;\n assert(updatedSchema.includes(\"export type Publish1Schema\"));\n assert(!updatedSchema.includes(\"GuestDBSchema\"));\n assert.equal(\n readFileSync(path.join(generatedTypesDir, `${DB_GENERATED_NAMES.SCHEMA}.ts`), \"utf8\"),\n updatedSchema,\n );\n await instance.update({ publish: originalPublish });\n assert.equal((await instance.getTSSchema()).tsSchema, tsSchema);\n } finally {\n sockets.forEach((socket) => socket.disconnect());\n await instance?.destroy();\n await new Promise<void>((resolve) => io.close(() => resolve()));\n await db.none(`DROP SCHEMA IF EXISTS ${schemaName} CASCADE`);\n }\n },\n );\n};\n\nconst checkTypes = (schema: string, checks: string) => {\n const filename = path.resolve(__dirname, \"../../../client/client-schema-typecheck.ts\");\n const options: ts.CompilerOptions = {\n strict: true,\n noEmit: true,\n skipLibCheck: true,\n target: ts.ScriptTarget.ES2022,\n module: ts.ModuleKind.CommonJS,\n moduleResolution: ts.ModuleResolutionKind.Node10,\n };\n const host = ts.createCompilerHost(options);\n const getSourceFile = host.getSourceFile;\n host.getSourceFile = (name, languageVersion, onError, shouldCreateNewSourceFile) =>\n name === filename ?\n ts.createSourceFile(name, schema + checks, languageVersion, true)\n : getSourceFile(name, languageVersion, onError, shouldCreateNewSourceFile);\n const program = ts.createProgram([filename], options, host);\n const diagnostics = ts.getPreEmitDiagnostics(program);\n assert.equal(\n diagnostics.length,\n 0,\n ts.formatDiagnosticsWithColorAndContext(diagnostics, {\n getCanonicalFileName: (name) => name,\n getCurrentDirectory: () => process.cwd(),\n getNewLine: () => \"\\n\",\n }),\n );\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/00262cad/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/00262cad/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/00c862ab/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/00c862ab/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n __rb_test_commit: {\n columns: {\n id?: null | number;\n };\n \n };\n \"\\\"\\\"\\\"*\\\"\\\"\\\"\": {\n columns: {\n \"\\\"*\\\"\"?: null | string;\n id?: number;\n qq?: null | string;\n };\n \n };\n \"\\\"\\\"\\\"quoted0\\\"\\\"\\\"\": {\n columns: {\n \"\\\"id0\\\"\"?: number;\n \"\\\"quoted1_id\\\"\"?: null | number;\n \"\\\"text_col0\\\"\"?: null | string;\n };\n \n };\n \"\\\"\\\"\\\"quoted1\\\"\\\"\\\"\": {\n columns: {\n \"\\\"id1\\\"\"?: number;\n \"\\\"quoted2_id\\\"\"?: null | number;\n \"\\\"text_col1\\\"\"?: null | string;\n };\n referencedBy: {\"\\\"\\\"\\\"quoted0\\\"\\\"\\\"\":[\"\\\"quoted1_id\\\"\"]};\n };\n \"\\\"\\\"\\\"quoted2\\\"\\\"\\\"\": {\n columns: {\n \"\\\"id2\\\"\"?: number;\n \"\\\"text_col2\\\"\"?: null | string;\n };\n referencedBy: {\"\\\"\\\"\\\"quoted1\\\"\\\"\\\"\":[\"\\\"quoted2_id\\\"\"]};\n };\n \"\\\"*\\\"\": {\n columns: {\n \"*\"?: null | string;\n id?: number;\n };\n \n };\n api_table: {\n columns: {\n col1?: null | string;\n id?: number;\n };\n \n };\n bytea_test: {\n columns: {\n id?: number;\n value?: null | Uint8Array;\n };\n \n };\n \"client_schema_types_00c862ab.correspondence\": {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n \"client_schema_types_00c862ab.private_table\": {\n columns: {\n id?: number;\n };\n \n };\n client_schema_types_files_00c862ab: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n ex_j_ins: {\n columns: {\n added?: null | string;\n id?: number;\n name: string;\n public?: null | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n metadata?: null | any;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n version?: number;\n };\n referencedBy: {\"files_versions\":[\"file_id\"],\"users_public_info\":[\"avatar\"]};\n };\n files_versions: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n created?: string;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n file_id: string;\n id?: string;\n metadata?: null | any;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key: string;\n updated?: string;\n url?: string;\n version: number;\n };\n \n };\n geography_columns: {\n columns: {\n coord_dimension?: null | number;\n f_geography_column?: null | string;\n f_table_catalog?: null | string;\n f_table_name?: null | string;\n f_table_schema?: null | string;\n srid?: null | number;\n type?: null | string;\n };\n \n };\n geometry_columns: {\n columns: {\n coord_dimension?: null | number;\n f_geometry_column?: null | string;\n f_table_catalog?: null | string;\n f_table_name?: null | string;\n f_table_schema?: null | string;\n srid?: null | number;\n type?: null | string;\n };\n \n };\n insert_rules: {\n columns: {\n added?: null | string;\n id?: number;\n name?: null | string;\n };\n \n };\n items: {\n columns: {\n h?: null | string[];\n id?: number;\n name?: null | string;\n };\n referencedBy: {\"items2\":[\"items_id\"],\"items4a\":[\"items_id\"],\"items_multi\":[\"items0_id\",\"items1_id\",\"items2_id\",\"items3_id\"],\"slow_items\":[\"id\"],\"very_slow_items\":[\"id\"]};\n };\n items_multi: {\n columns: {\n id?: number;\n items0_id?: null | number;\n items1_id?: null | number;\n items2_id?: null | number;\n items3_id?: null | number;\n name?: null | string;\n };\n \n };\n items2: {\n columns: {\n hh?: null | string[];\n id?: number;\n items_id?: null | number;\n name?: null | string;\n };\n referencedBy: {\"items4a\":[\"items2_id\"]};\n };\n items3: {\n columns: {\n h?: null | string[];\n id?: number;\n name?: null | string;\n };\n \n };\n items4: {\n columns: {\n added?: null | string;\n id?: number;\n name: string;\n public?: null | string;\n };\n \n };\n items4_pub: {\n columns: {\n added?: null | string;\n id?: number;\n name: string;\n public?: null | string;\n };\n \n };\n items4a: {\n columns: {\n id?: number;\n items_id?: null | number;\n items2_id?: null | number;\n name?: null | string;\n };\n \n };\n lookup_col1: {\n columns: {\n description?: null | string;\n id: string;\n };\n referencedBy: {\"uuid_text\":[\"col1\",\"col2\",\"col3\"]};\n };\n newly_created_table: {\n columns: {\n id?: null | number;\n };\n \n };\n obj_table: {\n columns: {\n id?: number;\n obj?: null | any;\n };\n \n };\n planes: {\n columns: {\n flight_number?: null | string;\n id?: number;\n last_updated: number | string;\n x?: null | number;\n y?: null | number;\n };\n \n };\n rec: {\n columns: {\n id?: number;\n parent_id?: null | number;\n recf?: null | number;\n };\n referencedBy: {\"rec\":[\"parent_id\"]};\n };\n rec_ref: {\n columns: {\n id?: number;\n };\n referencedBy: {\"rec\":[\"recf\"]};\n };\n self_join: {\n columns: {\n id?: number;\n my_id?: null | number;\n my_id1?: null | number;\n name?: null | string;\n };\n referencedBy: {\"self_join\":[\"my_id\",\"my_id1\"]};\n };\n shapes: {\n columns: {\n geog?: null | string;\n geom?: null | string;\n id?: string;\n };\n \n };\n slow_items: {\n columns: {\n h?: null | string[];\n id?: null | number;\n name?: null | string;\n };\n \n };\n spatial_ref_sys: {\n columns: {\n auth_name?: null | string;\n auth_srid?: null | number;\n proj4text?: null | string;\n srid: number;\n srtext?: null | string;\n };\n \n };\n symbols: {\n columns: {\n id: string;\n };\n referencedBy: {\"trades\":[\"symbol\"]};\n };\n table_name3434: {\n columns: {\n id: number;\n };\n referencedBy: {\"table_name3434cccc\":[\"id\",\"id2\"]};\n };\n table_name3434cccc: {\n columns: {\n id?: null | number;\n id2?: null | number;\n };\n \n };\n tjson: {\n columns: {\n colOneOf: string;\n json: any;\n jsonOneOf?: null | any;\n status?: null | any;\n table_config?: null | any;\n };\n \n };\n tr1: {\n columns: {\n id?: number;\n t1?: null | string;\n };\n referencedBy: {\"tr2\":[\"tr1_id\"]};\n };\n tr2: {\n columns: {\n id?: number;\n t1?: null | string;\n t2?: null | string;\n tr1_id?: null | number;\n };\n referencedBy: {\"tr3\":[\"tr2_id\"]};\n };\n tr3: {\n columns: {\n id?: number;\n t2?: null | string;\n tr2_id?: null | number;\n };\n \n };\n trades: {\n columns: {\n id?: number;\n price: number | string;\n symbol: string;\n };\n \n };\n users: {\n columns: {\n email: string;\n id?: number;\n preferences: any;\n status: string;\n type: string;\n };\n \n };\n users_public_info: {\n columns: {\n avatar?: null | string;\n id?: number;\n name?: null | string;\n sid?: null | string;\n };\n \n };\n uuid_text: {\n columns: {\n col1?: null | string;\n col2?: null | string;\n col3?: null | string;\n id?: null | string;\n };\n \n };\n v_items: {\n columns: {\n id?: null | number;\n name?: null | string;\n };\n \n };\n various: {\n columns: {\n added?: null | string;\n h?: null | string[];\n id?: number;\n jsn?: null | any;\n name?: null | string;\n tsv?: null | string;\n };\n \n };\n very_slow_items: {\n columns: {\n h?: null | string[];\n id?: null | number;\n name?: null | string;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"client_schema_types_00c862ab.correspondence\": DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"client_schema_types_00c862ab.private_table\": DBGeneratedSchema[\"client_schema_types_00c862ab.private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"client_schema_types_00c862ab.correspondence\": DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"client_schema_types_files_00c862ab\": DBGeneratedSchema[\"client_schema_types_files_00c862ab\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types_files_00c862ab\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"client_schema_types_files_00c862ab\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"client_schema_types_00c862ab.correspondence\": DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"client_schema_types_00c862ab.correspondence\": DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"client_schema_types_00c862ab.correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"client_schema_types_00c862ab.private_table\": DBGeneratedSchema[\"client_schema_types_00c862ab.private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n \"client_schema_types_files_00c862ab\": DBGeneratedSchema[\"client_schema_types_files_00c862ab\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types_files_00c862ab\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"client_schema_types_files_00c862ab\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/03aceb6e/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/03aceb6e/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/1218ba95/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/1218ba95/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/157cea9b/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/157cea9b/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/15ab6c75/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/15ab6c75/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/1c179c45/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/1c179c45/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/2341d42e/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/2341d42e/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/2b46338b/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/2b46338b/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/2eaa9d89/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/2eaa9d89/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/3136c402/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/3136c402/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/39536b6b/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/39536b6b/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/3a04fa6e/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/3a04fa6e/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/3e4522c2/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/3e4522c2/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/41bb50c0/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/41bb50c0/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/4516d6bf/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/4516d6bf/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/46b1e0d5/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/46b1e0d5/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/501c343f/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/501c343f/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/50f22745/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/50f22745/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/594e8a98/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/594e8a98/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/5d80a2cb/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/5d80a2cb/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/5e6f4f8c/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/5e6f4f8c/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/703e9585/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/703e9585/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/7603b8bb/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/7603b8bb/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/7a95f33a/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/7a95f33a/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/7b6e7f79/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/7b6e7f79/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/7dc67a38/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/7dc67a38/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/7f17afe3/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/7f17afe3/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/8187abed/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/8187abed/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/848638f5/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/848638f5/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/85a0c081/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/85a0c081/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/94cfa03b/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/94cfa03b/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/9670c687/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/9670c687/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/9ac7f94c/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/9ac7f94c/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/9f6c446d/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/9f6c446d/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n \"client_schema_types.correspondence\": {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n \"client_schema_types.private_table\": {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"client_schema_types.correspondence\": DBGeneratedSchema[\"client_schema_types.correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"client_schema_types.private_table\": DBGeneratedSchema[\"client_schema_types.private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"client_schema_types.correspondence\": DBGeneratedSchema[\"client_schema_types.correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"client_schema_types.correspondence\": DBGeneratedSchema[\"client_schema_types.correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"client_schema_types.correspondence\": DBGeneratedSchema[\"client_schema_types.correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"client_schema_types.correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"client_schema_types.private_table\": DBGeneratedSchema[\"client_schema_types.private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/a3105bfc/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/a3105bfc/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/a3edf66f/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/a3edf66f/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/b1b635a7/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/b1b635a7/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/b38fe151/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/b38fe151/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/b50c282b/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/b50c282b/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/b664a4e7/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/b664a4e7/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/b8794ced/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/b8794ced/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/b9775871/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/b9775871/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/bfb64ae9/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/bfb64ae9/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/c16b0ce1/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/c16b0ce1/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/d2ac1269/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/d2ac1269/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/d4755dba/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/d4755dba/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/d80f82d2/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/d80f82d2/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/df404117/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/df404117/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/e04af8e7/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/e04af8e7/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/e72ef1e1/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/e72ef1e1/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/eafccedc/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/eafccedc/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/ed65c1bb/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/ed65c1bb/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/ef335b0b/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/ef335b0b/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/f1399e56/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/f1399e56/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\n\n\nexport type GeneratedFunctionSchema = { \n \"transactionTest\": (args: { fail: boolean; }) => Promise<unknown>;\n}","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/f3888f28/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/f3888f28/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/debug/client-schema-types/f91c138b/DBGeneratedSchema.ts","messages":[{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"Parsing error: ESLint was configured to lint `<tsconfigRootDir>/tests/server/debug/client-schema-types/f91c138b/DBGeneratedSchema.ts` with type information from `parserOptions.project`:\n- <tsconfigRootDir>/tests/server/tsconfig.json\n- <tsconfigRootDir>/tests/client/tsconfig.json\n- <tsconfigRootDir>/tests/config_test/tsconfig.json\nHowever, none of those TSConfigs include this file, so type information is not available for it. Either:\n- Change ESLint's list of included files to not include this file\n- Change one of those TSConfigs to include this file\n- Create a new TSConfig that includes this file and include it in your parserOptions.project\nSee the typescript-eslint docs for more info: https://tseslint.com/none-of-those-tsconfigs-include-this-file"}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/* Schema definition generated by prostgles-server */\n\nexport type DBGeneratedSchema = {\n correspondence: {\n columns: {\n body: string;\n created_by: string;\n id?: number;\n internal?: string;\n note?: null | string;\n synced: number | string;\n };\n \n };\n files: {\n columns: {\n added?: string;\n cloud_url?: null | string;\n content_length?: number | string;\n content_type?: string;\n data: Uint8Array;\n deleted?: null | string;\n deleted_from_storage?: null | string;\n description?: null | string;\n etag?: string;\n extension?: string;\n id?: string;\n original_last_modified?: null | string;\n original_name: string;\n signed_url?: null | string;\n signed_url_expires?: null | number | string;\n storage_key?: null | string;\n updated?: string;\n url?: string;\n };\n \n };\n private_table: {\n columns: {\n id?: number;\n };\n \n };\n \n}\n\ntype CollapseNumberIfStringPresent<T> =\n [Extract<T, string>] extends [never] ? T : Exclude<T, number>;\n\n/**\n * Numeric columns that serialize to strings keep the numeric type as well to allow:\n * - inserting numeric values as either numbers or strings\n * - reading numeric values as strings\n */\nexport type NormalizedRow<T extends Record<string, unknown>> = Required<{\n [K in keyof T]: CollapseNumberIfStringPresent<T[K]>;\n}>;\n\n/**\n * Data types as expected when selecting from the database\n * */\nexport type DBSchema = {\n [K in keyof DBGeneratedSchema]: NormalizedRow<DBGeneratedSchema[K][\"columns\"]>;\n};\n\n/**\n * Data types as expected when inserting into the database (optional fields might be nullable/with defaults)\n * */\nexport type DBSchemaForInsert = {\n [K in keyof DBGeneratedSchema]: DBGeneratedSchema[K][\"columns\"];\n};\n/** Publish access profiles. Row types retain the database schema; runtime permissions still apply. */\n\nexport type AdminDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type GuestDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"synced\">> & { \"created_by\"?: never; \"internal\"?: never }; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"note\" | \"synced\">> & { \"created_by\"?: never; \"id\"?: never; \"internal\"?: never }; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; };\n};\n\nexport type ViewerDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: never; updateColumns: never; };\n};\n\nexport type ClientSchemas = [\n { userType: \"admin\"; schema: AdminDBSchema },\n { userType: \"guest\" | \"member\"; schema: GuestDBSchema },\n { userType: \"viewer\"; schema: ViewerDBSchema },\n];\n\n/** Permissive write inputs across all supplied profiles; tables missing from a profile are optional. */\n\nexport type ClientDBSchema = {\n \"correspondence\": DBGeneratedSchema[\"correspondence\"] & { insertColumns: Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"id\" | \"note\"> & Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"created_by\" | \"internal\" | \"synced\">>; updateColumns: Partial<Pick<DBGeneratedSchema[\"correspondence\"][\"columns\"], \"body\" | \"created_by\" | \"id\" | \"internal\" | \"note\" | \"synced\">>; };\n \"files\": DBGeneratedSchema[\"files\"] & { insertColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; updateColumns: Pick<DBGeneratedSchema[\"files\"][\"columns\"], \"id\" | \"original_name\" | \"original_last_modified\" | \"data\"> & { \"added\"?: never; \"cloud_url\"?: never; \"content_length\"?: never; \"content_type\"?: never; \"deleted\"?: never; \"deleted_from_storage\"?: never; \"description\"?: never; \"etag\"?: never; \"extension\"?: never; \"signed_url\"?: never; \"signed_url_expires\"?: never; \"storage_key\"?: never; \"updated\"?: never; \"url\"?: never }; optional: true; };\n \"private_table\": DBGeneratedSchema[\"private_table\"] & { insertColumns: never; updateColumns: never; optional: true; };\n};\n\nexport type GeneratedFunctionSchema = Record<string, never>;","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/fileStorage.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":17,"column":19,"nodeType":"TSAsExpression","messageId":"unnecessaryAssertion","endLine":17,"endColumn":44,"fix":{"range":[977,993],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":18,"column":20,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":18,"endColumn":62,"fix":{"range":[1055,1056],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, comparison is always false, since `\"local\" !== \"local\"` is false.","line":21,"column":9,"nodeType":"BinaryExpression","messageId":"comparisonBetweenLiteralTypes","endLine":21,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":45,"column":26,"nodeType":"TSAsExpression","messageId":"unnecessaryAssertion","endLine":45,"endColumn":60,"fix":{"range":[2099,2115],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":60,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":60,"endColumn":69,"fix":{"range":[2542,2543],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":60,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":60,"endColumn":62,"fix":{"range":[2535,2536],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":63,"column":11,"nodeType":"Identifier","messageId":"neverNullish","endLine":63,"endColumn":24},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'validate' has no 'await' expression.","line":66,"column":9,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":66,"endColumn":25,"suggestions":[{"messageId":"removeAsync","fix":{"range":[2714,2720],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":71,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":71,"endColumn":80},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":74,"column":36,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":74,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":74,"column":45,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":74,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":74,"column":72,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":74,"endColumn":83},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":74,"column":81,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":74,"endColumn":83},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":75,"column":86,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":75,"endColumn":88},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":76,"column":37,"nodeType":"Property","messageId":"anyAssignment","endLine":76,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":76,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":76,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":76,"column":63,"nodeType":"Property","messageId":"anyAssignment","endLine":76,"endColumn":87},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":76,"column":85,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":76,"endColumn":87},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":77,"column":78,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":77,"endColumn":80},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":82,"column":30,"nodeType":"Property","messageId":"anyAssignment","endLine":82,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":82,"column":43,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":82,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":83,"column":9,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":83,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":83,"column":42,"nodeType":"Property","messageId":"anyAssignment","endLine":83,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":83,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":83,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":84,"column":27,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":84,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":85,"column":49,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":85,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":85,"column":58,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":85,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":87,"column":27,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":87,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":87,"column":36,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":87,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":90,"column":78,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":90,"endColumn":80},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":95,"column":77,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":95,"endColumn":79},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":104,"column":61,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":104,"endColumn":72},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":104,"column":70,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":104,"endColumn":72},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":106,"column":30,"nodeType":"Property","messageId":"anyAssignment","endLine":106,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":106,"column":43,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":106,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":107,"column":9,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":107,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":107,"column":42,"nodeType":"Property","messageId":"anyAssignment","endLine":107,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":107,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":107,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .metadata on an `any` value.","line":108,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":108,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":109,"column":27,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":109,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":111,"column":60,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":111,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":111,"column":69,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":111,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .version on an `any` value.","line":115,"column":50,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":115,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":122,"column":13,"nodeType":"Property","messageId":"anyAssignment","endLine":122,"endColumn":28},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":122,"column":26,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":122,"endColumn":28},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":128,"column":9,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":128,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":128,"column":42,"nodeType":"Property","messageId":"anyAssignment","endLine":128,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":128,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":128,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .metadata on an `any` value.","line":129,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":129,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":130,"column":27,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":130,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":132,"column":57,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":132,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":132,"column":66,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":132,"endColumn":68},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":135,"column":42,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":135,"endColumn":44,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[6266,6268],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":147,"column":35,"nodeType":"Property","messageId":"anyAssignment","endLine":147,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":147,"column":49,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":147,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":151,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":151,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":151,"column":45,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":151,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":157,"column":26,"nodeType":"Property","messageId":"anyAssignment","endLine":157,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":157,"column":39,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":157,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":167,"column":48,"nodeType":"Property","messageId":"anyAssignment","endLine":167,"endColumn":63},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":167,"column":61,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":167,"endColumn":63},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":168,"column":27,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":168,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":176,"column":53,"nodeType":"Property","messageId":"anyAssignment","endLine":176,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":176,"column":66,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":176,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":178,"column":53,"nodeType":"Property","messageId":"anyAssignment","endLine":178,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":178,"column":66,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":178,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":181,"column":28,"nodeType":"Property","messageId":"anyAssignment","endLine":181,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":181,"column":41,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":181,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":190,"column":50,"nodeType":"Property","messageId":"anyAssignment","endLine":190,"endColumn":65},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":190,"column":63,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":190,"endColumn":65},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":191,"column":29,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":191,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":200,"column":79,"nodeType":"Property","messageId":"anyAssignment","endLine":200,"endColumn":94},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":200,"column":92,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":200,"endColumn":94},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":203,"column":53,"nodeType":"Property","messageId":"anyAssignment","endLine":203,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":203,"column":66,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":203,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":209,"column":28,"nodeType":"Property","messageId":"anyAssignment","endLine":209,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":209,"column":41,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":209,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":215,"column":39,"nodeType":"Property","messageId":"anyAssignment","endLine":215,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":215,"column":52,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":215,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":219,"column":29,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":219,"endColumn":37},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":236,"column":20,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":236,"endColumn":29,"fix":{"range":[10229,10230],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":236,"column":39,"nodeType":"Property","messageId":"anyAssignment","endLine":236,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":236,"column":52,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":236,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":240,"column":29,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":240,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":273,"column":51,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":273,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":273,"column":60,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":273,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":276,"column":51,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":276,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":276,"column":60,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":276,"endColumn":71},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":294,"column":15,"nodeType":"Identifier","messageId":"neverNullish","endLine":294,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":323,"column":21,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":325,"endColumn":17},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":323,"column":33,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":323,"endColumn":42,"fix":{"range":[13870,13871],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":326,"column":15,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":326,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":326,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":326,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":350,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":350,"endColumn":32,"fix":{"range":[14888,14889],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":350,"column":42,"nodeType":"Property","messageId":"anyAssignment","endLine":350,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":350,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":350,"endColumn":57},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":351,"column":49,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":351,"endColumn":58,"fix":{"range":[14997,14998],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":351,"column":68,"nodeType":"Property","messageId":"anyAssignment","endLine":351,"endColumn":83},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":351,"column":81,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":351,"endColumn":83},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":352,"column":49,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":352,"endColumn":58,"fix":{"range":[15084,15085],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":353,"column":33,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":353,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":357,"column":50,"nodeType":"Property","messageId":"anyAssignment","endLine":357,"endColumn":65},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":357,"column":63,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":357,"endColumn":65},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":375,"column":47,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":375,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":375,"column":56,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":375,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":377,"column":26,"nodeType":"Property","messageId":"anyAssignment","endLine":377,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":377,"column":39,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":377,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":378,"column":26,"nodeType":"Property","messageId":"anyAssignment","endLine":378,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":378,"column":39,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":378,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":380,"column":9,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":380,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":380,"column":42,"nodeType":"Property","messageId":"anyAssignment","endLine":380,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":380,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":380,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `{ id: string; storage_key: string; }`.","line":381,"column":30,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":381,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .original_name on an `any` value.","line":381,"column":56,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":381,"endColumn":69},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":384,"column":27,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":384,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":384,"column":36,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":384,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .version on an `any` value.","line":385,"column":70,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":385,"endColumn":77},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .version on an `any` value.","line":385,"column":92,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":385,"endColumn":99},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":390,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":390,"endColumn":27,"fix":{"range":[16658,16659],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":391,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":393,"endColumn":11},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":394,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":394,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":394,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":394,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":396,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":396,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":396,"column":45,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":396,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":397,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":397,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":397,"column":45,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":397,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":398,"column":11,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":398,"endColumn":62},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":398,"column":44,"nodeType":"Property","messageId":"anyAssignment","endLine":398,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":398,"column":57,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":398,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":400,"column":29,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":400,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":400,"column":38,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":400,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":403,"column":51,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":403,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":405,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":405,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":405,"column":45,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":405,"endColumn":47},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":406,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":406,"endColumn":29,"fix":{"range":[17359,17360],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":415,"column":23,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":415,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":417,"column":53,"nodeType":"Property","messageId":"anyAssignment","endLine":417,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":417,"column":66,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":417,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":418,"column":51,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":418,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":418,"column":60,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":418,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":421,"column":29,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":421,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":421,"column":38,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":421,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":424,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":424,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":424,"column":45,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":424,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":425,"column":45,"nodeType":"Property","messageId":"anyAssignment","endLine":425,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":425,"column":58,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":425,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":426,"column":51,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":426,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":426,"column":60,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":426,"endColumn":71},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'upload' has no 'await' expression.","line":435,"column":11,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":435,"endColumn":25,"suggestions":[{"messageId":"removeAsync","fix":{"range":[18650,18656],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'delete' has no 'await' expression.","line":445,"column":11,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":445,"endColumn":25,"suggestions":[{"messageId":"removeAsync","fix":{"range":[19006,19012],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'downloadAsStream' has no 'await' expression.","line":448,"column":11,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":448,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[19097,19103],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":448,"column":59,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":448,"endColumn":76,"fix":{"range":[19143,19144],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'getSignedUrlForDownload' has no 'await' expression.","line":449,"column":11,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":449,"endColumn":42,"suggestions":[{"messageId":"removeAsync","fix":{"range":[19183,19189],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":464,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":464,"endColumn":85},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":466,"column":71,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":466,"endColumn":73},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":471,"column":71,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":471,"endColumn":73},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":476,"column":17,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":476,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":476,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":476,"endColumn":43},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":482,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":482,"endColumn":30,"fix":{"range":[20692,20693],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":482,"column":40,"nodeType":"Property","messageId":"anyAssignment","endLine":482,"endColumn":50},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":482,"column":48,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":482,"endColumn":50},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":487,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":487,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":487,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":487,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":488,"column":11,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":488,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":488,"column":39,"nodeType":"Property","messageId":"anyAssignment","endLine":488,"endColumn":49},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":488,"column":47,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":488,"endColumn":49},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .signed_url on an `any` value.","line":489,"column":28,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":489,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":490,"column":76,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":490,"endColumn":87},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":491,"column":24,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":491,"endColumn":53,"fix":{"range":[21206,21207],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":491,"column":36,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":491,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":491,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":491,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .storage_key on an `any` value.","line":494,"column":44,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":494,"endColumn":55},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":500,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":500,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":500,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":500,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":503,"column":32,"nodeType":"Property","messageId":"anyAssignment","endLine":503,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":503,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":503,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":516,"column":28,"nodeType":"Property","messageId":"anyAssignment","endLine":516,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":516,"column":41,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":516,"endColumn":43}],"suppressedMessages":[],"errorCount":25,"fatalErrorCount":0,"warningCount":154,"fixableErrorCount":15,"fixableWarningCount":0,"source":"import { strict as assert } from \"node:assert\";\nimport { test } from \"node:test\";\nimport fs from \"node:fs\";\nimport { join } from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport { once } from \"node:events\";\nimport express from \"express\";\nimport type { DB, DBHandlerServer } from \"prostgles-server\";\nimport type { TableHandler } from \"prostgles-server/dist/DboBuilder/TableHandler/TableHandler\";\nimport type { CloudStorageClient } from \"prostgles-server/dist/StorageClient/StorageClientTypes\";\nimport { setupFileServeHandler } from \"prostgles-server/dist/StorageClient/setupFileServeHandler\";\nimport { getFileStorageKey } from \"prostgles-server/dist/StorageClient/getFileStorageKey\";\nimport { deleteUnreferencedFile } from \"prostgles-server/dist/StorageClient/deleteUnreferencedFile\";\n\nexport const testFileStorage = async (dbo: DBHandlerServer, db: DB) => {\n await test(\"Managed storage permission and transaction safety\", async (t) => {\n const files = dbo.files as TableHandler;\n const config = files.dboBuilder.prostgles.opts.fileTable!;\n const storage = config.storageClient;\n assert.equal(storage.type, \"local\");\n if (storage.type !== \"local\") throw new Error(\"Expected local test storage\");\n const folder = storage.localFolderPath;\n const upload = storage.upload;\n const remove = storage.delete;\n let failUpload = false;\n let failDelete = false;\n let uploads = 0;\n storage.upload = async (args) => {\n uploads++;\n const result = await upload(args);\n if (failUpload) throw new Error(\"simulated upload failure\");\n return result;\n };\n storage.delete = async (key) => {\n if (failDelete) throw new Error(\"simulated delete failure\");\n await remove(key);\n };\n const fileData = (value: string) => ({\n data: Buffer.from(value),\n original_name: `${value}.txt`,\n });\n const list = () => fs.readdirSync(folder).sort();\n const read = (row: { id: string; storage_key: string | null }) =>\n fs.readFileSync(join(folder, getFileStorageKey(row)), \"utf8\");\n const fileVersions = dbo.files_versions as TableHandler;\n const versions = (fileId: string) =>\n fileVersions.find(\n { file_id: fileId },\n {\n orderBy: \"version\",\n limit: null,\n },\n ) as Promise<\n (Record<string, unknown> & {\n version: number;\n storage_key: string;\n metadata: { description: string } | null;\n })[]\n >;\n const hooks = files.dboBuilder.prostgles.opts.tableHooks!.files!;\n const originalHooks = hooks.afterEach;\n hooks.afterEach = [\n ...(originalHooks ?? []),\n {\n commands: { insert: 1, update: 1 },\n validate: async ({ row }) => {\n if (row.original_name === \"reject.txt\") throw new Error(\"file hook rejected\");\n },\n },\n ];\n let original = await files.insert(fileData(\"original\"), { returning: \"*\" });\n try {\n await t.test(\"legacy ID-based files remain readable and replaceable\", async () => {\n fs.renameSync(join(folder, original.storage_key), join(folder, original.id));\n await db.none(\"UPDATE files SET storage_key = NULL WHERE id = $1\", [original.id]);\n await fileVersions.update({ file_id: original.id }, { storage_key: original.id });\n const response = await fetch(`http://127.0.0.1:3001/files/${original.id}`, {\n headers: { Authorization: `Bearer ${Buffer.from(\"main\").toString(\"base64\")}` },\n });\n assert.equal(response.status, 200);\n assert.equal(await response.text(), \"original\");\n await files.update({ id: original.id }, fileData(\"updated\"));\n original = await files.findOne({ id: original.id });\n assert.equal(read(original), \"updated\");\n assert.equal(fs.existsSync(join(folder, original.id)), true);\n assert.deepEqual(\n (await versions(original.id)).map(({ version }) => version),\n [1, 2],\n );\n const previous = await fetch(`http://127.0.0.1:3001/files/${original.id}?version=1`, {\n headers: { Authorization: `Bearer ${Buffer.from(\"main\").toString(\"base64\")}` },\n });\n assert.equal(previous.status, 200);\n assert.equal(await previous.text(), \"original\");\n const updated = await fetch(`http://127.0.0.1:3001/files/${original.id}`, {\n headers: { Authorization: `Bearer ${Buffer.from(\"main\").toString(\"base64\")}` },\n });\n assert.equal(updated.status, 200);\n assert.equal(await updated.text(), \"updated\");\n });\n\n await t.test(\"custom columns do not require or interfere with file data\", async () => {\n const count = uploads;\n const versionsBeforeMetadataUpdate = await versions(original.id);\n const metadataUpdatePayload = { metadata: { description: \"metadata-only update\" } };\n await files.update({ id: original.id }, metadataUpdatePayload);\n original = await files.findOne({ id: original.id });\n assert.deepEqual(original.metadata, metadataUpdatePayload.metadata);\n assert.equal(read(original), \"updated\");\n assert.equal(uploads, count);\n const versionsAfterMetadataUpdate = await versions(original.id);\n assert.deepEqual(\n versionsAfterMetadataUpdate,\n versionsBeforeMetadataUpdate.map((fileVersion) => {\n if (fileVersion.version !== original.version) return fileVersion;\n return { ...fileVersion, metadata: metadataUpdatePayload.metadata };\n }),\n );\n\n const metadataReplacementPayload = { metadata: { description: \"replacement update\" } };\n await files.update(\n { id: original.id },\n {\n ...fileData(\"updated\"),\n ...metadataReplacementPayload,\n },\n );\n original = await files.findOne({ id: original.id });\n assert.deepEqual(original.metadata, metadataReplacementPayload.metadata);\n assert.equal(read(original), \"updated\");\n assert.equal(uploads, count + 1);\n const versionsAfterReplacement = await versions(original.id);\n assert.deepEqual(versionsAfterReplacement.slice(0, -1), versionsAfterMetadataUpdate);\n assert.deepEqual(\n versionsAfterReplacement.at(-1)?.metadata,\n metadataReplacementPayload.metadata,\n );\n });\n\n await t.test(\"filtered updates and failed validation preserve storage\", async () => {\n const count = uploads;\n const rules = {\n update: {\n fields: \"*\",\n filterFields: \"*\",\n returningFields: \"*\",\n forcedFilter: { id: { $ne: original.id } },\n },\n } as const;\n assert.deepEqual(\n await files.update({ id: original.id }, fileData(\"forbidden\"), { returning: \"*\" }, rules),\n [],\n );\n assert.equal(uploads, count);\n const before = list();\n await assert.rejects(() =>\n files.update({ id: original.id }, fileData(\"forbidden\"), undefined, {\n update: {\n fields: [\"original_name\"],\n filterFields: \"*\",\n returningFields: \"*\",\n },\n }),\n );\n assert.equal(uploads, count + 1);\n assert.deepEqual(list(), before);\n assert.deepEqual(await files.findOne({ id: original.id }), original);\n assert.equal(read(original), \"updated\");\n });\n\n await t.test(\n \"failed uploads and application hooks leave no replacement objects\",\n async () => {\n const before = list();\n failUpload = true;\n await assert.rejects(() => files.update({ id: original.id }, fileData(\"failed\")));\n failUpload = false;\n await assert.rejects(() => files.update({ id: original.id }, fileData(\"reject\")));\n await assert.rejects(() => files.insert(fileData(\"reject\")));\n await assert.rejects(() =>\n files.update({ id: original.id }, fileData(\"check-filter\"), undefined, {\n update: {\n fields: \"*\",\n filterFields: \"*\",\n returningFields: \"*\",\n checkFilter: { original_name: \"allowed.txt\" },\n },\n }),\n );\n assert.deepEqual(await files.findOne({ id: original.id }), original);\n assert.equal(read(original), \"updated\");\n assert.deepEqual(list(), before);\n },\n );\n\n await t.test(\n \"duplicate IDs, conflict updates and SQL-only requests cannot overwrite\",\n async () => {\n const before = list();\n await assert.rejects(() => files.insert({ ...fileData(\"duplicate\"), id: original.id }));\n const count = uploads;\n await assert.rejects(() =>\n files.insert({ ...fileData(\"conflict\"), id: original.id }, { onConflict: \"DoUpdate\" }),\n );\n await assert.rejects(() =>\n files.insert(fileData(\"statement\"), { returnType: \"statement\" }),\n );\n await assert.rejects(() =>\n files.update({ id: original.id }, fileData(\"statement\"), {\n returnType: \"statement\",\n }),\n );\n assert.equal(uploads, count);\n await files.insert(\n { ...fileData(\"ignored\"), id: original.id },\n { onConflict: \"DoNothing\" },\n );\n assert.deepEqual(list(), before);\n assert.equal(read(original), \"updated\");\n },\n );\n\n await t.test(\"PostgreSQL update policies are enforced before uploading\", async () => {\n await db.none(`\n CREATE ROLE storage_rls_test;\n GRANT USAGE ON SCHEMA public TO storage_rls_test;\n GRANT SELECT, UPDATE ON files TO storage_rls_test;\n ALTER TABLE files ENABLE ROW LEVEL SECURITY;\n CREATE POLICY storage_select ON files FOR SELECT TO storage_rls_test USING (true);\n CREATE POLICY storage_update ON files FOR UPDATE TO storage_rls_test USING (false);\n `);\n try {\n const count = uploads;\n const rows = await files.dboBuilder.getTX(async (tx, pgTx) => {\n await pgTx.none(\"SET LOCAL ROLE storage_rls_test\");\n return tx.files!.update({ id: original.id }, fileData(\"forbidden\"), { returning: \"*\" });\n });\n assert.deepEqual(rows, []);\n assert.equal(uploads, count);\n assert.equal(read(original), \"updated\");\n } finally {\n await db.none(`\n DROP POLICY storage_select ON files;\n DROP POLICY storage_update ON files;\n ALTER TABLE files DISABLE ROW LEVEL SECURITY;\n REVOKE SELECT, UPDATE ON files FROM storage_rls_test;\n REVOKE USAGE ON SCHEMA public FROM storage_rls_test;\n DROP ROLE storage_rls_test;\n `);\n }\n });\n\n await t.test(\"RLS-hidden references fail closed during storage cleanup\", async () => {\n const role = \"storage_cleanup_rls_test\";\n await db.none(`\n CREATE ROLE ${role};\n GRANT USAGE ON SCHEMA public TO ${role};\n GRANT SELECT ON files, files_versions TO ${role};\n ALTER TABLE files ENABLE ROW LEVEL SECURITY;\n ALTER TABLE files_versions ENABLE ROW LEVEL SECURITY;\n CREATE POLICY storage_cleanup_files ON files TO ${role} USING (false);\n CREATE POLICY storage_cleanup_versions ON files_versions TO ${role} USING (false);\n `);\n const rlsDb = {\n tx: (callback: (tx: DB) => unknown) =>\n db.tx(async (tx) => {\n await tx.none(`SET LOCAL ROLE ${role}`);\n return callback(tx as unknown as DB);\n }),\n } as unknown as DB;\n try {\n await assert.rejects(\n deleteUnreferencedFile(rlsDb, config, original.storage_key),\n /row-level security policy/,\n );\n assert.equal(fs.existsSync(join(folder, original.storage_key)), true);\n } finally {\n await db.none(`\n DROP POLICY storage_cleanup_files ON files;\n DROP POLICY storage_cleanup_versions ON files_versions;\n ALTER TABLE files DISABLE ROW LEVEL SECURITY;\n ALTER TABLE files_versions DISABLE ROW LEVEL SECURITY;\n REVOKE SELECT ON files, files_versions FROM ${role};\n REVOKE USAGE ON SCHEMA public FROM ${role};\n DROP ROLE ${role};\n `);\n }\n });\n\n await t.test(\"beforeEach lifecycle callbacks follow the outer transaction\", async () => {\n const beforeHooks = hooks.beforeEach;\n const events: string[] = [];\n hooks.beforeEach = [\n ...(beforeHooks ?? []),\n {\n commands: { insert: 1 },\n validate: ({ data, onCommit, onRollback }) => {\n onCommit(async ({ db: committedDb }) => {\n assert.equal(committedDb, db);\n assert.ok(\n await committedDb.oneOrNone(\"SELECT id FROM files WHERE id = $1\", [data.id]),\n );\n events.push(\"commit\");\n });\n onRollback(async ({ db: rolledBackDb }) => {\n assert.equal(rolledBackDb, db);\n assert.equal(\n await rolledBackDb.oneOrNone(\"SELECT id FROM files WHERE id = $1\", [data.id]),\n null,\n );\n events.push(\"rollback\");\n });\n if (data.original_name === \"callback-failure.txt\")\n throw new Error(\"beforeEach failed\");\n },\n },\n ];\n try {\n for (const outcome of [\"commit\", \"rollback\", \"failure\"]) {\n events.length = 0;\n let id: string | undefined;\n const mutation = files.dboBuilder.getTX(async (tx) => {\n const row = await tx.files!.insert(fileData(`callback-${outcome}`), {\n returning: \"*\",\n });\n id = row.id;\n assert.deepEqual(events, []);\n if (outcome === \"rollback\") throw new Error(\"outer transaction failed\");\n });\n if (outcome === \"commit\") {\n await mutation;\n assert.deepEqual(events, [\"commit\"]);\n await files.delete({ id });\n } else {\n await assert.rejects(mutation);\n assert.deepEqual(events, [\"rollback\"]);\n }\n }\n } finally {\n hooks.beforeEach = beforeHooks;\n }\n });\n\n await t.test(\"outer rollback preserves replaced and deleted objects\", async () => {\n const before = list();\n for (const operation of [\"update\", \"delete\", \"insert\"] as const) {\n await assert.rejects(() =>\n files.dboBuilder.getTX(async (tx) => {\n if (operation === \"update\")\n await tx.files!.update({ id: original.id }, fileData(\"rollback\"));\n if (operation === \"delete\") await tx.files!.delete({ id: original.id });\n if (operation === \"insert\") await tx.files!.insert(fileData(\"rollback\"));\n assert.equal(read(original), \"updated\");\n throw new Error(\"rollback outer transaction\");\n }),\n );\n assert.deepEqual(await files.findOne({ id: original.id }), original);\n assert.deepEqual(list(), before);\n }\n });\n\n await t.test(\"a failed multi-insert waits for other uploads before cleanup\", async () => {\n const before = list();\n await assert.rejects(() =>\n files.insert([\n fileData(\"batch\"),\n { data: Buffer.from(\"invalid\"), original_name: \"no-extension\" },\n ]),\n );\n assert.deepEqual(list(), before);\n });\n\n await t.test(\"concurrent replacements leave one complete referenced object\", async () => {\n const before = list();\n const beforeVersions = await versions(original.id);\n await Promise.all([\n files.update({ id: original.id }, fileData(\"first\")),\n files.update({ id: original.id }, fileData(\"second\")),\n ]);\n original = await files.findOne({ id: original.id });\n assert.equal(`${read(original)}.txt`, original.original_name);\n assert.equal(list().length, before.length + 2);\n assert.deepEqual(\n (await versions(original.id)).map(({ version }) => version),\n [...beforeVersions.map(({ version }) => version), original.version - 1, original.version],\n );\n });\n\n await t.test(\"version retention removes only unreferenced objects\", async () => {\n config.versioning!.maxVersions = 2;\n let retained = await files.insert(fileData(\"retained-1\"), {\n returning: \"*\",\n });\n const firstKey = retained.storage_key;\n try {\n await files.update({ id: retained.id }, fileData(\"retained-2\"));\n await files.update({ id: retained.id }, fileData(\"retained-3\"));\n retained = await files.findOne({ id: retained.id });\n assert.deepEqual(\n (await versions(retained.id)).map(({ version }) => version),\n [2, 3],\n );\n assert.equal(fs.existsSync(join(folder, firstKey)), false);\n } finally {\n await files.delete({ id: retained.id });\n config.versioning!.maxVersions = undefined;\n }\n });\n\n await t.test(\n \"foreign-key failure preserves bytes and deletion waits for commit\",\n async () => {\n await db.none(\n \"CREATE TABLE storage_file_ref (file_id uuid REFERENCES files(id)); INSERT INTO storage_file_ref VALUES($1)\",\n [original.id],\n );\n await assert.rejects(() => files.delete({ id: original.id }));\n assert.equal(fs.existsSync(join(folder, original.storage_key)), true);\n await db.none(\"DROP TABLE storage_file_ref\");\n const storedKeys = new Set(\n (await versions(original.id)).map(({ storage_key }) => storage_key),\n );\n failDelete = true;\n await files.delete({ id: original.id });\n assert.ok(!(await files.findOne({ id: original.id })));\n assert.equal(fs.existsSync(join(folder, original.storage_key)), true);\n failDelete = false;\n await Promise.all([...storedKeys].map((storageKey) => remove(storageKey)));\n },\n );\n await t.test(\"cloud downloads and cleanup use the committed storage key\", async () => {\n const objects = new Map<string, Buffer>();\n const cloud: CloudStorageClient = {\n type: \"cloud\",\n upload: async ({ file, fileName }) => {\n assert.ok(Buffer.isBuffer(file));\n objects.set(fileName, file);\n return {\n type: \"cloud\",\n url: `https://storage.invalid/${fileName}`,\n contentHash: \"cloud-etag\",\n contentLength: file.length,\n };\n },\n delete: async (key) => {\n objects.delete(key);\n },\n downloadAsStream: async (key) => Readable.from([objects.get(key)!]),\n getSignedUrlForDownload: async (key) => `https://storage.invalid/${key}`,\n };\n config.storageClient = cloud;\n const app = express();\n const { destroy } = setupFileServeHandler(\n db,\n { ...config, fileServePath: \"/storage-cloud\" },\n cloud,\n app,\n files.dboBuilder.prostgles,\n );\n const server = app.listen(0, \"127.0.0.1\");\n await once(server, \"listening\");\n const address = server.address();\n assert.ok(address && typeof address === \"object\");\n let row = await files.insert(fileData(\"cloud-original\"), { returning: \"*\" });\n const download = () =>\n fetch(`http://127.0.0.1:${address.port}/storage-cloud/${row.id}`, {\n headers: { Authorization: `Bearer ${Buffer.from(\"main\").toString(\"base64\")}` },\n redirect: \"manual\",\n });\n const downloadVersion = (version: number) =>\n fetch(`http://127.0.0.1:${address.port}/storage-cloud/${row.id}?version=${version}`, {\n headers: { Authorization: `Bearer ${Buffer.from(\"main\").toString(\"base64\")}` },\n redirect: \"manual\",\n });\n try {\n const firstKey = row.storage_key;\n const response = await download();\n assert.equal(response.status, 302);\n assert.equal(response.headers.get(\"location\"), `https://storage.invalid/${firstKey}`);\n await assert.rejects(() =>\n files.dboBuilder.getTX(async (tx) => {\n await tx.files!.update({ id: row.id }, fileData(\"cloud-rollback\"));\n throw new Error(\"rollback cloud update\");\n }),\n );\n assert.deepEqual([...objects.keys()], [firstKey]);\n await files.update({ id: row.id }, fileData(\"cloud-updated\"));\n row = await files.findOne({ id: row.id });\n assert.equal(row.signed_url, null);\n assert.deepEqual(new Set(objects.keys()), new Set([firstKey, row.storage_key]));\n assert.equal(objects.get(row.storage_key)!.toString(), \"cloud-updated\");\n assert.equal(\n (await download()).headers.get(\"location\"),\n `https://storage.invalid/${row.storage_key}`,\n );\n assert.equal(\n (await downloadVersion(1)).headers.get(\"location\"),\n `https://storage.invalid/${firstKey}`,\n );\n await files.delete({ id: row.id });\n assert.equal(objects.size, 0);\n } finally {\n await files.delete({ id: row.id });\n destroy();\n await new Promise<void>((resolve) => server.close(() => resolve()));\n config.storageClient = storage;\n }\n });\n } finally {\n failUpload = false;\n failDelete = false;\n storage.upload = upload;\n storage.delete = remove;\n hooks.afterEach = originalHooks;\n await db.none(\"DROP TABLE IF EXISTS storage_file_ref\");\n await files.delete({ id: original.id });\n }\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/index.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":13,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":13,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":13,"column":14,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":13,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createServer on an `any` value.","line":13,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":13,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":18,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":18,"endColumn":88},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":18,"column":40,"nodeType":"CallExpression","messageId":"unsafeCall","endLine":18,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":19,"column":7,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":20,"endColumn":90},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":20,"column":31,"nodeType":"CallExpression","messageId":"unsafeCall","endLine":20,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":22,"column":1,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":22,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .listen on an `any` value.","line":22,"column":6,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":22,"endColumn":12},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":27,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":27,"endColumn":58,"fix":{"range":[1050,1050],"text":" type"}},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":39,"column":19,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":39,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe spread of an `any[]` array type.","line":41,"column":17,"nodeType":"SpreadElement","messageId":"unsafeArraySpread","endLine":41,"endColumn":24},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'dd' is defined but never used. Allowed unused vars must match /^_/u.","line":87,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":87,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":88,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":90,"endColumn":16},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":91,"column":7,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":91,"endColumn":11},{"ruleId":"@typescript-eslint/unbound-method","severity":2,"message":"A method that is not declared with `this: void` may cause unintentional scoping of `this` when separated from its object.\nConsider using an arrow function or explicitly `.bind()`ing the method to avoid calling the method with an unintended `this` value. \nIf a function does not access `this`, it can be annotated with `this: void`.","line":92,"column":3,"nodeType":"MemberExpression","messageId":"unboundWithoutThisAnnotation","endLine":92,"endColumn":15},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":95,"column":1,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":438,"endColumn":6,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[2889,2889],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[2889,2889],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":99,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":99,"endColumn":24},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'dbo' is defined but never used. Allowed unused args must match /^_/u.","line":102,"column":25,"nodeType":"Identifier","messageId":"unusedVar","endLine":102,"endColumn":28},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'db' is defined but never used. Allowed unused args must match /^_/u.","line":102,"column":30,"nodeType":"Identifier","messageId":"unusedVar","endLine":102,"endColumn":32},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":108,"column":3,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":437,"endColumn":6,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[3238,3238],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[3238,3238],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":111,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":111,"endColumn":7},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'onLog' has no 'await' expression.","line":116,"column":5,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":116,"endColumn":18,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3580,3586],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'db' is defined but never used. Allowed unused args must match /^_/u.","line":157,"column":33,"nodeType":"Identifier","messageId":"unusedVar","endLine":157,"endColumn":35},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'cb' is defined but never used. Allowed unused args must match /^_/u.","line":162,"column":39,"nodeType":"Identifier","messageId":"unusedVar","endLine":162,"endColumn":41},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":162,"column":43,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":162,"endColumn":45,"suggestions":[{"messageId":"removeAsync","fix":{"range":[4952,4958],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":169,"column":40,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":169,"endColumn":57,"fix":{"range":[5236,5237],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":171,"column":48,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":171,"endColumn":50,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5305,5311],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of an `any` typed value.","line":172,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":172,"endColumn":13},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'db' is defined but never used. Allowed unused args must match /^_/u.","line":179,"column":36,"nodeType":"Identifier","messageId":"unusedVar","endLine":179,"endColumn":38},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'getUser' has no 'await' expression.","line":186,"column":7,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":186,"endColumn":22,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5669,5675],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":189,"column":13,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":189,"endColumn":15},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":192,"column":40,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":192,"endColumn":41},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":193,"column":13,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":193,"endColumn":18},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'findUser' has no 'await' expression.","line":207,"column":7,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":207,"endColumn":23,"suggestions":[{"messageId":"removeAsync","fix":{"range":[6156,6162],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":207,"column":44,"nodeType":"TSAsExpression","messageId":"unsafeReturn","endLine":207,"endColumn":80},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'getSession' has no 'await' expression.","line":209,"column":9,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":209,"endColumn":27,"suggestions":[{"messageId":"removeAsync","fix":{"range":[6263,6269],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":211,"column":18,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":211,"endColumn":19},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'login' has no 'await' expression.","line":216,"column":9,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":216,"endColumn":22,"suggestions":[{"messageId":"removeAsync","fix":{"range":[6504,6510],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":220,"column":15,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":220,"endColumn":17},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always falsy.","line":224,"column":15,"nodeType":"UnaryExpression","messageId":"alwaysFalsy","endLine":224,"endColumn":17},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'sid' is defined but never used. Allowed unused args must match /^_/u.","line":231,"column":24,"nodeType":"Identifier","messageId":"unusedVar","endLine":231,"endColumn":27},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'params' is defined but never used. Allowed unused args must match /^_/u.","line":232,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":232,"endColumn":40},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'onProviderLoginStart' has no 'await' expression.","line":244,"column":11,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":244,"endColumn":39,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7606,7612],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'arg1' is defined but never used. Allowed unused args must match /^_/u.","line":257,"column":17,"nodeType":"Identifier","messageId":"unusedVar","endLine":257,"endColumn":21},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'dwadwa' is defined but never used. Allowed unused args must match /^_/u.","line":259,"column":17,"nodeType":"Identifier","messageId":"unusedVar","endLine":259,"endColumn":23},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'run' has no 'await' expression.","line":274,"column":13,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":274,"endColumn":24,"suggestions":[{"messageId":"removeAsync","fix":{"range":[8409,8415],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'arg1' is defined but never used. Allowed unused args must match /^_/u.","line":293,"column":21,"nodeType":"Identifier","messageId":"unusedVar","endLine":293,"endColumn":25},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'publishRawSQL' has no 'await' expression.","line":322,"column":5,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":322,"endColumn":26,"suggestions":[{"messageId":"removeAsync","fix":{"range":[9826,9832],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'params' is defined but never used. Allowed unused args must match /^_/u.","line":322,"column":27,"nodeType":"Identifier","messageId":"unusedVar","endLine":322,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":327,"column":10,"nodeType":"ChainExpression","messageId":"neverNullish","endLine":328,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":328,"column":11,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":328,"endColumn":13,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[10099,10101],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":332,"column":24,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":332,"endColumn":26,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[10203,10205],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":347,"column":30,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":347,"endColumn":32,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[10679,10681],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `DBHandlerServer`.","line":423,"column":35,"nodeType":"TSAsExpression","messageId":"unsafeArgument","endLine":423,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `DBOFullyTyped | Record<string, Partial<TableHandler & TableHandlerClientMethods<AnyObject, void>>>`.","line":425,"column":35,"nodeType":"TSAsExpression","messageId":"unsafeArgument","endLine":425,"endColumn":45},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":425,"column":35,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":425,"endColumn":45,"fix":{"range":[12830,12837],"text":""}}],"suppressedMessages":[],"errorCount":28,"fatalErrorCount":0,"warningCount":30,"fixableErrorCount":3,"fixableWarningCount":0,"source":"import express from \"express\";\nimport path from \"path\";\nimport { CHANNELS } from \"prostgles-types\";\nimport prostgles, { defineFunction, getLocalStorageClient } from \"prostgles-server\";\nimport { withUserRLS } from \"prostgles-server/dist/DboBuilder/DboBuilder\";\nimport { testPublishTypes } from \"./publishTypeCheck\";\nimport { testPublish } from \"./testPublish\";\nimport { testTableConfig, testTableHooks } from \"./testTableConfig\";\nimport { VALIDATE_SCHEMA_FUNCTION_SQL_TEST } from \"./VALIDATE_SCHEMA_FUNCTION_SQL_TEST\";\n\nconst app = express();\napp.use(express.json());\nconst http = require(\"http\").createServer(app);\n\ntestPublishTypes();\n\nconst isClientTest = process.env.TEST_TYPE === \"client\";\nconst io = !isClientTest ? undefined : require(\"socket.io\")(http, { path: \"/teztz/s\" });\nconst ioWatchSchema =\n !isClientTest ? undefined : require(\"socket.io\")(http, { path: \"/teztz/sWatchSchema\" });\n\nhttp.listen(3001);\n\nimport { isomorphicQueries } from \"../isomorphicQueries.spec\";\nimport { serverOnlyQueries } from \"../serverOnlyQueries.spec\";\n\nimport { DBGeneratedSchema } from \"../DBGeneratedSchema\";\n\nimport { spawn } from \"child_process\";\nimport type { DBOFullyTyped } from \"prostgles-server\";\nexport type { DBHandlerServer } from \"prostgles-server\";\n\nlet logs: unknown[] = [];\nconst replicationErrors: unknown[] = [];\n\nexport const log = (msg: string, extra?: any, trace?: boolean) => {\n const msgs = msg.includes(\"show-logs\") ? logs : [\"(server): \" + msg, extra].filter((v) => v);\n if (trace) {\n console.trace(...msgs);\n } else {\n console.log(...msgs);\n }\n};\nconst stopTest = (err?: unknown) => {\n err ??= replicationErrors.length ? replicationErrors : undefined;\n log(\"Stopping server ...\");\n if (err) {\n console.trace(err);\n }\n process.exit(err ? 1 : 0);\n};\n\nconst sessions: { id: string; user_id: string }[] = [\n { id: \"main\", user_id: \"1\" },\n { id: \"rest_api\", user_id: \"1\" },\n];\ntype USER = {\n id: string;\n username: string;\n password: string;\n type: string;\n};\nconst users: USER[] = [\n { id: \"1\", username: \"public\", password: \"\", type: \"public\" },\n { id: \"2\", username: \"john\", password: \"secret\", type: \"default\" },\n];\n\nprocess.on(\"unhandledRejection\", (reason, p) => {\n console.trace(\"Unhandled Rejection at:\", p, \"reason:\", reason);\n process.exit(1);\n});\n\n/**\n * To create a superuser in linux:\n * sudo su - postgres\n * createuser api -s -P\n * createdb prostgles_server_tests -O api\n */\nconst dbConnection = {\n host: process.env.POSTGRES_HOST || \"localhost\",\n port: +(process.env.POSTGRES_PORT || 5432),\n database: process.env.POSTGRES_DB || \"prostgles_server_tests\",\n user: process.env.POSTGRES_USER || \"api\",\n password: process.env.POSTGRES_PASSWORD || \"api\",\n};\n\nfunction dd() {\n const dbo: DBOFullyTyped<{\n tbl: { is_view: true; columns: { col1: { type: number } } };\n }> = 1 as any;\n if (!dbo) return;\n dbo.tbl.find;\n}\n\n(async () => {\n if (isClientTest && process.env.TEST_NAME === \"useProstgles\") {\n await prostgles<DBGeneratedSchema>({\n dbConnection,\n io: ioWatchSchema,\n transactions: true,\n schemaFilter: { public: 1, prostgles_test: 1 },\n onReady: async ({ dbo, db }) => {},\n publish: \"*\",\n watchSchema: true,\n });\n }\n\n prostgles<DBGeneratedSchema>({\n dbConnection,\n sqlFilePath: path.join(__dirname + \"/../../init.sql\"),\n io,\n tsGeneratedTypesDir: path.join(__dirname + \"/../../../\"),\n tsGeneratedTypesFunctionsPath: path.join(__dirname + \"/../../index.ts\"),\n transactions: true,\n schemaFilter: { public: 1, prostgles_test: 1 },\n onLog: async (ev) => {\n logs.push(ev);\n logs = logs.slice(-10);\n if (ev.type === \"sync\" && ev.command === \"replicationError\") {\n replicationErrors.push(ev);\n }\n if (ev.type === \"debug\" || ev.type === \"connect\" || ev.type === \"disconnect\") {\n // log(\"onLog\", ev);\n }\n },\n tableConfig: testTableConfig,\n tableConfigMigrations: {\n version: 1,\n onMigrate: () => {\n throw new Error(\"onMigrate must not run for a fresh schema\");\n },\n },\n tableHooks: testTableHooks,\n testRulesOnConnect: true,\n fileTable: {\n tableName: \"files\",\n versioning: {},\n storageClient: getLocalStorageClient({ localFolderPath: path.join(__dirname + \"/media\") }),\n expressApp: app,\n referencedTables: {\n users_public_info: {\n type: \"column\",\n referenceColumns: {\n avatar: {\n acceptedContent: \"*\",\n },\n },\n },\n },\n },\n // DEBUG_MODE: true,\n restApi: {\n expressApp: app,\n path: \"/api\",\n },\n\n onSocketConnect: ({ socket, db }) => {\n console.log(\"onSocketConnect\", socket.id);\n if (isClientTest) {\n log(\"Client connected -> console does not work. use log function. socket.id:\", socket.id);\n socket.emit(\"start-test\", { server_id: Math.random() });\n socket.on(\"log\", async (data, cb) => {\n console.log(\"Client log \", data);\n if (typeof data === \"string\" && data.includes(\"show-logs\")) {\n log(data);\n }\n });\n socket.on(\"reattach-syncs\", () => {\n socket.emit(CHANNELS.SCHEMA, socket.prostgles!.values().next().value);\n });\n socket.on(\"stop-test\", async (err, cb) => {\n cb();\n console.log(\"Client test \" + (!err ? \"successful\" : \"failed\"));\n stopTest(err);\n });\n }\n },\n\n onSocketDisconnect: ({ socket, db }) => {\n if (isClientTest) {\n log(\"Client disconnected. socket.id:\", socket.id);\n }\n },\n auth: {\n sidKeyName: \"token\",\n getUser: async (sid) => {\n if (!sid) return;\n const s = sessions.find((s) => s.id === sid);\n if (!s) {\n return;\n }\n const user = users.find((u) => s && s.user_id === u.id);\n if (!user) {\n return;\n }\n return {\n sid: s.id,\n user,\n clientUser: {\n sid: s.id,\n uid: user.id,\n id: user.id,\n type: user.type,\n },\n };\n },\n findUser: async (userFilter, dbo) => dbo.users.findOne(userFilter) as any,\n cacheSession: {\n getSession: async (sid) => {\n const s = sessions.find((s) => s.id === sid);\n return s ? { sid: s.id, expires: Infinity, onExpiration: \"redirect\" } : undefined;\n },\n },\n loginSignupConfig: {\n app,\n login: async (loginData) => {\n if (loginData.type !== \"username\") throw \"Only username login is supported\";\n const { username, password } = loginData;\n const u = users.find((u) => u.username === username && u.password === password);\n if (!u) {\n return \"no-match\";\n }\n let s = sessions.find((s) => s.user_id === u.id);\n if (!s) {\n s = { id: \"SID\" + Date.now(), user_id: u.id };\n sessions.push(s);\n }\n log(\"Logged in!\");\n return { session: { sid: s.id, expires: Infinity, onExpiration: \"redirect\" } };\n },\n logout: async (sid) => {},\n onGetRequestOK(req, res, params) {\n log(req.originalUrl);\n res.sendFile(path.join(__dirname, \"../../index.html\"), { dotfiles: \"allow\" });\n },\n loginWithOAuth: {\n websiteUrl: \"http://localhost:3001\",\n OAuthProviders: {\n github: {\n clientID: \"GITHUB_CLIENT_ID\",\n clientSecret: \"GITHUB\",\n },\n },\n onProviderLoginStart: async () => ({ success: true }),\n onProviderLoginFail: console.error,\n },\n },\n },\n functions: {\n allUsers: {\n userFilter: {},\n functions: {\n myfunc: defineFunction({\n input: { arg1: { type: \"number\" } },\n run: (\n {\n arg1,\n //@ts-expect-error\n dwadwa,\n },\n params,\n ) => {\n params.user;\n return 222;\n },\n }),\n myfuncVoid: defineFunction({\n run: async () => {\n await new Promise((res) => setTimeout(res, 100));\n },\n }),\n myfuncWithBadReturn: defineFunction({\n input: { arg1: { type: \"number\" } },\n run: async () => \"222\",\n }),\n myfuncWithComplexReturn: defineFunction({\n input: { arg1: { type: \"number\" } },\n run: () => {\n if (Math.random() > 0.5) {\n return { a: 1, b: \"str\", c: { d: true } };\n } else {\n return [1, 2, 3];\n }\n },\n }),\n },\n },\n admins: {\n userFilter: { email: \"admin@example.com\" },\n functions: {\n myAdminFunc: defineFunction({\n input: { arg1: { type: \"number\" } },\n run: ({ arg1 }, { user }) => {\n user.email === \"dwadaw\";\n //@ts-expect-error\n user.invalid_field === \"dwadaw\";\n return 222;\n },\n }),\n },\n },\n defaultUsers: {\n userFilter: { email: \"john@example.com\" },\n functions: {\n myfuncForDefault: defineFunction({\n run: async () => {\n await new Promise((res) => setTimeout(res, 100));\n },\n }),\n myfuncForDefault2: defineFunction({\n input: { name: \"string\" },\n run: async () => {\n await new Promise((res) => setTimeout(res, 100));\n if (Math.PI) return { a: 1 };\n return { b: \"1\" };\n },\n }),\n },\n },\n },\n publish: testPublish,\n publishRawSQL: async (params) => {\n return true; // Boolean(user && user.type === \"admin\")\n },\n modifyClientSchema: (table, tableConfig, userData) => {\n const passes =\n ((table as typeof table & { clientSchemaTest?: { passes: number } }).clientSchemaTest\n ?.passes ?? 0) + 1;\n return {\n ...table,\n clientSchemaTest: {\n sid: userData?.sid,\n tableIndex: 0,\n ...(table.name === \"planes\" && {\n passes,\n primaryKeys: table.columns\n .filter((column) => column.is_pkey)\n .map((column) => column.name),\n }),\n },\n columns:\n table.name === \"tr2\" ?\n table.columns\n : table.columns.map((column, columnIndex) => ({\n ...column,\n clientSchemaTest: {\n sid: userData?.sid,\n columnIndex,\n ...(table.name === \"planes\" && { passes }),\n },\n })),\n };\n },\n joins: [\n {\n tables: [\"items\", \"items2\"],\n on: [{ name: \"name\" }],\n type: \"many-many\",\n override: true,\n },\n {\n tables: [\"items2\", \"items3\"],\n on: [{ name: \"name\" }],\n type: \"many-many\",\n },\n {\n tables: [\"items4a\", \"items\"],\n on: [{ items_id: \"id\" }],\n type: \"many-many\",\n },\n {\n tables: [\"items4a\", \"items2\"],\n on: [{ items2_id: \"id\" }],\n type: \"many-many\",\n },\n {\n tables: [\"items_multi\", \"items\"],\n on: [{ items0_id: \"id\" }, { items1_id: \"id\" }, { items2_id: \"id\" }, { items3_id: \"id\" }],\n type: \"many-many\",\n },\n ],\n onReady: async ({ dbo, sql, db }) => {\n log(\"prostgles onReady\");\n await dbo.users.upsert(\n { id: 1 },\n {\n email: \"public@example.com\",\n status: \"active\",\n type: \"public\",\n preferences: { others: [] },\n },\n );\n await dbo.users.upsert(\n { id: 2 },\n {\n email: \"john@example.com\",\n status: \"active\",\n type: \"default\",\n preferences: { others: [] },\n },\n );\n await db.any(VALIDATE_SCHEMA_FUNCTION_SQL_TEST);\n try {\n if (isClientTest) {\n const execPath = path.resolve(`${__dirname}/../../../client`);\n /** For some reason the below doesn't work anymore */\n // const proc = spawn(\"npm\", [\"run\", \"test\"], { cwd: execPath, stdio: \"inherit\" });\n\n spawn(\n \"node\",\n [\n // \"--inspect-brk\",\n \"dist/client/index.js\",\n ],\n {\n cwd: execPath,\n stdio: \"inherit\",\n },\n );\n\n log(\"Waiting for client...\");\n } else if (process.env.TEST_TYPE === \"server\") {\n await serverOnlyQueries(dbo as any, db, withUserRLS);\n log(\"Server-only query tests successful\");\n await isomorphicQueries(dbo as any, sql, log);\n log(\"Server isomorphic tests successful\");\n\n stopTest();\n }\n } catch (err) {\n console.trace(err);\n if (process.env.TEST_TYPE) {\n stopTest(err ?? \"Error\");\n }\n }\n },\n });\n})();\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/joins.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":32,"column":25,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":35,"endColumn":63,"fix":{"range":[1728,1768],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":41,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":41,"endColumn":53,"fix":{"range":[1949,1950],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":42,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":42,"endColumn":46,"fix":{"range":[1996,1997],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":47,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":47,"endColumn":52,"fix":{"range":[2247,2248],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":64,"column":40,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":64,"endColumn":56,"fix":{"range":[2801,2802],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":66,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":66,"endColumn":52,"fix":{"range":[2890,2891],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":72,"column":19,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":72,"endColumn":35,"fix":{"range":[3118,3119],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":113,"column":21,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":116,"endColumn":59,"fix":{"range":[4636,4676],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":134,"column":23,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":134,"endColumn":43,"fix":{"range":[5110,5111],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":135,"column":26,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":135,"endColumn":39,"fix":{"range":[5150,5151],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":146,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":146,"endColumn":28,"fix":{"range":[5476,5477],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":153,"column":30,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":153,"endColumn":58,"fix":{"range":[5691,5692],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":155,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":155,"endColumn":35,"fix":{"range":[5751,5752],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":167,"column":9,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":167,"endColumn":29,"fix":{"range":[6106,6107],"text":""}}],"suppressedMessages":[],"errorCount":15,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":14,"fixableWarningCount":0,"source":"import { strict as assert } from \"node:assert\";\nimport { test } from \"node:test\";\nimport prostgles, { type ProstglesInitOptions } from \"prostgles-server\";\nimport type { Join } from \"prostgles-server/dist/ProstglesTypes\";\nimport type { DB } from \"prostgles-server/dist/Prostgles\";\nimport { getConnectionDetails } from \"prostgles-server/dist/DboBuilder/runSql/getAdminClient\";\n\nexport const testJoins = async (db: DB) => {\n await test(\"custom joins add conditions unless override is requested\", async () => {\n await db.none(`\n CREATE SCHEMA join_merge_test;\n CREATE TABLE join_merge_test.members (id int PRIMARY KEY, project_id int, discipline_id text);\n CREATE TABLE join_merge_test.conditions (\n id int PRIMARY KEY, assigned_member_id int REFERENCES join_merge_test.members(id),\n project_id int, discipline_id text\n );\n INSERT INTO join_merge_test.members VALUES (1, 1, 'drainage');\n INSERT INTO join_merge_test.conditions VALUES\n (1, 1, 2, 'ecology'), (2, NULL, 1, 'drainage'), (3, NULL, 1, 'ecology');\n `);\n try {\n for (const override of [false, true]) {\n // Reverse the inferred relationship's direction and duplicate the custom condition.\n const on = { project_id: \"project_id\", discipline_id: \"discipline_id\" };\n const join: Join = {\n tables: [\"members\", \"conditions\"],\n on: [on, { discipline_id: \"discipline_id\", project_id: \"project_id\" }],\n type: \"many-many\",\n ...(override && { override }),\n };\n const instance = await prostgles({\n dbConnection: {\n ...getConnectionDetails(db),\n options: \"-c search_path=join_merge_test,public\",\n } as unknown as ProstglesInitOptions[\"dbConnection\"],\n schemaFilter: { join_merge_test: 1 },\n joins: [join],\n onReady: () => {},\n });\n try {\n const conditions = instance.db.conditions!;\n const rows = await conditions.find!(\n { $existsJoined: { members: { id: 1 } } },\n { select: [\"id\"], orderBy: \"id\" },\n );\n assert.deepEqual(rows, override ? [{ id: 2 }] : [{ id: 1 }, { id: 2 }]);\n const scopedRows = await conditions.find!(\n {\n $existsJoined: {\n path: [{ table: \"members\", on: [on] }],\n filter: { id: 1 },\n },\n },\n { select: [\"id\"] },\n );\n assert.deepEqual(scopedRows, [{ id: 2 }]);\n const assignedFilter = {\n $existsJoined: {\n path: [{ table: \"members\", on: [{ assigned_member_id: \"id\" }] }],\n filter: { id: 1 },\n },\n };\n if (override) {\n await assert.rejects(() => conditions.find!(assignedFilter));\n } else {\n assert.deepEqual(await conditions.find!(assignedFilter, { select: [\"id\"] }), [\n { id: 1 },\n ]);\n }\n // A duplicate must not make an otherwise unambiguous join fail.\n if (override) {\n await conditions.find!({}, { select: { id: 1, members: \"*\" } });\n }\n } finally {\n await instance.destroy();\n }\n }\n } finally {\n await db.none(\"DROP SCHEMA join_merge_test CASCADE\");\n }\n });\n\n await test(\"custom self joins use configured paths and override inferred joins\", async () => {\n await db.none(`\n CREATE SCHEMA custom_self_join_test;\n CREATE TABLE custom_self_join_test.members (\n id int PRIMARY KEY,\n project_id int NOT NULL,\n discipline_id text NOT NULL,\n user_id int NOT NULL,\n role text NOT NULL\n );\n INSERT INTO custom_self_join_test.members VALUES\n (1, 1, 'drainage', 10, 'manager'),\n (2, 1, 'drainage', 20, 'viewer'),\n (3, 1, 'ecology', 20, 'viewer');\n\n CREATE TABLE custom_self_join_test.managed_members (\n id int PRIMARY KEY,\n manager_id int REFERENCES custom_self_join_test.managed_members(id),\n project_id int NOT NULL,\n user_id int NOT NULL,\n role text NOT NULL\n );\n INSERT INTO custom_self_join_test.managed_members VALUES\n (1, NULL, 3, 20, 'viewer'),\n (2, 1, 3, 20, 'viewer'),\n (3, NULL, 1, 10, 'manager');\n `);\n const on = { project_id: \"project_id\", discipline_id: \"discipline_id\" };\n const overrideOn = { project_id: \"id\" };\n const instance = await prostgles({\n dbConnection: {\n ...getConnectionDetails(db),\n options: \"-c search_path=custom_self_join_test,public\",\n } as unknown as ProstglesInitOptions[\"dbConnection\"],\n schemaFilter: { custom_self_join_test: 1 },\n joins: [\n {\n tables: [\"members\", \"members\"],\n on: [on],\n type: \"many-many\",\n },\n {\n tables: [\"managed_members\", \"managed_members\"],\n on: [overrideOn],\n type: \"many-many\",\n override: true,\n },\n ],\n onReady: () => {},\n });\n try {\n const members = instance.db.members!;\n const rows = await members.find!(\n {\n $existsJoined: {\n path: [{ table: \"members\", on: [on] }],\n filter: { user_id: 10, role: \"manager\" },\n },\n },\n { select: [\"id\"], orderBy: \"id\" },\n );\n assert.deepEqual(rows, [{ id: 1 }, { id: 2 }]);\n assert.deepEqual(\n await members.find!(\n { $existsJoined: { members: { user_id: 10, role: \"manager\" } } },\n { select: [\"id\"], orderBy: \"id\" },\n ),\n rows,\n );\n\n const managedMembers = instance.db.managed_members!;\n assert.deepEqual(\n await managedMembers.find!(\n {\n $existsJoined: {\n path: [{ table: \"managed_members\", on: [overrideOn] }],\n filter: { user_id: 10, role: \"manager\" },\n },\n },\n { select: [\"id\"], orderBy: \"id\" },\n ),\n [{ id: 1 }, { id: 2 }],\n );\n await assert.rejects(() =>\n managedMembers.find!({\n $existsJoined: {\n path: [{ table: \"managed_members\", on: [{ manager_id: \"id\" }] }],\n filter: {},\n },\n }),\n );\n } finally {\n await instance.destroy();\n await db.none(\"DROP SCHEMA custom_self_join_test CASCADE\");\n }\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/publishTypeCheck.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":1,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":1,"endColumn":77,"fix":{"range":[6,6],"text":" type"}},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":2,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":2,"endColumn":58,"fix":{"range":[83,83],"text":" type"}},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":5,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":5,"endColumn":91,"fix":{"range":[198,198],"text":" type"}},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'syncPublish' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":23,"column":9,"nodeType":"Identifier","messageId":"unusedVar","endLine":23,"endColumn":20},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'p2' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":37,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":37,"endColumn":13},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'p123' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":54,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":54,"endColumn":15},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'p1234' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":56,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":56,"endColumn":16},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'p12' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":58,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":58,"endColumn":14},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'validate' has no 'await' expression.","line":111,"column":11,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":111,"endColumn":27,"suggestions":[{"messageId":"removeAsync","fix":{"range":[2784,2790],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'res2' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":138,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":138,"endColumn":15},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'res3' is assigned a value but never used. Allowed unused vars must match /^_/u.","line":139,"column":11,"nodeType":"Identifier","messageId":"unusedVar","endLine":139,"endColumn":15}],"suppressedMessages":[],"errorCount":5,"fatalErrorCount":0,"warningCount":7,"fixableErrorCount":3,"fixableWarningCount":0,"source":"import { ProstglesInitOptions } from \"prostgles-server/dist/ProstglesTypes\";\nimport { DBGeneratedSchema } from \"../DBGeneratedSchema\";\nimport type { PublishProfile } from \"prostgles-server\";\n\nimport { PublishFullyTyped } from \"prostgles-server/dist/DBSchemaBuilder/DBSchemaBuilder\";\nexport const testPublishTypes = () => {\n const profiles: PublishProfile<DBGeneratedSchema>[] = [\n {\n userTypes: [\"member\"],\n publish: {\n items: {\n select: {\n fields: {\n id: 1,\n // @ts-expect-error profile fields must belong to the table\n missing_column: 1,\n },\n },\n },\n },\n },\n ];\n const syncPublish: ProstglesInitOptions<DBGeneratedSchema>[\"publish\"] = profiles;\n () => {\n const p1: PublishFullyTyped<DBGeneratedSchema> = {\n items: {\n delete: \"*\",\n select: {\n fields: { h: 1, id: 1 },\n forcedFilter: {\n $and: [{ h: { $overlaps: [\"23\", \"32\"] } }, { $existsJoined: { items: { h: [] } } }],\n },\n },\n },\n items3: \"*\",\n };\n const p2: ProstglesInitOptions<DBGeneratedSchema>[\"publish\"] = \"*\";\n\n const p11: PublishFullyTyped = {\n items: {\n delete: \"*\",\n select: {\n fields: { h: 1, id: 1 },\n forcedFilter: {\n $and: [\n { h: { $overlaps: [\"23\", \"32\"] } },\n { $existsJoined: { items: { \"h.$eq\": [] } } },\n ],\n },\n },\n },\n items3: \"*\",\n };\n const p123: PublishFullyTyped<DBGeneratedSchema> = p11;\n //@ts-ignore\n const p1234: PublishFullyTyped = p1;\n\n const p12: ProstglesInitOptions[\"publish\"] = \"*\";\n\n const res: PublishFullyTyped = {\n shapes: \"*\",\n items: \"*\",\n items2: \"*\",\n items3: \"*\",\n v_items: \"*\",\n various: \"*\",\n tr1: \"*\",\n tr2: \"*\",\n tr3: \"*\",\n planes: {\n select: \"*\",\n update: \"*\",\n insert: \"*\",\n delete: \"*\",\n // sync: {\n // id_fields: [\"id\"],\n // synced_field: \"last_updated\",\n // },\n },\n\n items4: {\n select:\n Math.random() ? \"*\" : (\n {\n fields: { name: 0 },\n forcedFilter: { name: \"abc\" },\n }\n ),\n insert: \"*\",\n update: \"*\",\n delete: \"*\",\n },\n\n items4_pub: \"*\",\n \"*\": {\n select: { fields: { \"*\": 0 } },\n insert: \"*\",\n update: \"*\",\n },\n [`\"*\"`]: {\n select: { fields: { [`\"*\"`]: 0 } },\n insert: \"*\",\n update: \"*\",\n },\n obj_table: \"*\",\n media: \"*\",\n insert_rules: {\n insert: {\n fields: \"*\",\n returningFields: { name: 1 },\n validate: async ({ row }) => {\n if (row.name === \"a\") row.name = \"b\";\n return row;\n },\n },\n },\n uuid_text: {\n insert: {\n fields: \"*\",\n forcedData: {\n id: \"c81089e1-c4c1-45d7-a73d-e2d613cb7c3e\",\n },\n },\n update: {\n fields: [],\n dynamicFields: [\n {\n fields: { id: 1 },\n filter: {\n id: \"c81089e1-c4c1-45d7-a73d-e2d613cb7c3e\",\n },\n },\n ],\n },\n },\n };\n\n const res2: PublishFullyTyped<DBGeneratedSchema> = res;\n const res3: PublishFullyTyped<DBGeneratedSchema> = {\n items: {\n select: {\n fields: {\n h: 1,\n },\n forcedFilter: {\n // \"h.$eq\": [\"2\"]\n $and: [{ h: [\"2\"] }],\n },\n },\n },\n };\n };\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/schemaTypes.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":107,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":112,"endColumn":8},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":150,"column":35,"nodeType":"Property","messageId":"anyAssignment","endLine":150,"endColumn":48},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":158,"column":11,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":158,"endColumn":13,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[5545,5547],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { test } from \"node:test\";\nimport { strict as assert } from \"node:assert\";\nimport { getDBGeneratedSchema } from \"prostgles-server/dist/DBSchemaBuilder/getDBGeneratedSchema\";\nimport type { TableConfig } from \"prostgles-server/dist/TableConfig/TableConfigTypes\";\nimport type { DBHandlerServer } from \"prostgles-server\";\nimport type { DB } from \"prostgles-server/dist/Prostgles\";\nimport type { TableRowFromColumnDefinitions } from \"prostgles-server/dist/TableConfig/TableRowFromColumnDefinitions\";\nimport { testTableConfig } from \"./testTableConfig\";\n\nexport const testSchemaTypes = async (db: DBHandlerServer, pgDb: DB) => {\n await test(\"column definition row types support SQL aliases, arrays and generated columns\", async () => {\n const columns = {\n int: \"INT NOT NULL\",\n int2: \"int2 not null\",\n int4: \" InT4\\tNoT\\nNuLl \",\n int8: \"INT8 NOT NULL\",\n smallint: \"SMALLINT NOT NULL\",\n integer: \"INTEGER NOT NULL\",\n bigint: \"BIGINT NOT NULL\",\n real: \"REAL NOT NULL\",\n float: \"FLOAT(24) NOT NULL\",\n float4: \"FLOAT4 NOT NULL\",\n float8: \"FLOAT8 NOT NULL\",\n double: \"DOUBLE PRECISION NOT NULL\",\n numeric: \"NUMERIC(8, 2) NOT NULL\",\n decimal: \"DECIMAL NOT NULL\",\n dec: \"DEC NOT NULL\",\n bool: \"bool not null\",\n boolean: \"BOOLEAN NOT NULL\",\n json: \"JSON NOT NULL\",\n jsonb: \"JSONB NOT NULL\",\n bytes: \"bytea not null\",\n ints: \"INT[] NOT NULL\",\n matrix: \"INTEGER[2][2] NOT NULL\",\n bools: \"BOOLEAN ARRAY NOT NULL\",\n decimals: \"NUMERIC(8, 2) ARRAY[2] NOT NULL\",\n words: \"VARCHAR(20)[] NOT NULL\",\n nullable: \"INT\",\n smallserial: \"smallserial\",\n serial2: \"SERIAL2\",\n serial: \"serial\",\n serial4: \"SERIAL4\",\n bigserial: \"BIGSERIAL\",\n serial8: \"SERIAL8\",\n identity: \"int generated always as identity primary key\",\n generated: \"int generated always as (int + 1) stored\",\n defaulted: \"int default 42\",\n quoted: \"text check (quoted <> 'DEFAULT SERIAL NOT NULL')\",\n } as const;\n type Row = TableRowFromColumnDefinitions<typeof columns>;\n const row: Row = {\n int: 1,\n int2: 2,\n int4: 4,\n int8: 8,\n smallint: 2,\n integer: 4,\n bigint: 8,\n real: 1.5,\n float: 1.5,\n float4: 1.5,\n float8: 1.5,\n double: 1.5,\n numeric: 1.25,\n decimal: 1.25,\n dec: 1.25,\n bool: true,\n boolean: false,\n json: { a: 1 },\n jsonb: { b: 2 },\n bytes: Buffer.from(\"hello\"),\n ints: [1, null, 3],\n matrix: [\n [1, 2],\n [3, 4],\n ],\n bools: [true, false],\n decimals: [1.25, null],\n words: [\"a\", \"b\"],\n nullable: null,\n quoted: \"ok\",\n };\n // @ts-expect-error INT columns must reject strings.\n const invalidInt: Row[\"int\"] = \"1\";\n // @ts-expect-error BOOL columns must reject strings.\n const invalidBool: Row[\"bool\"] = \"true\";\n // @ts-expect-error Array columns must reject scalars.\n const invalidArray: Row[\"ints\"] = 1;\n // @ts-expect-error Quoted keywords must not make a column optional.\n const missingQuoted: Pick<Row, \"quoted\"> = {};\n const serial8: Row[\"serial8\"] = \"1\";\n const customType: TableRowFromColumnDefinitions<{ value: \"integer_custom NOT NULL\" }> = {\n value: \"text\",\n };\n const interval: TableRowFromColumnDefinitions<{ value: \"INTERVAL NOT NULL\" }> = {\n value: \"1 day\",\n };\n void [invalidInt, invalidBool, invalidArray, missingQuoted, serial8, customType, interval];\n\n await pgDb.tx(async (tx) => {\n await tx.none(`CREATE TEMP TABLE column_definition_types (\n ${Object.entries(columns)\n .map(([name, definition]) => `\"${name}\" ${definition}`)\n .join(\",\\n\")}\n ) ON COMMIT DROP`);\n const keys = Object.keys(row);\n const result = await tx.one(\n `INSERT INTO column_definition_types (\n ${keys.map((key) => `\"${key}\"`).join(\", \")}\n ) VALUES (${keys.map((_, i) => `$${i + 1}`).join(\", \")}) RETURNING *`,\n Object.values(row),\n );\n assert.deepEqual(result, {\n ...row,\n int8: \"8\",\n bigint: \"8\",\n numeric: \"1.25\",\n decimal: \"1.25\",\n dec: \"1.25\",\n smallserial: 1,\n serial2: 1,\n serial: 1,\n serial4: 1,\n bigserial: \"1\",\n serial8: \"1\",\n identity: 1,\n generated: 2,\n defaulted: 42,\n });\n });\n });\n\n await test(\"lookup types propagate through database references while preserving overrides\", () => {\n const tablesOrViews = db.uuid_text.dboBuilder.getSchema();\n const lookupType = 'null | \"a\" | \"b\"';\n const cases = [\n [\"TEXT REFERENCES lookup_col1\", lookupType],\n [undefined, lookupType],\n [{}, lookupType],\n [{ sqlDefinition: \"TEXT REFERENCES lookup_col1\" }, lookupType],\n [{ references: { tableName: \"lookup_col1\" } }, lookupType],\n [{ enum: [\"a\"] }, 'null | \"a\"'],\n [{ jsonbSchema: { type: \"boolean\" } }, \"boolean\"],\n [{ jsonbSchemaType: { value: \"boolean\" } }, \"{ value: boolean; };\"],\n ] as const;\n for (const [colConf, expected] of cases) {\n const config: TableConfig = {\n lookup_col1: testTableConfig.lookup_col1,\n ...(colConf !== undefined && {\n uuid_text: { columns: { col3: colConf } },\n }),\n };\n const schema = getDBGeneratedSchema({ config, tablesOrViews });\n assert.equal(\n schema\n .split(\"\\n\")\n .find((line) => line.trim().startsWith(\"col3?:\"))\n ?.trim().replace(/\\s+/g, \" \"),\n `col3?: ${expected}`,\n JSON.stringify(colConf),\n );\n assert(schema.includes('col1?: null | \"a\" | \"b\"'));\n assert(schema.includes('id: \"a\" | \"b\"'));\n }\n const schema = getDBGeneratedSchema({ config: undefined, tablesOrViews });\n assert(schema.includes(\"col3?: null | string;\"));\n });\n\n await test(\"lookup types follow FK chains by column and terminate cycles\", async () => {\n const { tablesOrViews } = await db.uuid_text.dboBuilder.getTsDefinitions({\n ddlWithRollback: `\n CREATE TABLE lookup_chain_bridge (\n lookup_key TEXT PRIMARY KEY REFERENCES lookup_col1,\n unrelated TEXT UNIQUE,\n UNIQUE (unrelated, lookup_key)\n );\n CREATE TABLE lookup_chain_middle (\n renamed_key TEXT PRIMARY KEY REFERENCES lookup_chain_bridge(lookup_key)\n );\n CREATE TABLE lookup_chain_cycle_a (id TEXT PRIMARY KEY);\n CREATE TABLE lookup_chain_cycle_b (id TEXT PRIMARY KEY REFERENCES lookup_chain_cycle_a);\n ALTER TABLE lookup_chain_cycle_a ADD FOREIGN KEY (id) REFERENCES lookup_chain_cycle_b;\n ALTER TABLE lookup_chain_cycle_a ADD FOREIGN KEY (id) REFERENCES lookup_col1;\n CREATE TABLE lookup_chain_self (id TEXT PRIMARY KEY REFERENCES lookup_chain_self);\n CREATE TABLE lookup_chain_leaf (\n chain_required TEXT NOT NULL REFERENCES lookup_chain_middle(renamed_key),\n chain_nullable TEXT REFERENCES lookup_chain_middle(renamed_key),\n chain_unrelated TEXT REFERENCES lookup_chain_bridge(unrelated),\n compound_unrelated TEXT,\n compound_lookup TEXT,\n FOREIGN KEY (compound_unrelated, compound_lookup)\n REFERENCES lookup_chain_bridge(unrelated, lookup_key),\n cycle_lookup TEXT REFERENCES lookup_chain_cycle_a,\n cycle_plain TEXT REFERENCES lookup_chain_self\n );\n `,\n });\n const config: TableConfig = { lookup_col1: testTableConfig.lookup_col1 };\n const schema = getDBGeneratedSchema({ config, tablesOrViews });\n const lines = schema.split(\"\\n\").map((line) => line.trim());\n for (const definition of [\n 'chain_required: \"a\" | \"b\"',\n 'chain_nullable?: null | \"a\" | \"b\"',\n 'compound_lookup?: null | \"a\" | \"b\"',\n 'cycle_lookup?: null | \"a\" | \"b\"',\n \"chain_unrelated?: null | string;\",\n \"compound_unrelated?: null | string;\",\n \"cycle_plain?: null | string;\",\n ]) {\n assert(lines.includes(definition), definition);\n }\n\n config.lookup_chain_leaf = {\n columns: {\n chain_required: { enum: [\"a\"] },\n chain_nullable: {\n references: { tableName: \"lookup_chain_middle\", columnName: \"renamed_key\" },\n },\n },\n };\n const overriddenSchema = getDBGeneratedSchema({ config, tablesOrViews });\n const overriddenLines = overriddenSchema.split(\"\\n\").map((line) => line.trim());\n assert(overriddenLines.includes('chain_required: \"a\"'));\n assert(overriddenLines.includes('chain_nullable?: null | \"a\" | \"b\"'));\n });\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/socketLifecycle.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":33,"column":32,"nodeType":"CallExpression","messageId":"neverOptionalChain","endLine":33,"endColumn":34,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1417,1419],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'findUser' has no 'await' expression.","line":36,"column":11,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":36,"endColumn":27,"suggestions":[{"messageId":"removeAsync","fix":{"range":[1503,1509],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":60,"column":55,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":60,"endColumn":72,"fix":{"range":[2702,2703],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":79,"column":22,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":79,"endColumn":24,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3356,3362],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":92,"column":22,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":92,"endColumn":24,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3882,3888],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":119,"column":23,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":119,"endColumn":25,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[5310,5312],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .err on an `any` value.","line":137,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":137,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .err on an `any` value.","line":137,"column":64,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":137,"endColumn":67},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `ClientSchema | PromiseLike<ClientSchema>`.","line":138,"column":20,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":138,"endColumn":27},{"ruleId":"@typescript-eslint/prefer-promise-reject-errors","severity":1,"message":"Expected the Promise rejection reason to be an Error.","line":157,"column":34,"nodeType":"CallExpression","messageId":"rejectAnError","endLine":157,"endColumn":63}],"suppressedMessages":[],"errorCount":7,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":1,"fixableWarningCount":0,"source":"import { strict as assert } from \"node:assert\";\nimport { once } from \"node:events\";\nimport { createServer } from \"node:http\";\nimport { test } from \"node:test\";\nimport prostgles, { type ProstglesInitOptions } from \"prostgles-server\";\nimport type { DB } from \"prostgles-server/dist/Prostgles\";\nimport { getConnectionDetails } from \"prostgles-server/dist/DboBuilder/runSql/getAdminClient\";\nimport { CHANNELS, type ClientSchema } from \"prostgles-types\";\nimport { Server } from \"socket.io\";\nimport { io as createClient, type Socket } from \"socket.io-client\";\nimport express from \"express\";\n\nexport const testSocketLifecycle = async (db: DB) => {\n await test(\n \"destroy allows reusing Socket.IO on a running HTTP server\",\n { timeout: 15000 },\n async () => {\n const app = express();\n app.use(express.json());\n const http = createServer(app);\n const io = new Server(http, { path: \"/ws-api/restart\" });\n const clients: Socket[] = [];\n const user = { id: \"lifecycle-user\", type: \"test\" };\n let beforeGetUser: (() => Promise<void>) | undefined;\n const options = {\n dbConnection: getConnectionDetails(db) as unknown as ProstglesInitOptions[\"dbConnection\"],\n io,\n publish: \"*\" as const,\n schemaFilter: { socket_lifecycle_test: 1 as const },\n auth: {\n sidKeyName: \"token\",\n getUser: async () => {\n await beforeGetUser?.();\n return { user, clientUser: user };\n },\n findUser: async () => user,\n },\n onReady: () => {},\n publishRawSQL: () => true,\n restApi: { expressApp: app, path: \"/lifecycle\" },\n };\n let instance: Awaited<ReturnType<typeof prostgles>> | undefined;\n try {\n await db.none(\"DROP SCHEMA IF EXISTS socket_lifecycle_test CASCADE\");\n await db.none(\"CREATE SCHEMA socket_lifecycle_test\");\n http.listen(0, \"127.0.0.1\");\n await once(http, \"listening\");\n const address = http.address();\n assert(address && typeof address === \"object\");\n const url = `http://127.0.0.1:${address.port}`;\n instance = await prostgles({ ...options, functions: getFunctions(0) });\n for (let cycle = 0; cycle < 2; cycle++) {\n const client = connect(url);\n clients.push(client.socket);\n const schema = await client.schema;\n assert(schema.methods.some(({ name }) => name === `only${cycle}`));\n assert.equal(await callMethod(client.socket, \"version\"), cycle);\n assert.equal(await (await callHttpMethod(url)).json(), cycle);\n const oldInstance = instance;\n const serverSocket = io.sockets.sockets.get(client.socket.id!);\n assert(serverSocket);\n const oldHandlers = await instance.getClientDBHandlers(\n { socket: serverSocket },\n undefined,\n );\n const closed = new Promise<string>((resolve) =>\n client.socket.once(\"disconnect\", resolve),\n );\n let resumeAuth = () => {};\n const authPaused = new Promise<void>((resolve) => {\n beforeGetUser = () => {\n resolve();\n return new Promise<void>((resume) => {\n resumeAuth = resume;\n });\n };\n });\n const inFlight = assert.rejects(\n async () => oldHandlers.clientMethods.version.run(),\n /instance is destroyed/,\n );\n await authPaused;\n const destroying = instance.destroy();\n beforeGetUser = undefined;\n resumeAuth();\n await Promise.all([destroying, inFlight]);\n instance = undefined;\n assert.equal(await closed, \"transport close\");\n assert(http.listening);\n assert.equal((await callHttpMethod(url)).status, 404);\n await assert.rejects(\n async () => oldHandlers.clientMethods.version.run(),\n /instance is destroyed/,\n );\n await assert.rejects(() => oldHandlers.clientSql(\"SELECT 1\"), /instance is destroyed/);\n await assert.rejects(oldInstance.restart, /instance is destroyed/);\n await assert.rejects(\n () => oldInstance.update({ functions: getFunctions(99) }),\n /instance is destroyed/,\n );\n\n // A reconnect may arrive before the replacement Prostgles instance is ready.\n const pending = connect(url);\n clients.push(pending.socket);\n await Promise.race([once(io, \"connection\"), pending.schema]);\n assert.equal(io.listenerCount(\"connection\"), 0);\n instance = await prostgles({ ...options, functions: getFunctions(cycle + 1) });\n const newSchema = await pending.schema;\n assert(!newSchema.methods.some(({ name }) => name === `only${cycle}`));\n await assert.rejects(() => callMethod(pending.socket, `only${cycle}`));\n await oldInstance.destroy();\n assert.equal(await callMethod(pending.socket, \"version\"), cycle + 1);\n assert.equal(await (await callHttpMethod(url)).json(), cycle + 1);\n assert.equal(io.listenerCount(\"connection\"), 1);\n pending.socket.close();\n }\n } finally {\n clients.forEach((client) => client.close());\n await instance?.destroy();\n await io.close();\n await db.none(\"DROP SCHEMA socket_lifecycle_test CASCADE\");\n }\n },\n );\n};\n\nconst connect = (url: string) => {\n const socket = createClient(url, {\n path: \"/ws-api/restart\",\n transports: [\"websocket\"],\n reconnection: false,\n query: { token: \"lifecycle-session\" },\n });\n const schema = new Promise<ClientSchema>((resolve, reject) => {\n socket.once(\"connect_error\", reject);\n socket.once(CHANNELS.SCHEMA, (payload) => {\n if (payload.err) reject(new Error(JSON.stringify(payload.err)));\n else resolve(payload);\n });\n });\n return { socket, schema };\n};\n\nconst getFunctions = (version: number): ProstglesInitOptions[\"functions\"] => ({\n users: {\n userFilter: {},\n functions: {\n version: { run: () => version },\n [`only${version}`]: { run: () => version },\n },\n },\n});\n\nconst callMethod = (socket: Socket, name: string) =>\n new Promise<unknown>((resolve, reject) => {\n socket.timeout(2000).emit(CHANNELS.METHOD, { name }, (timeoutError, error, result) => {\n if (timeoutError || error) reject(timeoutError || error);\n else resolve(result);\n });\n });\n\nconst callHttpMethod = (url: string) =>\n fetch(`${url}/lifecycle/methods/version`, {\n method: \"POST\",\n headers: { authorization: \"Bearer lifecycle-session\" },\n });\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/testPublish.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":1,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":1,"endColumn":95,"fix":{"range":[6,6],"text":" type"}},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":2,"message":"All imports in the declaration are only used as types. Use `import type`.","line":2,"column":1,"nodeType":"ImportDeclaration","messageId":"typeOverValue","endLine":2,"endColumn":58,"fix":{"range":[101,101],"text":" type"}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function 'testPublish' has no 'await' expression.","line":5,"column":78,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":5,"endColumn":80,"suggestions":[{"messageId":"removeAsync","fix":{"range":[305,311],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":91,"column":9,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":91,"endColumn":13},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'validate' has no 'await' expression.","line":124,"column":9,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":124,"endColumn":25,"suggestions":[{"messageId":"removeAsync","fix":{"range":[2746,2752],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":134,"column":17,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":134,"endColumn":96},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":136,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":136,"endColumn":35},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":136,"column":57,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":136,"endColumn":59,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3326,3328],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":7,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":2,"fixableWarningCount":0,"source":"import { Publish, PublishTableRule } from \"prostgles-server/dist/PublishParser/PublishParser\";\nimport { DBGeneratedSchema } from \"../DBGeneratedSchema\";\nimport type { PublishFullyTyped } from \"prostgles-server/dist/DBSchemaBuilder/DBSchemaBuilder\";\n\nexport const testPublish: Publish<DBGeneratedSchema> = async ({ user, sid }) => {\n if (sid === \"noAuth\") {\n return {\n planes: {\n select: { fields: { last_updated: 0 } },\n },\n };\n }\n if (sid === \"rest_api\") {\n return {\n planes: \"*\",\n };\n }\n const users_public_info = {\n select: {\n fields: \"*\",\n forcedFilter: { sid },\n },\n insert: {\n fields: \"*\",\n forcedData: { sid },\n },\n delete: {\n filterFields: \"*\",\n forcedFilter: { sid },\n },\n update: {\n fields: \"*\",\n forcedFilter: { sid },\n },\n } satisfies PublishTableRule<\n DBGeneratedSchema[\"users_public_info\"][\"columns\"],\n DBGeneratedSchema\n >;\n\n if (sid === \"files\") {\n return {\n users_public_info,\n };\n }\n if (sid === \"files_versions_denied\") {\n return {\n users_public_info: {\n ...users_public_info,\n select: {\n ...users_public_info.select,\n forcedFilter: { sid: \"files\" },\n },\n },\n files_versions: {\n select: {\n fields: \"*\",\n forcedFilter: { version: -1 },\n },\n },\n };\n }\n const res: PublishFullyTyped<DBGeneratedSchema> = {\n shapes: \"*\",\n items: \"*\",\n items2: \"*\",\n items3: \"*\",\n items4a: \"*\",\n tjson: \"*\",\n items_multi: \"*\",\n v_items: \"*\",\n various: \"*\",\n tr1: \"*\",\n tr2: \"*\",\n tr3: \"*\",\n bytea_test: \"*\",\n slow_items: \"*\",\n very_slow_items: \"*\",\n planes: {\n select: sid === \"client_only\" ? { fields: { last_updated: false } } : \"*\",\n update: \"*\",\n insert: \"*\",\n delete: \"*\",\n // sync: {\n // id_fields: [\"id\"],\n // synced_field: \"last_updated\",\n // },\n },\n\n items4: {\n select:\n user && user.type !== \"public\" ? \"*\" : (\n {\n fields: { name: 0 },\n filterFields: \"*\",\n orderByFields: { added: 1 },\n forcedFilter: { name: \"abc\" },\n }\n ),\n insert: \"*\",\n update: \"*\",\n delete: \"*\",\n },\n\n items4_pub: \"*\",\n [`\"*\"`]: {\n select: { fields: { \"*\": 0 } },\n insert: \"*\",\n update: \"*\",\n },\n [`\"\"\"*\"\"\"`]: {\n select: { fields: { [`\"*\"`]: 0 } },\n insert: \"*\",\n update: \"*\",\n },\n obj_table: \"*\",\n files: \"*\",\n users_public_info,\n self_join: \"*\",\n insert_rules: {\n select: \"*\",\n insert: {\n fields: { added: 0 },\n returningFields: { name: 1 },\n validate: async ({ row }) => {\n if (row.name === \"a\") row.name = \"b\";\n row.added = new Date().toUTCString();\n return row;\n },\n checkFilter: {\n $and: [{ name: { \"<>\": \"fail-check\" } }],\n },\n postValidate: async ({ row, dbx: dboTx, tx }) => {\n /** Records must exist in this transaction */\n const exists = await tx.oneOrNone(\"SELECT * FROM insert_rules WHERE id = ${id}\", row);\n const existsd = await dboTx.insert_rules.findOne({ id: row.id });\n if (row.id !== exists.id || row.id !== existsd?.id) {\n console.error(\"postValidate failed\");\n // process.exit(1)\n }\n if (row.name === \"fail\") throw \"Failed\";\n return undefined;\n },\n },\n },\n uuid_text: {\n insert: {\n fields: \"*\",\n forcedData: {\n id: \"c81089e1-c4c1-45d7-a73d-e2d613cb7c3e\",\n },\n },\n update: {\n fields: [],\n dynamicFields: [\n {\n fields: { id: 1 },\n filter: {\n id: \"c81089e1-c4c1-45d7-a73d-e2d613cb7c3e\",\n },\n },\n ],\n },\n },\n \"prostgles_test.basic\": \"*\",\n \"prostgles_test.basic1\": \"*\",\n \"prostgles_test.mv_basic1\": \"*\",\n [`\"\"\"quoted0\"\"\"`]: \"*\",\n [`\"\"\"quoted1\"\"\"`]: \"*\",\n [`\"\"\"quoted2\"\"\"`]: \"*\",\n symbols: \"*\",\n trades: \"*\",\n };\n\n return res;\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/testTableConfig.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/restrict-plus-operands","severity":2,"message":"Invalid operand for a '+' operation. Operands must each be a number or string, allowing a string + any of: `any`, `boolean`, `null`, `RegExp`, `undefined`. Got `InsertDataWithNested<{ id?: number; parent_id?: number; recf?: number; }, DBGeneratedSchema, \"rec\">`.","line":17,"column":11,"nodeType":"TSNonNullExpression","messageId":"invalid","endLine":17,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":17,"column":11,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":17,"endColumn":26,"fix":{"range":[592,593],"text":""}},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'validate' has no 'await' expression.","line":30,"column":9,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":30,"endColumn":25,"suggestions":[{"messageId":"removeAsync","fix":{"range":[938,944],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'dbo' is defined but never used. Allowed unused args must match /^_/u.","line":248,"column":28,"nodeType":"Identifier","messageId":"unusedVar","endLine":248,"endColumn":31}],"suppressedMessages":[],"errorCount":4,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":1,"fixableWarningCount":0,"source":"import type { TableConfig, TableHooks } from \"prostgles-server\";\nimport type { DBGeneratedSchema } from \"../DBGeneratedSchema\";\n\nexport const testTableHooks: TableHooks<DBGeneratedSchema> = {\n rec: {\n beforeEach: [\n {\n commands: { insert: 1, update: 1 },\n validate: ({ data }) => {\n // Before hooks receive nested inputs, not resolved foreign-key values.\n const nested: typeof data = {\n parent_id: { id: \"1\" },\n rec: [{ recf: { id: 1 } }],\n };\n\n // @ts-expect-error Can be nested insert\n data.parent_id! + 1;\n\n // @ts-expect-error Nested rows retain their column types.\n const invalid: typeof data = { rec: [{ missing_column: true }] };\n void nested;\n void invalid;\n return { row: data };\n },\n },\n ],\n afterEach: [\n {\n commands: { insert: 1, update: 1 },\n validate: async ({ command, data, row }) => {\n row.id satisfies number;\n if (command === \"insert\") {\n const inputs: typeof data = [{}, { id: \"1\" }];\n void inputs;\n // @ts-expect-error Bulk insert data must be narrowed before accessing columns.\n data.id;\n const input = Array.isArray(data) ? data[0] : data;\n // @ts-expect-error Input values can still require PostgreSQL casts.\n input.id satisfies number;\n } else if (command === \"update\") {\n const input: typeof data = { id: \"1\" };\n // @ts-expect-error Updates receive one input object, not an array.\n const inputs: typeof data = [{ id: 1 }];\n void input;\n void inputs;\n }\n },\n },\n ],\n },\n files: {\n afterEach: [\n {\n commands: {\n insert: 1,\n },\n validate: async ({ command, data, row, tx }) => {\n row satisfies DBGeneratedSchema[\"files\"][\"columns\"];\n if (command === \"insert\") {\n // @ts-expect-error Input data is partial and may contain multiple rows.\n data satisfies DBGeneratedSchema[\"files\"][\"columns\"];\n }\n // @ts-expect-error The hook row is typed from DBGeneratedSchema.\n row.missing_column;\n // throw new Error(JSON.stringify({ message: \"afterEach hook error\", data, row }));\n await tx.any(\"UPDATE files SET metadata = $1 WHERE id = $2\", [\n { description: \"Updated by afterEach hook\" },\n row.id,\n ]);\n },\n },\n ],\n },\n};\nexport const testTableConfig: TableConfig<{ en: 1; fr: 1 }> = {\n /** Allow extending the files table */\n files: {\n columns: {\n metadata: {\n nullable: true,\n jsonbSchemaType: {\n description: { type: \"string\" },\n },\n },\n },\n },\n planes: {\n syncConfig: {\n id_fields: [\"id\"],\n synced_field: \"last_updated\",\n },\n },\n tr2: {\n // dropIfExists: true,\n columns: {\n t1: {\n label: { fr: \"fr_t1\" },\n info: { hint: \"hint...\", min: \"a\", max: \"b\" },\n },\n t2: { label: { en: \"en_t2\" } },\n },\n triggers: {\n atLeastOneA: {\n actions: [\"delete\", \"update\"],\n forEach: \"statement\",\n type: \"after\",\n query: `\n DECLARE\n x_rec record;\n BEGIN\n\n IF NOT EXISTS(SELECT * FROM tr2 WHERE t1 = 'a' AND t2 = 'b') THEN\n RAISE EXCEPTION 'Must have at least one row with t1 = a AND t2 = b';\n END IF;\n\n RETURN NULL;\n END;\n `,\n },\n },\n },\n users_public_info: {\n // dropIfExists: true,\n columns: {\n id: \"SERIAL PRIMARY KEY\",\n name: \"TEXT\",\n avatar: `UUID REFERENCES files ON DELETE CASCADE`,\n // avatar: `UUID`,\n sid: `TEXT`,\n },\n },\n users: {\n dropIfExists: true,\n columns: {\n id: { sqlDefinition: `SERIAL PRIMARY KEY ` },\n email: { sqlDefinition: `TEXT NOT NULL` },\n status: { enum: [\"active\", \"disabled\", \"pending\"] },\n type: \"TEXT NOT NULL\",\n preferences: {\n jsonbSchemaType: {\n showIntro: { type: \"boolean\", optional: true },\n theme: { enum: [\"light\", \"dark\", \"auto\"], optional: true },\n others: { type: \"any[]\" },\n },\n },\n },\n },\n tjson: {\n dropIfExists: true,\n columns: {\n json: {\n jsonbSchemaType: {\n a: { type: \"boolean\" },\n arr: { enum: [\"1\", \"2\", \"3\"] },\n arr1: { enum: [1, 2, 3] },\n arr2: { type: \"integer[]\" },\n arrStr: { type: \"string[]\", optional: true, nullable: true },\n o: {\n optional: true,\n nullable: true,\n oneOfType: [{ o1: \"integer\" }, { o2: \"boolean\" }],\n },\n },\n },\n colOneOf: { enum: [\"a\", \"b\", \"c\"] },\n status: {\n nullable: true,\n jsonbSchema: {\n oneOfType: [\n { ok: { type: \"string\" } },\n { err: { type: \"string\" } },\n {\n loading: {\n type: {\n loaded: { type: \"number\" },\n total: { type: \"number\" },\n },\n },\n },\n ],\n },\n },\n jsonOneOf: {\n nullable: true,\n jsonbSchema: {\n oneOfType: [\n { command: { enum: [\"a\"] } },\n {\n command: { enum: [\"b\"] },\n option: { type: \"integer[]\" },\n },\n ],\n },\n },\n table_config: {\n nullable: true,\n jsonbSchemaType: {\n referencedTables: {\n optional: true,\n arrayOfType: { name: \"string\", minFiles: \"number\" },\n },\n recType: {\n nullable: true,\n optional: true,\n record: {\n keysEnum: [\"a\", \"b\"],\n values: { type: { bools: \"boolean[]\" } },\n },\n },\n },\n },\n },\n },\n lookup_col1: {\n dropIfExistsCascade: true,\n isLookupTable: {\n values: {\n a: { description: \"desc\" },\n b: {},\n },\n },\n },\n uuid_text: {\n columns: {\n id: \"UUID\",\n col1: {\n nullable: true,\n references: {\n tableName: \"lookup_col1\",\n },\n },\n col2: {\n nullable: true,\n references: {\n tableName: \"lookup_col1\",\n },\n },\n col3: {\n sqlDefinition: \"TEXT REFERENCES lookup_col1\",\n },\n },\n },\n api_table: {\n dropIfExists: true,\n columns: {\n id: \"SERIAL PRIMARY KEY\",\n },\n onMount: async ({ _db, dbo }) => {\n await _db.any(`ALTER TABLE api_table ADD COLUMN col1 TEXT`);\n },\n },\n rec_ref: {\n columns: {\n id: \"SERIAL PRIMARY KEY\",\n },\n },\n rec: {\n columns: {\n id: \"SERIAL PRIMARY KEY\",\n parent_id: \"INTEGER REFERENCES rec\",\n recf: \"INTEGER REFERENCES rec_ref\",\n },\n },\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/server/withUserRLS.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .user on an `any` value.","line":38,"column":47,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":38,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":43,"column":45,"nodeType":"Property","messageId":"anyAssignment","endLine":43,"endColumn":80},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":45,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":45,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":49,"column":11,"nodeType":"Property","messageId":"anyAssignment","endLine":49,"endColumn":14},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":105,"column":17,"nodeType":"TSAsExpression","messageId":"unnecessaryAssertion","endLine":105,"endColumn":51,"fix":{"range":[3897,3931],"text":"dbo.rec"}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":191,"column":17,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":191,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any[]` assigned to a parameter of type `number[]`.","line":195,"column":28,"nodeType":"CallExpression","messageId":"unsafeArgument","endLine":195,"endColumn":78},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":195,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":195,"endColumn":43,"fix":{"range":[7416,7417],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":195,"column":71,"nodeType":"MemberExpression","messageId":"unsafeReturn","endLine":195,"endColumn":77},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":195,"column":75,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":195,"endColumn":77},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":214,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":219,"endColumn":8},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parent_id on an `any` value.","line":220,"column":29,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":220,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parent_id on an `any` value.","line":239,"column":54,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":239,"endColumn":63},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":240,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":245,"endColumn":8},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parent_id on an `any` value.","line":246,"column":29,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":246,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parent_id on an `any` value.","line":269,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":269,"endColumn":64},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":353,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":353,"endColumn":29,"fix":{"range":[13000,13001],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":371,"column":21,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":371,"endColumn":29,"fix":{"range":[13480,13481],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":378,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":378,"endColumn":94},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":379,"column":26,"nodeType":"Property","messageId":"anyAssignment","endLine":379,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":379,"column":34,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":379,"endColumn":36},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since the receiver accepts the original type of the expression.","line":405,"column":25,"nodeType":"TSAsExpression","messageId":"contextuallyUnnecessary","endLine":405,"endColumn":100,"fix":{"range":[14687,14727],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":411,"column":23,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":411,"endColumn":61},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .user on an `any` value.","line":411,"column":57,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":411,"endColumn":61},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":413,"column":23,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":413,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .user on an `any` value.","line":413,"column":56,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":413,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":414,"column":27,"nodeType":"Property","messageId":"anyAssignment","endLine":414,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":414,"column":35,"nodeType":"Property","messageId":"anyAssignment","endLine":414,"endColumn":40},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'findUser' has no 'await' expression.","line":420,"column":13,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":420,"endColumn":29,"suggestions":[{"messageId":"removeAsync","fix":{"range":[15257,15263],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'getUser' has no 'await' expression.","line":421,"column":13,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":421,"endColumn":28,"suggestions":[{"messageId":"removeAsync","fix":{"range":[15303,15309],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary optional chain on a non-nullish value.","line":456,"column":23,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":456,"endColumn":25,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[16603,16605],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, value is always truthy.","line":459,"column":36,"nodeType":"Identifier","messageId":"alwaysTruthy","endLine":459,"endColumn":41}],"suppressedMessages":[],"errorCount":10,"fatalErrorCount":0,"warningCount":23,"fixableErrorCount":5,"fixableWarningCount":0,"source":"import { strict as assert } from \"node:assert\";\nimport { once } from \"node:events\";\nimport { createServer } from \"node:http\";\nimport { test } from \"node:test\";\nimport express from \"express\";\nimport pgPromise from \"pg-promise\";\nimport prostgles, { type ProstglesInitOptions } from \"prostgles-server\";\nimport { fetchSyncServerData } from \"prostgles-server/dist/PubSubManager/SyncReplication/fetchSyncServerData\";\nimport type { Subscription } from \"../../dist/PubSubManager/PubSubManager\";\nimport type { DB, DBHandlerServer } from \"../../dist/Prostgles\";\nimport type { LocalParams } from \"../../dist/DboBuilder/DboBuilderTypes\";\nimport { getConnectionDetails } from \"prostgles-server/dist/DboBuilder/runSql/getAdminClient\";\nimport type { TableHandler } from \"../../dist/DboBuilder/TableHandler/TableHandler\";\nimport type { withUserRLS as WithUserRLS } from \"../../dist/DboBuilder/dboBuilderUtils\";\nimport type { ParsedTableRule } from \"../../dist/PublishParser/PublishParser\";\n\nexport const testWithUserRLS = async (\n dbo: DBHandlerServer,\n db: DB,\n withUserRLS: typeof WithUserRLS,\n) => {\n const requestUser = {\n id: \"00000000-0000-0000-0000-000000000002\",\n type: \"admin\",\n tenant_id: 42,\n };\n const localParams: LocalParams = {\n isRemoteRequest: { user: requestUser, clientInfo: undefined },\n };\n const anonymousParams: LocalParams = {\n isRemoteRequest: { clientInfo: undefined },\n };\n const readUser = `SELECT prostgles.user()::jsonb AS \"user\"`;\n const assertUser = async (\n tx: Pick<pgPromise.ITask<{}>, \"one\">,\n user: object = requestUser,\n ) => {\n assert.deepEqual((await tx.one(readUser)).user, user);\n };\n\n await test(\"RLS context is isolated across implicit transactions, commit, rollback and pool reuse\", async () => {\n const pgp = pgPromise();\n const pool = pgp({ ...db.$pool.options, password: db.$pool.options.password, max: 1 });\n try {\n const { pid } = await pool.one(\"SELECT pg_backend_pid() AS pid\");\n const assertReset = async () => {\n assert.deepEqual(await pool.one(`${readUser}, pg_backend_pid() AS pid`), {\n user: {},\n pid,\n });\n };\n assert.deepEqual(\n await pool.one(\n withUserRLS(\n localParams,\n `SELECT prostgles.user_id()::text AS id,\n prostgles.user_type() AS type, prostgles.user('tenant_id') AS tenant`,\n ),\n ),\n { id: requestUser.id, type: requestUser.type, tenant: \"42\" },\n );\n await assertReset();\n\n for (const rollback of [false, true]) {\n const abort = new Error(\"rollback RLS test\");\n const transaction = pool.tx(async (tx) => {\n await tx.none(withUserRLS(localParams, \"\"));\n // Separate statements and local dbx-style calls must keep the transaction's user.\n await assertUser(tx);\n await tx.one(withUserRLS(undefined, \"SELECT 1\", true));\n await assertUser(tx);\n if (rollback) throw abort;\n });\n if (rollback) await assert.rejects(transaction, (error) => error === abort);\n else await transaction;\n await assertReset();\n }\n await assert.rejects(\n pool.tx(async (tx) => {\n await tx.none(withUserRLS(localParams, \"\"));\n await tx.one(\"SELECT 1 / 0\");\n }),\n { code: \"22012\" },\n );\n await assertReset();\n\n const secondUser = {\n ...requestUser,\n id: \"00000000-0000-0000-0000-000000000003\",\n };\n await pool.tx(async (tx) => {\n await tx.none(\n withUserRLS({ isRemoteRequest: { user: secondUser, clientInfo: undefined } }, \"\"),\n );\n await assertUser(tx, secondUser);\n await tx.none(withUserRLS(anonymousParams, \"\", true));\n await assertUser(tx, {});\n });\n await assertReset();\n } finally {\n await pool.$pool.end();\n }\n });\n\n const table = dbo.rec as unknown as TableHandler;\n await test(\"subscription and sync reads isolate users with a real RLS policy\", async () => {\n const manager = await table.dboBuilder.getPubSubManager();\n const rollback = new Error(\"rollback RLS fixture\");\n await assert.rejects(\n db.tx(async (tx) => {\n // The suite connects as a superuser; use an unprivileged role to exercise RLS.\n const role = pgPromise.as.name(`rls_test_${process.pid}_${Date.now()}`);\n await tx.none(`\n CREATE ROLE ${role};\n GRANT USAGE ON SCHEMA public, prostgles TO ${role};\n GRANT SELECT ON rec TO ${role};\n INSERT INTO rec (id) VALUES (-42001), (-42002);\n ALTER TABLE rec ENABLE ROW LEVEL SECURITY;\n CREATE POLICY rls_test ON rec USING (id = prostgles.user('tenant_id')::integer);\n SET LOCAL ROLE ${role};\n `);\n for (const tenantId of [-42001, -42002, undefined]) {\n const params: LocalParams = {\n isRemoteRequest: {\n clientInfo: undefined,\n user:\n tenantId === undefined ? undefined : { ...requestUser, tenant_id: tenantId },\n },\n tx: { t: tx, dbTX: table.dboBuilder.dbo },\n };\n const expected = tenantId === undefined ? [] : [{ id: tenantId }];\n const table_rules = { select: { fields: \"*\", filterFields: \"*\", orderByFields: \"*\" } } as const;\n const result = await manager.getSubData({\n table_info: { name: \"rec\" },\n filter: {},\n selectParams: { select: [\"id\"] },\n onData: () => {},\n localParams: params,\n table_rules,\n } as unknown as Subscription);\n assert.deepEqual(result, { data: expected });\n assert.deepEqual(\n await fetchSyncServerData(\n {\n tableHandler: table,\n localParams: params,\n from_synced: undefined,\n offset: undefined,\n },\n {\n filter: {},\n id_fields: [\"id\"],\n synced_field: \"id\",\n batch_size: 10,\n params: { select: [\"id\"] },\n table_rules,\n },\n ),\n expected,\n );\n }\n throw rollback;\n }),\n (error) => error === rollback,\n );\n });\n\n await test(\"ordinary beforeEach hooks transform inputs before validation\", async () => {\n await table.dboBuilder.getTX(async (dbx) => {\n const rec = dbx.rec as TableHandler;\n // Negative fixture IDs avoid collisions with generated positive IDs.\n const rows = {\n allowed: { id: -43001 },\n denied: { id: -43002 },\n transformed: { id: -43003 },\n stripped: { id: -43004 },\n statementOnly: { id: -43005 },\n missing: { id: -43999 },\n };\n await rec.insert([rows.allowed, rows.denied]);\n const calls: number[][] = [];\n const inputs: object[] = [];\n rec.hooks = {\n beforeEach: [\n {\n commands: { insert: 1, update: 1 },\n validate: async ({ data, command, filter, dbx }) => {\n inputs.push({ ...data });\n // Pre-validation hooks can consume fields that are not database columns.\n if (\"parent\" in data) {\n data.parent_id = data.parent;\n delete data.parent;\n }\n if (command === \"update\") {\n calls.push((await dbx.rec!.find(filter)).map((row) => row.id));\n } else {\n // Trusted hooks may add fields in place that clients cannot supply.\n data.parent_id = rows.allowed.id;\n }\n return { row: data };\n },\n },\n ],\n };\n const rules: ParsedTableRule = {\n insert: { fields: [\"id\"], returningFields: \"*\" },\n update: {\n fields: [\"parent_id\"],\n filterFields: \"*\",\n returningFields: \"*\",\n forcedFilter: rows.allowed,\n },\n };\n const inserted = await rec.insert(\n { ...rows.transformed, parent: rows.allowed.id },\n { returning: \"*\" },\n undefined,\n rules,\n );\n assert.equal(inserted.parent_id, rows.allowed.id);\n assert.deepEqual(inputs.at(-1), { ...rows.transformed, parent: rows.allowed.id });\n // Fields left by the hook still undergo the usual validation.\n await assert.rejects(() =>\n rec.insert({ ...rows.stripped, recf: null }, undefined, undefined, rules),\n );\n await assert.rejects(() => rec.update(rows.allowed, { recf: null }, undefined, rules));\n assert.equal(inputs.length, 3);\n calls.length = 0;\n assert.deepEqual(\n await rec.update(rows.denied, { parent: rows.allowed.id }, { returning: \"*\" }, rules),\n [],\n );\n assert.deepEqual(\n await rec.update(rows.missing, { parent: rows.allowed.id }, { returning: \"*\" }, rules),\n [],\n );\n await rec.update({}, { parent: rows.allowed.id }, undefined, rules);\n assert.deepEqual(calls, [[], [], [rows.allowed.id]]);\n assert.equal((await rec.findOne(rows.denied))!.parent_id, null);\n const stripped = await rec.insert(\n { ...rows.stripped, recf: null },\n { returning: \"*\", removeDisallowedFields: true },\n undefined,\n rules,\n );\n assert.equal(stripped.parent_id, rows.allowed.id);\n assert.deepEqual(inputs.at(-1), { ...rows.stripped, recf: null });\n const count = inputs.length;\n assert.equal(\n typeof (await rec.insert(\n { ...rows.statementOnly },\n { returnType: \"statement\" },\n undefined,\n rules,\n )),\n \"string\",\n );\n assert.equal(\n typeof (await rec.update(\n {},\n { parent: rows.allowed.id },\n { returnType: \"statement\" },\n rules,\n )),\n \"string\",\n );\n await rec.updateBatch([[{}, { parent: rows.denied.id }]], undefined, undefined, rules);\n assert.equal(inputs.length, count + 3);\n assert.equal((await rec.findOne(rows.allowed))!.parent_id, rows.denied.id);\n assert.equal(await rec.findOne(rows.statementOnly), undefined);\n await rec.delete({ id: { $in: Object.values(rows).map(({ id }) => id) } });\n });\n });\n\n await test(\"multi false is checked after beforeEach and rolls back the update\", async () => {\n let calls = 0;\n const rows = [{ id: -43001 }, { id: -43002 }];\n const filter = { id: { $in: rows.map(({ id }) => id) } };\n await assert.rejects(\n table.dboBuilder.getTX(async (dbx) => {\n const rec = dbx.rec as TableHandler;\n await rec.insert(rows);\n rec.hooks = {\n beforeEach: [\n {\n commands: { update: 1 },\n validate: () => {\n calls++;\n },\n },\n ],\n };\n await rec.update(filter, { parent_id: rows[0].id }, { multi: false });\n }),\n (error: unknown) => JSON.stringify(error).includes(\"More than 1 row modified\"),\n );\n assert.equal(calls, 1);\n assert.equal(await table.count(filter), 0);\n });\n\n await test(\"ordinary beforeEach hooks run before PostgreSQL UPDATE policy checks\", async () => {\n const abort = new Error(\"rollback hook RLS fixture\");\n await assert.rejects(\n table.dboBuilder.getTX(async (dbx, tx) => {\n const rec = dbx.rec as TableHandler;\n const row = { id: -43001 };\n await rec.insert(row);\n let calls = 0;\n rec.hooks = {\n beforeEach: [\n {\n commands: { update: 1 },\n validate: () => {\n calls++;\n },\n },\n ],\n };\n const role = pgPromise.as.name(`hook_rls_${process.pid}`);\n await tx.none(`\n CREATE ROLE ${role};\n GRANT USAGE ON SCHEMA public, prostgles TO ${role};\n -- Statement triggers still run when RLS prevents every row update.\n GRANT SELECT ON prostgles.v_triggers TO ${role};\n GRANT SELECT, UPDATE ON rec TO ${role};\n ALTER TABLE rec ENABLE ROW LEVEL SECURITY;\n CREATE POLICY hook_select ON rec FOR SELECT TO ${role} USING (true);\n CREATE POLICY hook_update ON rec FOR UPDATE TO ${role} USING (false);\n SET LOCAL ROLE ${role};\n `);\n assert.deepEqual(\n await rec.update(row, { parent_id: null }, { returning: \"*\" }),\n [],\n );\n assert.equal(calls, 1);\n throw abort;\n }),\n (error) => error === abort,\n );\n });\n\n await test(\"before and after hooks preserve RLS across dbx and raw tx calls\", async () => {\n await table.dboBuilder.getTX(async (dbx) => {\n const rec = dbx.rec as TableHandler;\n let beforeCalls = 0;\n let afterCalls = 0;\n rec.hooks = {\n beforeEach: [\n {\n commands: { insert: 1 },\n validate: async ({ tx, dbx }) => {\n await assertUser(tx);\n await dbx.rec!.find({});\n await assertUser(tx);\n beforeCalls++;\n },\n },\n {\n commands: { insert: 1 },\n validate: async ({ tx }) => {\n await assertUser(tx);\n beforeCalls++;\n },\n },\n ],\n afterEach: [\n {\n commands: { insert: 1 },\n validate: async ({ tx, dbx }) => {\n await assertUser(tx);\n await dbx.rec!.count({});\n await assertUser(tx);\n afterCalls++;\n },\n },\n ],\n };\n const row = await rec.insert({}, { returning: \"*\" }, undefined, undefined, localParams);\n await rec.delete({ id: row.id });\n assert.equal(beforeCalls, 2);\n assert.equal(afterCalls, 1);\n });\n });\n\n await test(\n \"onInsteadOfDelete receives the authenticated or anonymous request context\",\n { timeout: 15_000 },\n async () => {\n const schemaName = `delete_context_${process.pid}_${Date.now()}`;\n const tableName = `${schemaName}.rec`;\n const schema = pgPromise.as.name(schemaName);\n const app = express();\n const http = createServer(app);\n let instance: Awaited<ReturnType<typeof prostgles>> | undefined;\n app.use(express.json());\n\n try {\n await db.none(`CREATE SCHEMA ${schema}; CREATE TABLE ${schema}.rec (id INTEGER PRIMARY KEY)`);\n http.listen(0, \"127.0.0.1\");\n await once(http, \"listening\");\n const address = http.address();\n assert(address && typeof address === \"object\");\n\n instance = await prostgles({\n dbConnection: getConnectionDetails(db) as unknown as ProstglesInitOptions[\"dbConnection\"],\n schemaFilter: { [schemaName]: 1 },\n publish: \"*\",\n tableHooks: {\n [tableName]: {\n onInsteadOfDelete: async ({ tx, dbx }) => {\n const before = (await tx.one(readUser)).user;\n await (dbx[tableName] as TableHandler).find({});\n const after = (await tx.one(readUser)).user;\n return [{ before, after }];\n },\n },\n },\n auth: {\n sidKeyName: \"token\",\n findUser: async () => requestUser,\n getUser: async (sid) =>\n sid === \"authenticated\" ?\n {\n user: requestUser,\n clientUser: { id: requestUser.id, type: requestUser.type },\n sessionFields: \"*\",\n }\n : undefined,\n },\n restApi: { expressApp: app, path: \"/rls-context\" },\n onReady: () => {},\n });\n\n const url = `http://127.0.0.1:${address.port}/rls-context/db/${tableName}/delete`;\n const deleteRequest = async (sid?: string) => {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(sid && {\n Authorization: `Bearer ${Buffer.from(sid).toString(\"base64\")}`,\n }),\n },\n body: JSON.stringify([{ id: -1 }]),\n });\n const result = await response.json();\n assert.equal(response.status, 200, JSON.stringify(result));\n return result;\n };\n\n assert.deepEqual(await deleteRequest(\"authenticated\"), [\n { before: requestUser, after: requestUser },\n ]);\n assert.deepEqual(await deleteRequest(\"anonymous\"), [{ before: {}, after: {} }]);\n } finally {\n await instance?.destroy();\n if (http.listening) {\n await new Promise<void>((resolve, reject) =>\n http.close((error) => (error ? reject(error) : resolve())),\n );\n }\n await db.none(`DROP SCHEMA IF EXISTS ${schema} CASCADE`);\n }\n },\n );\n};\n","usedDeprecatedRules":[]},{"filePath":"/home/s/prostgles-server-js/tests/serverOnlyQueries.spec.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.","line":0,"column":1,"nodeType":null,"messageId":"noStrictNullCheck","endLine":0,"endColumn":1},{"ruleId":"prefer-const","severity":2,"message":"'results' is never reassigned. Use 'const' instead.","line":72,"column":11,"nodeType":"Identifier","messageId":"useConst","endLine":72,"endColumn":25,"fix":{"range":[2790,2814],"text":"const results: any[] = [];"}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":73,"column":20,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":73,"endColumn":37,"fix":{"range":[2850,2851],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":76,"column":20,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":76,"endColumn":39,"fix":{"range":[2945,2946],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":2,"message":"Unnecessary conditional, comparison is always true, since `5000 > 0` is true.","line":80,"column":36,"nodeType":"BinaryExpression","messageId":"comparisonBetweenLiteralTypes","endLine":80,"endColumn":47},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":84,"column":7,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":84,"endColumn":34,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[3251,3251],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[3251,3251],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":85,"column":7,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":85,"endColumn":34,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[3285,3285],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[3285,3285],"text":"await "},"desc":"Add await operator."}]},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":89,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":89,"endColumn":28,"fix":{"range":[3458,3459],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":93,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":93,"endColumn":19,"fix":{"range":[3619,3620],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":94,"column":15,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":94,"endColumn":30,"fix":{"range":[3664,3665],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":95,"column":31,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":95,"endColumn":45,"fix":{"range":[3719,3720],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":96,"column":36,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":96,"endColumn":51,"fix":{"range":[3780,3781],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":97,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":97,"endColumn":61},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":97,"column":35,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":97,"endColumn":52,"fix":{"range":[3842,3843],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":99,"column":67,"nodeType":"Property","messageId":"anyAssignment","endLine":99,"endColumn":78},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":104,"column":29,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":104,"endColumn":44,"fix":{"range":[4185,4186],"text":""}},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":109,"column":13,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":109,"endColumn":34,"fix":{"range":[4343,4344],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":110,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":110,"endColumn":72},{"ruleId":"@typescript-eslint/no-unnecessary-type-assertion","severity":2,"message":"This assertion is unnecessary since it does not change the type of the expression.","line":110,"column":28,"nodeType":"TSNonNullExpression","messageId":"unnecessaryAssertion","endLine":110,"endColumn":48,"fix":{"range":[4403,4404],"text":""}},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .col1 on an `any` value.","line":111,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":111,"endColumn":22}],"suppressedMessages":[],"errorCount":16,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":12,"fixableWarningCount":0,"source":"//@ts-ignore\nimport { describe, test } from \"node:test\";\nimport { strict as assert } from \"node:assert\";\nimport { getJSONBSchemaValidationErrorAsync, type TableHandler } from \"prostgles-types\";\nimport type { DB, DBHandlerServer } from \"../dist/Prostgles\";\nimport { testWithUserRLS } from \"./server/withUserRLS.spec\";\nimport { testAudit } from \"./server/audit.spec\";\nimport { testSocketLifecycle } from \"./server/socketLifecycle.spec\";\nimport { testJoins } from \"./server/joins.spec\";\nimport { testFileStorage } from \"./server/fileStorage.spec\";\nimport type { withUserRLS as WithUserRLS } from \"../dist/DboBuilder/dboBuilderUtils\";\nimport { testSchemaTypes } from \"./server/schemaTypes.spec\";\nimport { testClientSchemaTypes } from \"./server/clientSchemaTypes.spec\";\n\nexport const serverOnlyQueries = async (\n db: DBHandlerServer,\n pgDb: DB,\n withUserRLS: typeof WithUserRLS,\n) => {\n await describe(\"Server Only Queries\", async () => {\n await testSchemaTypes(db, pgDb);\n await testClientSchemaTypes(pgDb);\n await testFileStorage(db, pgDb);\n await testJoins(pgDb);\n await testSocketLifecycle(pgDb);\n await testAudit(pgDb);\n await test(\"getJSONBSchemaValidationErrorAsync with real db handlers\", async () => {\n const dbMap = new Map(Object.entries(db)) as Map<string, TableHandler>;\n\n assert.deepEqual(\n await getJSONBSchemaValidationErrorAsync({ type: \"TableLookup\" }, \"items\", dbMap),\n { data: \"items\" },\n );\n assert.deepEqual(\n await getJSONBSchemaValidationErrorAsync({ type: \"TableLookup\" }, \"missing\", dbMap),\n { error: 'value references an unknown table \"missing\"' },\n );\n\n const column = { table: \"items\", column: \"name\" };\n assert.deepEqual(\n await getJSONBSchemaValidationErrorAsync({ type: \"ColumnLookup\" }, column, dbMap),\n { data: column },\n );\n assert.deepEqual(\n await getJSONBSchemaValidationErrorAsync(\n { type: \"ColumnLookup\" },\n { table: \"items\", column: \"missing\" },\n dbMap,\n ),\n { error: 'value references an unknown or disallowed column \"items.missing\"' },\n );\n\n assert.deepEqual(\n await getJSONBSchemaValidationErrorAsync(\n { type: \"RowLookup\", table: \"users\" },\n { id: 1 },\n dbMap,\n ),\n { data: { id: 1 } },\n );\n assert.deepEqual(\n await getJSONBSchemaValidationErrorAsync(\n { type: \"ValueLookup\", table: \"users\", column: \"id\" },\n -1,\n dbMap,\n ),\n { error: 'value does not reference an existing row in \"users\"' },\n );\n });\n\n await test('Parallel subscription at init causing crash in getPubSubManager: duplicate key value violates unique constraint \"apps_pkey\"', async () => {\n let results: any[] = [];\n const sub1 = db.rec.subscribe!({}, {}, (res) => {\n results.push(res);\n });\n const sub2 = db.items.subscribe!({}, {}, (res) => {\n results.push(res);\n });\n const timeout = 5_000;\n while (results.length < 2 && timeout > 0) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n assert(results.length === 2, \"Did not receive both subscription initial results\");\n (await sub1).unsubscribe();\n (await sub2).unsubscribe();\n });\n await testWithUserRLS(db, pgDb, withUserRLS);\n await test(\"Self reference recursion bug\", async () => {\n await db.rec.findOne!({ id: 1 }, { select: { \"*\": 1, rec_ref: \"*\" } });\n });\n await test(\"Transactions\", async () => {\n const rowData = { name: \"tx_\" };\n await db.tx!(async (t) => {\n await t.items.insert!(rowData);\n const expect1 = await t.items.count!(rowData);\n const expect0count = await db.items.count!(rowData);\n const expect0find = await db.items.findOne!(rowData);\n if (expect0count !== 0 || expect0find || expect1 !== 1) {\n throw \"db.tx failed: \" + JSON.stringify({ expect0count, expect0find, expect1 });\n }\n\n //throw \"err\"; // Any errors will revert all data-changing commands using the transaction object ( t )\n });\n const expect1 = await db.items.count!(rowData);\n if (expect1 !== 1) throw \"db.tx failed\";\n });\n\n await test(\"TableConfig onMount works\", async () => {\n await db.api_table.findOne!({ id: 1 });\n const newRow = await db.api_table.insert!({}, { returning: \"*\" });\n if (newRow.col1 !== null) {\n throw \"api_table onMount failed: col1 missing. Got: \" + JSON.stringify(newRow);\n }\n });\n });\n};\n","usedDeprecatedRules":[]}]