@teleporthq/teleport-plugin-next-data-source 0.44.14 → 0.44.17

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 (125) hide show
  1. package/__tests__/_helpers/exposure.ts +29 -0
  2. package/__tests__/_helpers/first-page-runtime.ts +12 -2
  3. package/__tests__/blog-post-contents.test.ts +3 -1
  4. package/__tests__/blog-post-page-enrichment.test.ts +2 -1
  5. package/__tests__/blog-post-seo-fields.test.ts +124 -0
  6. package/__tests__/browser-row-policy.test.ts +65 -5
  7. package/__tests__/data-source-cache-wrapping.test.ts +48 -7
  8. package/__tests__/external-read-routes-guard.test.ts +991 -0
  9. package/__tests__/null-filter-where.test.ts +19 -2
  10. package/__tests__/range-control.test.ts +29 -0
  11. package/__tests__/search-relevance.test.ts +42 -6
  12. package/__tests__/table-read-route-protected-tables.test.ts +54 -4
  13. package/dist/cjs/count-fetchers.d.ts.map +1 -1
  14. package/dist/cjs/count-fetchers.js +1 -1
  15. package/dist/cjs/count-fetchers.js.map +1 -1
  16. package/dist/cjs/data-source-fetchers.d.ts +4 -0
  17. package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
  18. package/dist/cjs/data-source-fetchers.js +97 -20
  19. package/dist/cjs/data-source-fetchers.js.map +1 -1
  20. package/dist/cjs/fetchers/postgresql.d.ts +3 -1
  21. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  22. package/dist/cjs/fetchers/postgresql.js +11 -3
  23. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  24. package/dist/cjs/fetchers/raw-query.d.ts +20 -1
  25. package/dist/cjs/fetchers/raw-query.d.ts.map +1 -1
  26. package/dist/cjs/fetchers/raw-query.js +37 -7
  27. package/dist/cjs/fetchers/raw-query.js.map +1 -1
  28. package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
  29. package/dist/cjs/fetchers/redshift.js +2 -1
  30. package/dist/cjs/fetchers/redshift.js.map +1 -1
  31. package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
  32. package/dist/cjs/fetchers/teleport.js +5 -3
  33. package/dist/cjs/fetchers/teleport.js.map +1 -1
  34. package/dist/cjs/fetchers/utils/external-read-guard.d.ts +53 -0
  35. package/dist/cjs/fetchers/utils/external-read-guard.d.ts.map +1 -0
  36. package/dist/cjs/fetchers/utils/external-read-guard.js +126 -0
  37. package/dist/cjs/fetchers/utils/external-read-guard.js.map +1 -0
  38. package/dist/cjs/fetchers/utils/table-access-guard.d.ts +76 -12
  39. package/dist/cjs/fetchers/utils/table-access-guard.d.ts.map +1 -1
  40. package/dist/cjs/fetchers/utils/table-access-guard.js +123 -15
  41. package/dist/cjs/fetchers/utils/table-access-guard.js.map +1 -1
  42. package/dist/cjs/index.js +1 -1
  43. package/dist/cjs/pagination-controls.d.ts +4 -1
  44. package/dist/cjs/pagination-controls.d.ts.map +1 -1
  45. package/dist/cjs/pagination-controls.js +4 -1
  46. package/dist/cjs/pagination-controls.js.map +1 -1
  47. package/dist/cjs/pagination-plugin.js +1 -0
  48. package/dist/cjs/pagination-plugin.js.map +1 -1
  49. package/dist/cjs/range-control.d.ts +10 -5
  50. package/dist/cjs/range-control.d.ts.map +1 -1
  51. package/dist/cjs/range-control.js +23 -2
  52. package/dist/cjs/range-control.js.map +1 -1
  53. package/dist/cjs/transformations/blog-post.d.ts +5 -0
  54. package/dist/cjs/transformations/blog-post.d.ts.map +1 -1
  55. package/dist/cjs/transformations/blog-post.js +6 -2
  56. package/dist/cjs/transformations/blog-post.js.map +1 -1
  57. package/dist/cjs/transformations/index.d.ts +18 -2
  58. package/dist/cjs/transformations/index.d.ts.map +1 -1
  59. package/dist/cjs/transformations/index.js +26 -1
  60. package/dist/cjs/transformations/index.js.map +1 -1
  61. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  62. package/dist/esm/count-fetchers.d.ts.map +1 -1
  63. package/dist/esm/count-fetchers.js +1 -1
  64. package/dist/esm/count-fetchers.js.map +1 -1
  65. package/dist/esm/data-source-fetchers.d.ts +4 -0
  66. package/dist/esm/data-source-fetchers.d.ts.map +1 -1
  67. package/dist/esm/data-source-fetchers.js +97 -20
  68. package/dist/esm/data-source-fetchers.js.map +1 -1
  69. package/dist/esm/fetchers/postgresql.d.ts +3 -1
  70. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  71. package/dist/esm/fetchers/postgresql.js +12 -4
  72. package/dist/esm/fetchers/postgresql.js.map +1 -1
  73. package/dist/esm/fetchers/raw-query.d.ts +20 -1
  74. package/dist/esm/fetchers/raw-query.d.ts.map +1 -1
  75. package/dist/esm/fetchers/raw-query.js +38 -8
  76. package/dist/esm/fetchers/raw-query.js.map +1 -1
  77. package/dist/esm/fetchers/redshift.d.ts.map +1 -1
  78. package/dist/esm/fetchers/redshift.js +2 -1
  79. package/dist/esm/fetchers/redshift.js.map +1 -1
  80. package/dist/esm/fetchers/teleport.d.ts.map +1 -1
  81. package/dist/esm/fetchers/teleport.js +6 -4
  82. package/dist/esm/fetchers/teleport.js.map +1 -1
  83. package/dist/esm/fetchers/utils/external-read-guard.d.ts +53 -0
  84. package/dist/esm/fetchers/utils/external-read-guard.d.ts.map +1 -0
  85. package/dist/esm/fetchers/utils/external-read-guard.js +118 -0
  86. package/dist/esm/fetchers/utils/external-read-guard.js.map +1 -0
  87. package/dist/esm/fetchers/utils/table-access-guard.d.ts +76 -12
  88. package/dist/esm/fetchers/utils/table-access-guard.d.ts.map +1 -1
  89. package/dist/esm/fetchers/utils/table-access-guard.js +119 -15
  90. package/dist/esm/fetchers/utils/table-access-guard.js.map +1 -1
  91. package/dist/esm/index.js +1 -1
  92. package/dist/esm/pagination-controls.d.ts +4 -1
  93. package/dist/esm/pagination-controls.d.ts.map +1 -1
  94. package/dist/esm/pagination-controls.js +4 -1
  95. package/dist/esm/pagination-controls.js.map +1 -1
  96. package/dist/esm/pagination-plugin.js +1 -0
  97. package/dist/esm/pagination-plugin.js.map +1 -1
  98. package/dist/esm/range-control.d.ts +10 -5
  99. package/dist/esm/range-control.d.ts.map +1 -1
  100. package/dist/esm/range-control.js +23 -2
  101. package/dist/esm/range-control.js.map +1 -1
  102. package/dist/esm/transformations/blog-post.d.ts +5 -0
  103. package/dist/esm/transformations/blog-post.d.ts.map +1 -1
  104. package/dist/esm/transformations/blog-post.js +6 -2
  105. package/dist/esm/transformations/blog-post.js.map +1 -1
  106. package/dist/esm/transformations/index.d.ts +18 -2
  107. package/dist/esm/transformations/index.d.ts.map +1 -1
  108. package/dist/esm/transformations/index.js +27 -2
  109. package/dist/esm/transformations/index.js.map +1 -1
  110. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  111. package/package.json +5 -5
  112. package/src/count-fetchers.ts +10 -2
  113. package/src/data-source-fetchers.ts +144 -23
  114. package/src/fetchers/postgresql.ts +38 -9
  115. package/src/fetchers/raw-query.ts +125 -13
  116. package/src/fetchers/redshift.ts +3 -0
  117. package/src/fetchers/teleport.ts +29 -8
  118. package/src/fetchers/utils/external-read-guard.ts +289 -0
  119. package/src/fetchers/utils/table-access-guard.ts +469 -20
  120. package/src/index.ts +1 -1
  121. package/src/pagination-controls.ts +4 -1
  122. package/src/pagination-plugin.ts +1 -0
  123. package/src/range-control.ts +40 -8
  124. package/src/transformations/blog-post.ts +107 -4
  125. package/src/transformations/index.ts +44 -1
@@ -1 +1 @@
1
- {"version":3,"file":"raw-query.js","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"raw-query.js","sourceRoot":"","sources":["../../../src/fetchers/raw-query.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"redshift.d.ts","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA6MF,CAAA"}
1
+ {"version":3,"file":"redshift.d.ts","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA+MF,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { replaceSecretReference, generateDateFormatterCode, generateSafeJSONParseCode, generateFilterTreeHelpersCode, generateSearchEscapeHelpersCode, } from '../utils';
2
+ import { DataExposure } from '@teleporthq/teleport-shared';
2
3
  import { generateSearchSqlHelpersCode, REDSHIFT_SEARCH_SQL } from '../search-relevance';
3
4
  export var generateRedshiftFetcher = function (config, tableName) {
4
5
  var _a;
@@ -11,7 +12,7 @@ export var generateRedshiftFetcher = function (config, tableName) {
11
12
  var ssl = redshiftConfig.ssl;
12
13
  var sslConfig = redshiftConfig.sslConfig;
13
14
  var schema = (_a = redshiftConfig.options) === null || _a === void 0 ? void 0 : _a.schema;
14
- return "import { Client } from 'pg'\n\nconst getClient = () => {\n return new Client({\n host: ".concat(JSON.stringify(host), ",\n port: ").concat(port || 5439, ",\n user: ").concat(JSON.stringify(user), ",\n password: ").concat(replaceSecretReference(password), ",\n database: ").concat(JSON.stringify(database), ",\n ssl: ").concat(ssl === false
15
+ return "import { Client } from 'pg'\n\n// No query waits on the database longer than this (enforced by the client).\nconst getClient = () => {\n return new Client({\n query_timeout: ".concat(DataExposure.READ_QUERY_TIMEOUT_MS, ",\n host: ").concat(JSON.stringify(host), ",\n port: ").concat(port || 5439, ",\n user: ").concat(JSON.stringify(user), ",\n password: ").concat(replaceSecretReference(password), ",\n database: ").concat(JSON.stringify(database), ",\n ssl: ").concat(ssl === false
15
16
  ? '{ rejectUnauthorized: false }'
16
17
  : sslConfig
17
18
  ? "{\n ".concat(sslConfig.ca ? "ca: ".concat(replaceSecretReference(sslConfig.ca), ",") : '', "\n ").concat(sslConfig.cert ? "cert: ".concat(replaceSecretReference(sslConfig.cert), ",") : '', "\n ").concat(sslConfig.key ? "key: ".concat(replaceSecretReference(sslConfig.key), ",") : '', "\n rejectUnauthorized: ").concat(sslConfig.rejectUnauthorized !== false, "\n }")
@@ -1 +1 @@
1
- {"version":3,"file":"redshift.js","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,6BAA6B,EAC7B,+BAA+B,GAChC,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAavF,MAAM,CAAC,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAA;IAC9B,IAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAA;IAC1C,IAAM,MAAM,GAAG,MAAA,cAAc,CAAC,OAAO,0CAAE,MAAM,CAAA;IAE7C,OAAO,qGAIG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0BACpB,IAAI,IAAI,IAAI,0BACZ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8BAChB,sBAAsB,CAAC,QAAQ,CAAC,8BAChC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,yBAElC,GAAG,KAAK,KAAK;QACX,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,mBACF,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAClE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAS,sBAAsB,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBACxE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,eAAQ,sBAAsB,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,yCACjD,SAAS,CAAC,kBAAkB,KAAK,KAAK,YAC5D;YACE,CAAC,CAAC,+BAA+B,CAAC,wDAAwD;8BAKhG,yBAAyB,EAAE,iBAE3B,6BAA6B,EAAE,iBAE/B,+BAA+B,EAAE,eACjC,4BAA4B,CAAC,mBAAmB,CAAC,iBAEjD,yBAAyB,EAAE,+IAOvB,MAAM,CAAC,CAAC,CAAC,iDAA0C,MAAM,OAAI,CAAC,CAAC,CAAC,EAAE,2oBAmB1D,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,2FAG5C,MAAM;QACJ,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAG;QAC7D,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAG,i7EAiEhB,SAAS,wvEAkExC,CAAA;AACD,CAAC,CAAA"}
1
+ {"version":3,"file":"redshift.js","sourceRoot":"","sources":["../../../src/fetchers/redshift.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,6BAA6B,EAC7B,+BAA+B,GAChC,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAavF,MAAM,CAAC,IAAM,uBAAuB,GAAG,UACrC,MAA+B,EAC/B,SAAiB;;IAEjB,IAAM,cAAc,GAAG,MAAwB,CAAA;IAC/C,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAA;IAChC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAA;IACxC,IAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAA;IAC9B,IAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAA;IAC1C,IAAM,MAAM,GAAG,MAAA,cAAc,CAAC,OAAO,0CAAE,MAAM,CAAA;IAE7C,OAAO,4LAKY,YAAY,CAAC,qBAAqB,0BAC3C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0BACpB,IAAI,IAAI,IAAI,0BACZ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8BAChB,sBAAsB,CAAC,QAAQ,CAAC,8BAChC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,yBAElC,GAAG,KAAK,KAAK;QACX,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,mBACF,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,cAAO,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBAClE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAS,sBAAsB,CAAC,SAAS,CAAC,IAAI,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,qBACxE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,eAAQ,sBAAsB,CAAC,SAAS,CAAC,GAAG,CAAC,MAAG,CAAC,CAAC,CAAC,EAAE,yCACjD,SAAS,CAAC,kBAAkB,KAAK,KAAK,YAC5D;YACE,CAAC,CAAC,+BAA+B,CAAC,wDAAwD;8BAKhG,yBAAyB,EAAE,iBAE3B,6BAA6B,EAAE,iBAE/B,+BAA+B,EAAE,eACjC,4BAA4B,CAAC,mBAAmB,CAAC,iBAEjD,yBAAyB,EAAE,+IAOvB,MAAM,CAAC,CAAC,CAAC,iDAA0C,MAAM,OAAI,CAAC,CAAC,CAAC,EAAE,2oBAmB1D,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,2FAG5C,MAAM;QACJ,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAG;QAC7D,CAAC,CAAC,WAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAG,i7EAiEhB,SAAS,wvEAkExC,CAAA;AACD,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"teleport.d.ts","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAA;AA2C3B,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAMpC,CAAA;AAED,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,qBACC,sBAAsB,KACvC,MAycF,CAAA;AAED,eAAO,MAAM,4BAA4B,WAC/B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA0FF,CAAA"}
1
+ {"version":3,"file":"teleport.d.ts","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAA;AAgD3B,eAAO,MAAM,sBAAsB,WACzB,OAAO,MAAM,EAAE,OAAO,CAAC,KAC9B;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAMpC,CAAA;AAED,eAAO,MAAM,uBAAuB,WAC1B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,qBACC,sBAAsB,KACvC,MAwdF,CAAA;AAED,eAAO,MAAM,4BAA4B,WAC/B,OAAO,MAAM,EAAE,OAAO,CAAC,aACpB,MAAM,KAChB,MA2FF,CAAA"}
@@ -6,7 +6,8 @@ import { generateRowOrderTiebreakHelper, rowIdentityColumn } from '../row-order'
6
6
  import { generateProductFilterClauseHelper } from '../product-filter-fields';
7
7
  import { collectLocalizedColumns, generateLocalizedColumnsHelper } from '../localized-columns';
8
8
  import { REQUEST_LOCALE_PARAM } from '../request-locale';
9
- import { generateReadGuardCall, generateTableAccessPreamble } from './utils/table-access-guard';
9
+ import { DataExposure } from '@teleporthq/teleport-shared';
10
+ import { generateReadGuardCall, generateTableAccessPreamble, sqlRouteFieldPolicy, } from './utils/table-access-guard';
10
11
  import { generateRequestSqlGuardsCode } from './utils/request-sql-guards';
11
12
  import { generateArrayOverlapSqlCode } from '../array-overlap-sql';
12
13
  import { generateSearchSqlHelpersCode, PG_SEARCH_SQL } from '../search-relevance';
@@ -56,9 +57,10 @@ export var generateTeleportFetcher = function (config, tableName, transformOptio
56
57
  ? "key: ".concat(resolveEnvReference(dbConfig.sslConfig.key, 'TELEPORT_DB_SSL_KEY'), ",")
57
58
  : '', "\n rejectUnauthorized: false\n }")
58
59
  : "(process.env.".concat(DEFAULT_ENV_KEYS.ssl, " === 'false' ? false : process.env.").concat(DEFAULT_ENV_KEYS.ssl, " === 'true' ? { rejectUnauthorized: false } : undefined)");
59
- return "".concat(PG_CLIENT_IMPORT, "\n\n").concat(generateTableAccessPreamble(transformOptions.trustedReaderRoles || []), "\nfunction normalizePostgresConnectionString(connectionString) {\n if (!connectionString || typeof connectionString !== 'string') return connectionString;\n if (/^postgresql:\\/(?!\\/)/i.test(connectionString)) {\n return connectionString.replace(/^postgresql:\\//i, 'postgresql://');\n }\n return connectionString;\n}\n\nfunction stripSslQueryParamsFromConnectionString(connectionString) {\n if (!connectionString || typeof connectionString !== 'string') return connectionString;\n try {\n var u = new URL(connectionString.replace(/^postgresql:/i, 'postgres:'));\n u.searchParams.delete('sslmode');\n u.searchParams.delete('ssl');\n u.searchParams.delete('sslrootcert');\n u.searchParams.delete('sslcert');\n u.searchParams.delete('sslkey');\n return u.toString().replace(/^postgres:/i, 'postgresql:');\n } catch (e) {\n return connectionString;\n }\n}\n\nconst getClient = () => {\n var ssl = ").concat(sslCode, ";\n var connStr = process.env.TELEPORT_DB_CONNECTION_STRING;\n if (connStr) {\n connStr = normalizePostgresConnectionString(connStr);\n }\n if (ssl === false && connStr) {\n connStr = stripSslQueryParamsFromConnectionString(connStr);\n }\n if (connStr) {\n return new Client(Object.assign(\n { connectionString: connStr },\n ssl !== undefined ? { ssl: ssl } : {}\n ));\n }\n return new Client(Object.assign(\n {\n host: ").concat(hostRef, ",\n port: parseInt(").concat(portRef, " || '5432', 10),\n user: ").concat(userRef, ",\n password: ").concat(passwordRef, ",\n database: ").concat(databaseRef, ",\n },\n ssl !== undefined ? { ssl: ssl } : {}\n ));\n}\n\n").concat(generateSafeJSONParseCode(), "\n\n").concat(generateFilterTreeHelpersCode(), "\n\n").concat(generateSearchEscapeHelpersCode(), "\n").concat(generateSearchSqlHelpersCode(PG_SEARCH_SQL), "\n").concat(generateArrayOverlapSqlCode(), "\n").concat(getTransformationCode(tableName, transformOptions), "\n").concat(getTransformWrapperCode(tableName, transformOptions), "\n").concat(generateRequestSqlGuardsCode(), "\nconst processFilters = (filters, conditions, queryParams, paramIndex) => {\n if (!filters) return paramIndex\n \n const filterTree = normalizeFilterTree(safeJSONParse(filters))\n if (!filterTree) return paramIndex\n \n const buildCondition = (condition) => {\n const field = condition.source\n const normalizedCondition = normalizeInOperand(condition.operand, condition.destination)\n if (normalizedCondition === null) return null\n const value = normalizedCondition.value\n const operand = normalizedCondition.operand\n \n // The products table's virtual fields (effective price, rating bucket,\n // on-sale flag, variant axes) are whole clauses, not columns - so they are\n // answered before any branch below can interpolate the field name raw.\n const productClause = productFilterClause(field, operand, value, (param) => {\n queryParams.push(param)\n return '$' + paramIndex++\n })\n if (productClause !== null) return productClause\n\n // A translatable column is compared against the value in every language,\n // so a localized slug resolves under any locale - see localized-columns.ts.\n const localizedClause = localizedEqualityClause(field, operand, value, (param) => {\n queryParams.push(param)\n return '$' + paramIndex++\n })\n if (localizedClause !== null) return localizedClause\n assertRequestColumn(field, 'filter field')\n \n if (Array.isArray(value)) {\n if (value.length === 0) return null\n if (operand === 'array_overlap') {\n // The row's list (see array-overlap-sql.ts) shares any value with the set.\n const clause = arrayOverlapSql((localizedColumnList(field) || [field]), '$' + paramIndex)\n queryParams.push(value.map((entry) => String(entry)))\n paramIndex++\n return clause\n }\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n return operand === '!='\n ? `${field} NOT IN (${placeholders.join(', ')})`\n : `${field} IN (${placeholders.join(', ')})`\n }\n \n if (operand === 'array_overlap') {\n if (value === '' || value === null || value === undefined) return null\n // A single comma-joined string (the multi-select Category Filter's\n // ?categoryFilter=a,b,c) expands to multiple ids; one id stays one.\n const overlapValues = String(value).split(',').map((entry) => entry.trim()).filter(Boolean)\n if (overlapValues.length === 0) return null\n const clause = arrayOverlapSql((localizedColumnList(field) || [field]), '$' + paramIndex)\n queryParams.push(overlapValues)\n paramIndex++\n return clause\n }\n \n if (value === null) {\n if (operand === '=') return `${field} IS NULL`\n if (operand === '!=') return `${field} IS NOT NULL`\n return null\n }\n \n const validOps = ['=', '!=', '>', '<', '>=', '<=']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n const clause = `${field} ${sqlOperator} $${paramIndex}`\n queryParams.push(value)\n paramIndex++\n return clause\n }\n \n const clause = buildFilterTreeClause(filterTree, buildCondition)\n if (clause) conditions.push(clause)\n \n return paramIndex\n}\n\n").concat(generateDateFormatterCode(), "\n\n").concat(generateSortFieldSqlHelper(tableName), "\n\n").concat(generateSortFallbackFieldHelper(tableName), "\n\n").concat(generateRowOrderTiebreakHelper(rowIdentityColumn(config, tableName)), "\n\n").concat(generateProductFilterClauseHelper(tableName), "\n\n").concat(generateLocalizedColumnsHelper(localizedColumns), "\n\n// Matches DDL / dangerous statements the raw-query branch should refuse.\n// Keep this list conservative \u2014 anything destructive or schema-changing is\n// out of scope for a client-triggered fetch. SELECT and CTEs (WITH ...) are\n// the only shapes consumers legitimately need.\nconst BLOCKED_RAW_QUERY_PATTERNS = [\n /\\bcreate\\s+(?:temporary\\s+|temp\\s+|unlogged\\s+|global\\s+|local\\s+)?table\\b/i,\n /\\bcreate\\s+(?:unique\\s+)?index\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?(?:materialized\\s+)?view\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?trigger\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?(?:aggregate\\s+)?function\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?procedure\\b/i,\n /\\bcreate\\s+(?:database|schema|sequence|extension|type|role|user)\\b/i,\n /\\bdrop\\s+(?:table|view|index|schema|database|sequence|trigger|function|procedure|role|user|extension|type|materialized)\\b/i,\n /\\balter\\s+(?:table|view|index|schema|database|sequence|role|user|system)\\b/i,\n /\\btruncate\\b/i,\n /\\bgrant\\b/i,\n /\\brevoke\\b/i,\n /\\binsert\\b/i,\n /\\bupdate\\b/i,\n /\\bdelete\\b/i,\n /\\bcopy\\b/i,\n /\\bvacuum\\b/i,\n /\\breindex\\b/i,\n /\\bcluster\\b/i,\n]\n\nfunction assertRawQuerySafe(rawQuery) {\n if (typeof rawQuery !== 'string' || rawQuery.length === 0) {\n throw new Error('rawQuery must be a non-empty string')\n }\n // Reject multi-statement payloads \u2014 only single SELECT / WITH statements.\n // A trailing semicolon is tolerated but any content after it fails.\n var trimmed = rawQuery.trim().replace(/;\\s*$/, '')\n if (trimmed.indexOf(';') !== -1) {\n throw new Error('rawQuery must contain exactly one statement')\n }\n for (var i = 0; i < BLOCKED_RAW_QUERY_PATTERNS.length; i++) {\n if (BLOCKED_RAW_QUERY_PATTERNS[i].test(trimmed)) {\n throw new Error('rawQuery contains a blocked statement')\n }\n }\n}\n\nexport default async function handler(req, res) {\n").concat(generateReadGuardCall(tableName, 'req.query && req.query.rawQuery'), "\n const client = getClient()\n\n try {\n await client.connect()\n ").concat(schema ? "await client.query('SET search_path TO ".concat(schema, "')") : '', "\n\n // If the caller supplied a rawQuery, run it verbatim (after a safety\n // guard). The schema-driven branch below builds `SELECT * FROM ").concat(tableName, "`\n // with optional filters \u2014 it's the default read path and ignores\n // rawQuery. Page-load workflows and other consumers that need a JOIN\n // or a user-scoped filter pass their fully-rendered SQL here via\n // `fetchData({ rawQuery })` and expect it to execute verbatim.\n if (req.query && typeof req.query.rawQuery === 'string' && req.query.rawQuery.length > 0) {\n assertRawQuerySafe(req.query.rawQuery)\n // A page's own statement, read for a visitor, runs over the rows a\n // visitor is served of every narrowed table it names.\n const rawSql = __rowAccess.narrowRaw ? __brpNarrowRawQuery(req.query.rawQuery) : req.query.rawQuery\n const rawResult = await client.query(rawSql)\n const rawRows = Array.isArray(rawResult?.rows) ? rawResult.rows : []\n const rawPlain = rawRows.map((row) =>\n row && typeof row.toJSON === 'function' ? row.toJSON() : row\n )\n const rawSafe = JSON.parse(JSON.stringify(rawPlain, dateReplacer))\n return res.status(200).json({\n success: true,\n // Every row here ends up in a browser (a page's props or a client\n // refetch), so no credential column survives, whatever joined it.\n data: __taWithoutCredentials(\n __rowAccess.narrowRaw ? __brpStripHiddenOfRaw(req.query.rawQuery, rawSafe) : rawSafe,\n null\n ),\n timestamp: Date.now()\n })\n }\n\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n // A visitor never filters, sorts or searches by a column it is not served.\n if (__rowPolicy) __brpAssertVisibleFields(__rowPolicy, req.query)\n // The language the page is in - what a translatable sort orders by.\n const requestLocale = typeof req.query.").concat(REQUEST_LOCALE_PARAM, " === 'string' ? req.query.").concat(REQUEST_LOCALE_PARAM, " : null\n \n const conditions = []\n const queryParams = []\n let paramIndex = 1\n let searchRank = ''\n let searchFrom = ''\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : [])\n } else {\n try {\n const schemaQuery = `\n SELECT column_name \n FROM information_schema.columns \n WHERE table_name = $1\n ").concat(schema ? "AND table_schema = $2" : '', "\n ORDER BY ordinal_position\n `\n const schemaParams = ").concat(schema
60
+ return "".concat(PG_CLIENT_IMPORT, "\n\n").concat(generateTableAccessPreamble(transformOptions.trustedReaderRoles || [], transformOptions.routeExposure ||
61
+ DataExposure.readExposureFor(transformOptions.dataExposure, { tableName: tableName }), sqlRouteFieldPolicy(config, tableName), tableName, transformOptions), "\nfunction normalizePostgresConnectionString(connectionString) {\n if (!connectionString || typeof connectionString !== 'string') return connectionString;\n if (/^postgresql:\\/(?!\\/)/i.test(connectionString)) {\n return connectionString.replace(/^postgresql:\\//i, 'postgresql://');\n }\n return connectionString;\n}\n\nfunction stripSslQueryParamsFromConnectionString(connectionString) {\n if (!connectionString || typeof connectionString !== 'string') return connectionString;\n try {\n var u = new URL(connectionString.replace(/^postgresql:/i, 'postgres:'));\n u.searchParams.delete('sslmode');\n u.searchParams.delete('ssl');\n u.searchParams.delete('sslrootcert');\n u.searchParams.delete('sslcert');\n u.searchParams.delete('sslkey');\n return u.toString().replace(/^postgres:/i, 'postgresql:');\n } catch (e) {\n return connectionString;\n }\n}\n\nconst getClient = () => {\n var ssl = ").concat(sslCode, ";\n var connStr = process.env.TELEPORT_DB_CONNECTION_STRING;\n if (connStr) {\n connStr = normalizePostgresConnectionString(connStr);\n }\n if (ssl === false && connStr) {\n connStr = stripSslQueryParamsFromConnectionString(connStr);\n }\n // No query waits on the database longer than this (enforced by the client:\n // a server-side statement_timeout does not survive a pooler).\n if (connStr) {\n return new Client(Object.assign(\n { connectionString: connStr, query_timeout: ").concat(DataExposure.READ_QUERY_TIMEOUT_MS, " },\n ssl !== undefined ? { ssl: ssl } : {}\n ));\n }\n return new Client(Object.assign(\n {\n host: ").concat(hostRef, ",\n port: parseInt(").concat(portRef, " || '5432', 10),\n user: ").concat(userRef, ",\n password: ").concat(passwordRef, ",\n database: ").concat(databaseRef, ",\n query_timeout: ").concat(DataExposure.READ_QUERY_TIMEOUT_MS, ",\n },\n ssl !== undefined ? { ssl: ssl } : {}\n ));\n}\n\n").concat(generateSafeJSONParseCode(), "\n\n").concat(generateFilterTreeHelpersCode(), "\n\n").concat(generateSearchEscapeHelpersCode(), "\n").concat(generateSearchSqlHelpersCode(PG_SEARCH_SQL), "\n").concat(generateArrayOverlapSqlCode(), "\n").concat(getTransformationCode(tableName, transformOptions), "\n").concat(getTransformWrapperCode(tableName, transformOptions), "\n").concat(generateRequestSqlGuardsCode(), "\nconst processFilters = (filters, conditions, queryParams, paramIndex) => {\n if (!filters) return paramIndex\n \n const filterTree = normalizeFilterTree(safeJSONParse(filters))\n if (!filterTree) return paramIndex\n \n const buildCondition = (condition) => {\n const field = condition.source\n const normalizedCondition = normalizeInOperand(condition.operand, condition.destination)\n if (normalizedCondition === null) return null\n const value = normalizedCondition.value\n const operand = normalizedCondition.operand\n \n // The products table's virtual fields (effective price, rating bucket,\n // on-sale flag, variant axes) are whole clauses, not columns - so they are\n // answered before any branch below can interpolate the field name raw.\n const productClause = productFilterClause(field, operand, value, (param) => {\n queryParams.push(param)\n return '$' + paramIndex++\n })\n if (productClause !== null) return productClause\n\n // A translatable column is compared against the value in every language,\n // so a localized slug resolves under any locale - see localized-columns.ts.\n const localizedClause = localizedEqualityClause(field, operand, value, (param) => {\n queryParams.push(param)\n return '$' + paramIndex++\n })\n if (localizedClause !== null) return localizedClause\n assertRequestColumn(field, 'filter field')\n \n if (Array.isArray(value)) {\n if (value.length === 0) return null\n if (operand === 'array_overlap') {\n // The row's list (see array-overlap-sql.ts) shares any value with the set.\n const clause = arrayOverlapSql((localizedColumnList(field) || [field]), '$' + paramIndex)\n queryParams.push(value.map((entry) => String(entry)))\n paramIndex++\n return clause\n }\n const placeholders = value.map(() => `$${paramIndex++}`)\n queryParams.push(...value)\n return operand === '!='\n ? `${field} NOT IN (${placeholders.join(', ')})`\n : `${field} IN (${placeholders.join(', ')})`\n }\n \n if (operand === 'array_overlap') {\n if (value === '' || value === null || value === undefined) return null\n // A single comma-joined string (the multi-select Category Filter's\n // ?categoryFilter=a,b,c) expands to multiple ids; one id stays one.\n const overlapValues = String(value).split(',').map((entry) => entry.trim()).filter(Boolean)\n if (overlapValues.length === 0) return null\n const clause = arrayOverlapSql((localizedColumnList(field) || [field]), '$' + paramIndex)\n queryParams.push(overlapValues)\n paramIndex++\n return clause\n }\n \n if (value === null) {\n if (operand === '=') return `${field} IS NULL`\n if (operand === '!=') return `${field} IS NOT NULL`\n return null\n }\n \n // 'like' reads a JSON-list cell for one member (a post's former slugs); the\n // value is a bound parameter, so a pattern never reaches the SQL text.\n const validOps = ['=', '!=', '>', '<', '>=', '<=', 'like']\n const sqlOperator = validOps.includes(operand) ? operand : '='\n const clause = `${field} ${sqlOperator} $${paramIndex}`\n queryParams.push(value)\n paramIndex++\n return clause\n }\n \n const clause = buildFilterTreeClause(filterTree, buildCondition)\n if (clause) conditions.push(clause)\n \n return paramIndex\n}\n\n").concat(generateDateFormatterCode(), "\n\n").concat(generateSortFieldSqlHelper(tableName), "\n\n").concat(generateSortFallbackFieldHelper(tableName), "\n\n").concat(generateRowOrderTiebreakHelper(rowIdentityColumn(config, tableName)), "\n\n").concat(generateProductFilterClauseHelper(tableName), "\n\n").concat(generateLocalizedColumnsHelper(localizedColumns), "\n\n// Matches DDL / dangerous statements the raw-query branch should refuse.\n// Keep this list conservative \u2014 anything destructive or schema-changing is\n// out of scope for a client-triggered fetch. SELECT and CTEs (WITH ...) are\n// the only shapes consumers legitimately need.\nconst BLOCKED_RAW_QUERY_PATTERNS = [\n /\\bcreate\\s+(?:temporary\\s+|temp\\s+|unlogged\\s+|global\\s+|local\\s+)?table\\b/i,\n /\\bcreate\\s+(?:unique\\s+)?index\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?(?:materialized\\s+)?view\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?trigger\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?(?:aggregate\\s+)?function\\b/i,\n /\\bcreate\\s+(?:or\\s+replace\\s+)?procedure\\b/i,\n /\\bcreate\\s+(?:database|schema|sequence|extension|type|role|user)\\b/i,\n /\\bdrop\\s+(?:table|view|index|schema|database|sequence|trigger|function|procedure|role|user|extension|type|materialized)\\b/i,\n /\\balter\\s+(?:table|view|index|schema|database|sequence|role|user|system)\\b/i,\n /\\btruncate\\b/i,\n /\\bgrant\\b/i,\n /\\brevoke\\b/i,\n /\\binsert\\b/i,\n /\\bupdate\\b/i,\n /\\bdelete\\b/i,\n /\\bcopy\\b/i,\n /\\bvacuum\\b/i,\n /\\breindex\\b/i,\n /\\bcluster\\b/i,\n]\n\nfunction assertRawQuerySafe(rawQuery) {\n if (typeof rawQuery !== 'string' || rawQuery.length === 0) {\n throw new Error('rawQuery must be a non-empty string')\n }\n // Reject multi-statement payloads \u2014 only single SELECT / WITH statements.\n // A trailing semicolon is tolerated but any content after it fails.\n var trimmed = rawQuery.trim().replace(/;\\s*$/, '')\n if (trimmed.indexOf(';') !== -1) {\n throw new Error('rawQuery must contain exactly one statement')\n }\n for (var i = 0; i < BLOCKED_RAW_QUERY_PATTERNS.length; i++) {\n if (BLOCKED_RAW_QUERY_PATTERNS[i].test(trimmed)) {\n throw new Error('rawQuery contains a blocked statement')\n }\n }\n}\n\nexport default async function handler(req, res) {\n").concat(generateReadGuardCall(tableName, 'req.query && req.query.rawQuery'), "\n const client = getClient()\n\n try {\n await client.connect()\n ").concat(schema ? "await client.query('SET search_path TO ".concat(schema, "')") : '', "\n\n // If the caller supplied a rawQuery, run it verbatim (after a safety\n // guard). The schema-driven branch below builds `SELECT * FROM ").concat(tableName, "`\n // with optional filters \u2014 it's the default read path and ignores\n // rawQuery. Page-load workflows and other consumers that need a JOIN\n // or a user-scoped filter pass their fully-rendered SQL here via\n // `fetchData({ rawQuery })` and expect it to execute verbatim.\n if (req.query && typeof req.query.rawQuery === 'string' && req.query.rawQuery.length > 0) {\n assertRawQuerySafe(req.query.rawQuery)\n // A page's own statement, read for a visitor, runs over the rows a\n // visitor is served of every narrowed table it names.\n const rawSql = __rowAccess.narrowRaw ? __brpNarrowRawQuery(req.query.rawQuery) : req.query.rawQuery\n const rawResult = await client.query(rawSql)\n const rawRows = Array.isArray(rawResult?.rows) ? rawResult.rows : []\n const rawPlain = rawRows.map((row) =>\n row && typeof row.toJSON === 'function' ? row.toJSON() : row\n )\n const rawSafe = JSON.parse(JSON.stringify(rawPlain, dateReplacer))\n return res.status(200).json({\n success: true,\n // Every row here ends up in a browser (a page's props or a client\n // refetch), so no credential column survives, whatever joined it.\n data: __taWithoutCredentials(\n __rowAccess.narrowRaw ? __brpStripHiddenOfRaw(req.query.rawQuery, rawSafe) : rawSafe,\n null\n ),\n timestamp: Date.now()\n })\n }\n\n const { query, queryColumns, limit, page, perPage, sortBy, sortOrder, filters, sorts, offset } = req.query\n // A visitor never filters, sorts or searches by a column it is not served.\n if (__rowPolicy) __brpAssertVisibleFields(__rowPolicy, req.query)\n // The language the page is in - what a translatable sort orders by.\n const requestLocale = typeof req.query.").concat(REQUEST_LOCALE_PARAM, " === 'string' ? req.query.").concat(REQUEST_LOCALE_PARAM, " : null\n \n const conditions = []\n const queryParams = []\n let paramIndex = 1\n let searchRank = ''\n let searchFrom = ''\n \n if (query) {\n let columns = []\n \n if (queryColumns) {\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : [])\n } else {\n try {\n const schemaQuery = `\n SELECT column_name \n FROM information_schema.columns \n WHERE table_name = $1\n ").concat(schema ? "AND table_schema = $2" : '', "\n ORDER BY ordinal_position\n `\n const schemaParams = ").concat(schema
60
62
  ? "[".concat(JSON.stringify(tableName), ", ").concat(JSON.stringify(schema), "]")
61
- : "[".concat(JSON.stringify(tableName), "]"), "\n \n const schemaResult = await client.query(schemaQuery, schemaParams)\n columns = schemaResult.rows.map(row => row.column_name)\n } catch (schemaError) {\n console.warn('Failed to fetch column names from information_schema:', schemaError.message)\n }\n }\n if (__rowPolicy) columns = __brpVisibleColumns(__rowPolicy, columns)\n \n const search = buildSearchSql(query, columns, paramIndex)\n if (search) {\n conditions.push(search.where)\n queryParams.push(...search.params)\n paramIndex = search.nextIndex\n searchRank = search.rank\n searchFrom = search.from\n }\n }\n \n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n if (__rowPolicy) conditions.push('(' + __rowPolicy.predicate + ')')\n \n // A search's worked-out texts stay out of the rows: only the table's own columns.\n let sql = `SELECT ${searchFrom ? '").concat(tableName, ".*' : '*'} FROM ").concat(tableName, "${searchFrom}`\n \n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`\n }\n \n // Handle sorts - new array format. Two ORDER BY clauses are built: the one\n // actually used (a translatable column in the request's language, the\n // products table's price rewrites, rows without a value last), and a\n // plain-column twin kept only as the fallback below.\n // A search orders its matches by where the words are first; the sort\n // orders the rows within each of those groups.\n let orderBySql = ''\n let plainOrderBySql = ''\n const searchOrder = searchRank ? searchRank + ', ' : ''\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const valid = parsedSorts.filter((sort) => sort && sort.field)\n valid.forEach((sort) => assertRequestColumn(sort.field, 'sort field'))\n const orderOf = (sort) => (sort.order || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n const orderClauses = valid.map((sort) => `${localizedSortFieldSql(sort.field, requestLocale) || sortFieldSql(sort.field)} ${orderOf(sort)}").concat(SORT_NULLS_LAST_SQL, "`)\n const plainClauses = valid.map((sort) => `${sortFallbackField(sort.field)} ${orderOf(sort)}`)\n\n if (orderClauses.length > 0) {\n // The row's own key last, so equal rows can't repeat across pages\n // or vanish between them.\n const tiebreak = rowOrderTiebreak(valid.map((sort) => sort.field), orderOf(valid[valid.length - 1]))\n orderBySql = ` ORDER BY ${searchOrder}${orderClauses.join(', ')}${tiebreak}`\n plainOrderBySql = ` ORDER BY ${searchOrder}${plainClauses.join(', ')}${tiebreak}`\n }\n }\n } else if (sortBy) {\n assertRequestColumn(sortBy, 'sort field')\n const sortByDirection = (sortOrder || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n const tiebreak = rowOrderTiebreak([sortBy], sortByDirection)\n orderBySql = ` ORDER BY ${searchOrder}${localizedSortFieldSql(sortBy, requestLocale) || sortBy} ${sortByDirection}").concat(SORT_NULLS_LAST_SQL, "${tiebreak}`\n plainOrderBySql = ` ORDER BY ${searchOrder}${sortBy} ${sortByDirection}${tiebreak}`\n }\n if (!orderBySql && searchRank) {\n orderBySql = plainOrderBySql = ' ORDER BY ' + searchRank + rowOrderTiebreak([], 'ASC')\n }\n const usedRewrittenSort = orderBySql !== plainOrderBySql\n\n const limitValue = requestRowCount(limit || perPage)\n const offsetValue = offset !== undefined ? parseInt(offset) : (page && perPage ? (parseInt(page) - 1) * parseInt(perPage) : undefined)\n\n let sqlTail = ''\n if (limitValue !== undefined) {\n sqlTail += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sqlTail += ` OFFSET ${offsetValue}`\n }\n\n const baseSql = sql\n sql = baseSql + orderBySql + sqlTail\n\n // The discount-aware price ordering is an inline sub-select over a JSON\n // column. It is written to be unraisable, but it runs inside ORDER BY for\n // the whole table - so if a database ever rejects it, fall back to ordering\n // by the stored list price rather than serving an empty products page. The\n // translatable-column ordering takes the same exit: a per-language column\n // the schema had at generation time may have been dropped since. So does\n // the empty-values-last ordering.\n let result\n try {\n result = await client.query(sql, queryParams)\n } catch (sortError) {\n if (!usedRewrittenSort) throw sortError\n console.warn(\n 'Rewritten sort failed; falling back to the plain column:',\n sortError && sortError.message\n )\n result = await client.query(baseSql + plainOrderBySql + sqlTail, queryParams)\n }\n const rows = Array.isArray(result?.rows) ? result.rows : []\n const plainRows = rows.map((row) =>\n row && typeof row.toJSON === 'function' ? row.toJSON() : row\n )\n const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))\n ").concat(getTransformExpression(tableName)
63
+ : "[".concat(JSON.stringify(tableName), "]"), "\n \n const schemaResult = await client.query(schemaQuery, schemaParams)\n // A credential column is never searched: a search is an oracle for it.\n columns = schemaResult.rows.map(row => row.column_name).filter((column) => !__taIsCredentialColumn(column))\n } catch (schemaError) {\n console.warn('Failed to fetch column names from information_schema:', schemaError.message)\n }\n }\n if (__rowPolicy) columns = __brpVisibleColumns(__rowPolicy, columns)\n \n const search = buildSearchSql(query, columns, paramIndex)\n if (search) {\n conditions.push(search.where)\n queryParams.push(...search.params)\n paramIndex = search.nextIndex\n searchRank = search.rank\n searchFrom = search.from\n }\n }\n \n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n if (__rowPolicy) conditions.push('(' + __rowPolicy.predicate + ')')\n \n // A search's worked-out texts stay out of the rows: only the table's own columns.\n let sql = `SELECT ${searchFrom ? '").concat(tableName, ".*' : '*'} FROM ").concat(tableName, "${searchFrom}`\n \n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`\n }\n \n // Handle sorts - new array format. Two ORDER BY clauses are built: the one\n // actually used (a translatable column in the request's language, the\n // products table's price rewrites, rows without a value last), and a\n // plain-column twin kept only as the fallback below.\n // A search orders its matches by where the words are first; the sort\n // orders the rows within each of those groups.\n let orderBySql = ''\n let plainOrderBySql = ''\n const searchOrder = searchRank ? searchRank + ', ' : ''\n if (sorts) {\n const parsedSorts = safeJSONParse(sorts)\n if (Array.isArray(parsedSorts) && parsedSorts.length > 0) {\n const valid = parsedSorts.filter((sort) => sort && sort.field)\n valid.forEach((sort) => assertRequestColumn(sort.field, 'sort field'))\n const orderOf = (sort) => (sort.order || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n const orderClauses = valid.map((sort) => `${localizedSortFieldSql(sort.field, requestLocale) || sortFieldSql(sort.field)} ${orderOf(sort)}").concat(SORT_NULLS_LAST_SQL, "`)\n const plainClauses = valid.map((sort) => `${sortFallbackField(sort.field)} ${orderOf(sort)}`)\n\n if (orderClauses.length > 0) {\n // The row's own key last, so equal rows can't repeat across pages\n // or vanish between them.\n const tiebreak = rowOrderTiebreak(valid.map((sort) => sort.field), orderOf(valid[valid.length - 1]))\n orderBySql = ` ORDER BY ${searchOrder}${orderClauses.join(', ')}${tiebreak}`\n plainOrderBySql = ` ORDER BY ${searchOrder}${plainClauses.join(', ')}${tiebreak}`\n }\n }\n } else if (sortBy) {\n assertRequestColumn(sortBy, 'sort field')\n const sortByDirection = (sortOrder || '').toUpperCase().startsWith('DESC') ? 'DESC' : 'ASC'\n const tiebreak = rowOrderTiebreak([sortBy], sortByDirection)\n orderBySql = ` ORDER BY ${searchOrder}${localizedSortFieldSql(sortBy, requestLocale) || sortBy} ${sortByDirection}").concat(SORT_NULLS_LAST_SQL, "${tiebreak}`\n plainOrderBySql = ` ORDER BY ${searchOrder}${sortBy} ${sortByDirection}${tiebreak}`\n }\n if (!orderBySql && searchRank) {\n orderBySql = plainOrderBySql = ' ORDER BY ' + searchRank + rowOrderTiebreak([], 'ASC')\n }\n const usedRewrittenSort = orderBySql !== plainOrderBySql\n\n // Whole numbers only, and a browser's read capped - see __taReadWindow.\n const __window = __taReadWindow(req)\n const limitValue = __window.limit || __window.perPage\n const offsetValue = __window.offset !== undefined ? __window.offset : (__window.page && __window.perPage ? (__window.page - 1) * __window.perPage : undefined)\n\n let sqlTail = ''\n if (limitValue !== undefined) {\n sqlTail += ` LIMIT ${limitValue}`\n }\n \n if (offsetValue !== undefined) {\n sqlTail += ` OFFSET ${offsetValue}`\n }\n\n const baseSql = sql\n sql = baseSql + orderBySql + sqlTail\n\n // The discount-aware price ordering is an inline sub-select over a JSON\n // column. It is written to be unraisable, but it runs inside ORDER BY for\n // the whole table - so if a database ever rejects it, fall back to ordering\n // by the stored list price rather than serving an empty products page. The\n // translatable-column ordering takes the same exit: a per-language column\n // the schema had at generation time may have been dropped since. So does\n // the empty-values-last ordering.\n let result\n try {\n result = await client.query(sql, queryParams)\n } catch (sortError) {\n if (!usedRewrittenSort) throw sortError\n console.warn(\n 'Rewritten sort failed; falling back to the plain column:',\n sortError && sortError.message\n )\n result = await client.query(baseSql + plainOrderBySql + sqlTail, queryParams)\n }\n const rows = Array.isArray(result?.rows) ? result.rows : []\n const plainRows = rows.map((row) =>\n row && typeof row.toJSON === 'function' ? row.toJSON() : row\n )\n const safeData = JSON.parse(JSON.stringify(plainRows, dateReplacer))\n ").concat(getTransformExpression(tableName)
62
64
  ? "const transformedData = ".concat(getTransformExpression(tableName))
63
65
  : '', "\n\n // Stamp each row with a globally-correct 1-based `__rowNumber` (the page\n // offset is applied server-side above), so list index columns keep counting\n // across pages instead of restarting at 1. Renderer-internal field \u2014 it is\n // filtered from ordinary field bindings and only read by the index column.\n const __finalData = ").concat(getTransformExpression(tableName) ? 'transformedData' : 'safeData', "\n const __rowNumberStart = (typeof offsetValue === 'number' && !isNaN(offsetValue)) ? offsetValue : 0\n const __numberedData = Array.isArray(__finalData)\n ? __finalData.map((__row, __i) =>\n __row && typeof __row === 'object' && !Array.isArray(__row)\n ? Object.assign({}, __row, { __rowNumber: __rowNumberStart + __i + 1 })\n : __row)\n : __finalData\n\n return res.status(200).json({\n success: true,\n data: __taWithoutCredentials(\n __rowPolicy ? __brpStripHidden(__rowPolicy, __numberedData) : __numberedData,\n ").concat(JSON.stringify(tableName), "\n ),\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Teleport DB fetch error:', error)\n // A database error names tables, columns and values: it stays in the server\n // log. Only an error this route raised for the caller (it carries a status)\n // is repeated to it.\n return res.status(error.status || 500).json({\n success: false,\n error: error.status ? error.message : 'Failed to fetch data',\n timestamp: Date.now()\n })\n } finally {\n if (client) {\n try {\n await client.end()\n } catch (error) {\n console.error('Error closing database client:', error)\n }\n }\n }\n}\n");
64
66
  };
@@ -68,6 +70,6 @@ export var generateTeleportCountFetcher = function (config, tableName) {
68
70
  var hasSchema = !!((_a = dbConfig.options) === null || _a === void 0 ? void 0 : _a.schema);
69
71
  return "\nasync function getCount(req, res) {\n".concat(generateReadGuardCall(tableName, null), "\n const client = getClient()\n\n try {\n await client.connect()\n const { query, queryColumns, filters } = req.query\n if (__rowPolicy) __brpAssertVisibleFields(__rowPolicy, req.query)\n const conditions = []\n const queryParams = []\n let paramIndex = 1\n let searchFrom = ''\n\n if (query) {\n let columns = []\n \n if (queryColumns) {\n const parsed = safeJSONParse(queryColumns)\n columns = Array.isArray(parsed) ? parsed : [parsed]\n } else {\n try {\n const schemaQuery = `\n SELECT column_name \n FROM information_schema.columns \n WHERE table_name = $1\n ").concat(hasSchema ? "AND table_schema = $2" : '', "\n ORDER BY ordinal_position\n `\n const schemaParams = ").concat(hasSchema
70
72
  ? "[".concat(JSON.stringify(tableName), ", ").concat(JSON.stringify(dbConfig.options.schema), "]")
71
- : "[".concat(JSON.stringify(tableName), "]"), "\n \n const schemaResult = await client.query(schemaQuery, schemaParams)\n columns = schemaResult.rows.map(row => row.column_name)\n } catch (schemaError) {\n console.warn('Failed to fetch column names from information_schema:', schemaError.message)\n }\n }\n if (__rowPolicy) columns = __brpVisibleColumns(__rowPolicy, columns)\n \n const search = buildSearchSql(query, columns, paramIndex)\n if (search) {\n conditions.push(search.where)\n queryParams.push(...search.params)\n paramIndex = search.nextIndex\n searchFrom = search.from\n }\n }\n\n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n if (__rowPolicy) conditions.push('(' + __rowPolicy.predicate + ')')\n\n let countSql = `SELECT COUNT(*) FROM ").concat(tableName, "${searchFrom}`\n if (conditions.length > 0) {\n countSql += ` WHERE ${conditions.join(' AND ')}`\n }\n\n const result = await client.query(countSql, queryParams)\n const count = parseInt(result.rows[0].count, 10)\n\n return res.status(200).json({\n success: true,\n count: count,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Error getting count:', error)\n return res.status(error.status || 500).json({\n success: false,\n error: error.status ? error.message : 'Failed to get count',\n timestamp: Date.now()\n })\n } finally {\n if (client) {\n try {\n await client.end()\n } catch (error) {\n console.error('Error closing database client:', error)\n }\n }\n }\n}\n");
73
+ : "[".concat(JSON.stringify(tableName), "]"), "\n \n const schemaResult = await client.query(schemaQuery, schemaParams)\n // A credential column is never searched: a search is an oracle for it.\n columns = schemaResult.rows.map(row => row.column_name).filter((column) => !__taIsCredentialColumn(column))\n } catch (schemaError) {\n console.warn('Failed to fetch column names from information_schema:', schemaError.message)\n }\n }\n if (__rowPolicy) columns = __brpVisibleColumns(__rowPolicy, columns)\n \n const search = buildSearchSql(query, columns, paramIndex)\n if (search) {\n conditions.push(search.where)\n queryParams.push(...search.params)\n paramIndex = search.nextIndex\n searchFrom = search.from\n }\n }\n\n paramIndex = processFilters(filters, conditions, queryParams, paramIndex)\n if (__rowPolicy) conditions.push('(' + __rowPolicy.predicate + ')')\n\n let countSql = `SELECT COUNT(*) FROM ").concat(tableName, "${searchFrom}`\n if (conditions.length > 0) {\n countSql += ` WHERE ${conditions.join(' AND ')}`\n }\n\n const result = await client.query(countSql, queryParams)\n const count = parseInt(result.rows[0].count, 10)\n\n return res.status(200).json({\n success: true,\n count: count,\n timestamp: Date.now()\n })\n } catch (error) {\n console.error('Error getting count:', error)\n return res.status(error.status || 500).json({\n success: false,\n error: error.status ? error.message : 'Failed to get count',\n timestamp: Date.now()\n })\n } finally {\n if (client) {\n try {\n await client.end()\n } catch (error) {\n console.error('Error closing database client:', error)\n }\n }\n }\n}\n");
72
74
  };
73
75
  //# sourceMappingURL=teleport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"teleport.js","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"teleport.js","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { DataReadExposure } from '@teleporthq/teleport-types';
2
+ import { RequestFieldPolicy, SchemaColumn, SessionReaderPlacement } from './table-access-guard';
3
+ /**
4
+ * The same guard for a read route over an EXTERNAL source (MySQL, MariaDB,
5
+ * Redshift, ClickHouse, Turso, Supabase, MongoDB, Firestore, Airtable, Redis,
6
+ * REST, Google Sheets, CSV, JavaScript) as the TeleportHQ / Postgres routes
7
+ * carry inline: the table's exposure, the protected-table net, a row window of
8
+ * whole numbers (a browser's capped), request fields of a safe shape, no
9
+ * credential column in a row, and a generic error to the client.
10
+ *
11
+ * The drivers differ in everything else, so the guard wraps the driver's
12
+ * handler rather than living inside fourteen of them: the driver runs only for
13
+ * a request the guard let through, with `limit` / `perPage` / `page` /
14
+ * `offset` replaced by the whole numbers the guard settled on — a driver that
15
+ * splices them into its SQL text splices digits — and its answer passes back
16
+ * through the guard, which strips credentials and replaces any error text.
17
+ */
18
+ /** How a request may name a field for a driver. */
19
+ export type RequestFieldRule = 'identifier' | 'label' | 'any';
20
+ /** SQL drivers splice the field into their statement; document stores read it as a path or an operator. */
21
+ export declare const requestFieldRuleOf: (dataSourceType: string) => RequestFieldRule;
22
+ /**
23
+ * What a request may name for a driver (see `RequestFieldPolicy`): the
24
+ * export's schema of the table — required for a SQL driver, so a table without
25
+ * one answers every named field 400 — and the driver's own shape rule.
26
+ */
27
+ export declare const driverFieldPolicy: (dataSourceType: string, schemaColumns: string[] | null) => RequestFieldPolicy;
28
+ /**
29
+ * The columns a browser's search runs over when it names none (N3): the
30
+ * table's schema — for Supabase, whose PostgREST `ilike` refuses any other
31
+ * type, its text columns — else, for a source without one, the fields the
32
+ * project's own bindings read. Never a credential column: what a search
33
+ * matches, it lets the searcher test character by character.
34
+ */
35
+ export declare const defaultSearchColumns: (dataSourceType: string, schema: SchemaColumn[] | null, bindingFields: string[]) => string[];
36
+ /**
37
+ * The driver's fetcher module with the guard around its handler: same
38
+ * imports, the preamble, the driver renamed, and a guarded `handler` exported
39
+ * in its place.
40
+ */
41
+ export declare const guardExternalDriverModule: (driverCode: string, params: {
42
+ tableName: string;
43
+ dataSourceType: string;
44
+ exposure: DataReadExposure;
45
+ trustedReaderRoles: ReadonlyArray<string>;
46
+ /** The table's columns as the data source config lists them (null: no schema). */
47
+ schema?: SchemaColumn[] | null;
48
+ /** Where the route sits and whether its session reader checks revocation. */
49
+ reader?: SessionReaderPlacement;
50
+ }) => string;
51
+ /** The driver's count handler behind the same guard (the guard code comes with the handler module). */
52
+ export declare const guardExternalDriverCount: (countCode: string) => string;
53
+ //# sourceMappingURL=external-read-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-read-guard.d.ts","sourceRoot":"","sources":["../../../../src/fetchers/utils/external-read-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAElE,OAAO,EAEL,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACvB,MAAM,sBAAsB,CAAA;AAE7B;;;;;;;;;;;;;;GAcG;AAEH,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,OAAO,GAAG,KAAK,CAAA;AAgB7D,2GAA2G;AAC3G,eAAO,MAAM,kBAAkB,mBAAoB,MAAM,KAAG,gBAkB3D,CAAA;AAKD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,mBACZ,MAAM,iBACP,MAAM,EAAE,GAAG,IAAI,KAC7B,kBAQF,CAAA;AAaD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,mBACf,MAAM,UACd,YAAY,EAAE,GAAG,IAAI,iBACd,MAAM,EAAE,KACtB,MAAM,EAQR,CAAA;AA+GD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,eACxB,MAAM;eAEL,MAAM;oBACD,MAAM;cACZ,gBAAgB;wBACN,cAAc,MAAM,CAAC;IACzC,kFAAkF;aACzE,YAAY,EAAE,GAAG,IAAI;IAC9B,6EAA6E;aACpE,sBAAsB;MAEhC,MAiCF,CAAA;AAED,uGAAuG;AACvG,eAAO,MAAM,wBAAwB,cAAe,MAAM,KAAG,MAU5D,CAAA"}
@@ -0,0 +1,118 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { DataExposure, TableAccess } from '@teleporthq/teleport-shared';
13
+ import { generateTableAccessPreamble, } from './table-access-guard';
14
+ /**
15
+ * A SQL column: plain, quoted or table-qualified — what the Postgres routes
16
+ * accept (`request-sql-guards.ts`).
17
+ */
18
+ var IDENTIFIER_FIELD_RE = /^"?[A-Za-z_][A-Za-z0-9_]*"?(?:\."?[A-Za-z_][A-Za-z0-9_]*"?)?$/;
19
+ /**
20
+ * A field of a document store or a base whose names are labels: anything but
21
+ * the characters its query language gives a meaning (`{}` closes an Airtable
22
+ * field reference, `$` opens a MongoDB operator, quotes and parentheses open
23
+ * literals and calls).
24
+ */
25
+ var LABEL_FIELD_RE = /^[^{}'"`\\(),;$]{1,128}$/;
26
+ /** SQL drivers splice the field into their statement; document stores read it as a path or an operator. */
27
+ export var requestFieldRuleOf = function (dataSourceType) {
28
+ switch (dataSourceType) {
29
+ case 'mysql':
30
+ case 'tidb':
31
+ case 'mariadb':
32
+ case 'amazon-redshift':
33
+ case 'clickhouse':
34
+ case 'turso':
35
+ case 'supabase':
36
+ return 'identifier';
37
+ case 'mongodb':
38
+ case 'firestore':
39
+ case 'airtable':
40
+ return 'label';
41
+ default:
42
+ // REST, JavaScript, CSV, Google Sheets, Redis filter the rows in memory.
43
+ return 'any';
44
+ }
45
+ };
46
+ /** The stores that read a `$`-key as an operator or a dotted key as a path. */
47
+ var DOCUMENT_STORES = new Set(['mongodb', 'firestore', 'redis']);
48
+ /**
49
+ * What a request may name for a driver (see `RequestFieldPolicy`): the
50
+ * export's schema of the table — required for a SQL driver, so a table without
51
+ * one answers every named field 400 — and the driver's own shape rule.
52
+ */
53
+ export var driverFieldPolicy = function (dataSourceType, schemaColumns) {
54
+ var rule = requestFieldRuleOf(dataSourceType);
55
+ return __assign(__assign({ columns: rule === 'identifier' ? schemaColumns || [] : schemaColumns, documentStore: DOCUMENT_STORES.has(dataSourceType) }, (rule === 'identifier' && { pattern: IDENTIFIER_FIELD_RE })), (rule === 'label' && { pattern: LABEL_FIELD_RE }));
56
+ };
57
+ /**
58
+ * The stores whose search turns the text into a pattern of their own query
59
+ * language (MongoDB's `$regex`): the text is escaped first, so it is matched
60
+ * as text — never an anchored, character-by-character probe, never a pattern
61
+ * that takes the server's time.
62
+ */
63
+ var PATTERN_SEARCH_STORES = new Set(['mongodb']);
64
+ /** A text type, as the sources name theirs (`text`, `varchar(255)`, `character varying`, `string`). */
65
+ var TEXT_COLUMN_TYPE = /char|text|string|clob|enum/i;
66
+ /**
67
+ * The columns a browser's search runs over when it names none (N3): the
68
+ * table's schema — for Supabase, whose PostgREST `ilike` refuses any other
69
+ * type, its text columns — else, for a source without one, the fields the
70
+ * project's own bindings read. Never a credential column: what a search
71
+ * matches, it lets the searcher test character by character.
72
+ */
73
+ export var defaultSearchColumns = function (dataSourceType, schema, bindingFields) {
74
+ var textOnly = dataSourceType === 'supabase';
75
+ var candidates = schema
76
+ ? schema
77
+ .filter(function (column) { return !textOnly || !column.type || TEXT_COLUMN_TYPE.test(column.type); })
78
+ .map(function (column) { return column.name; })
79
+ : bindingFields;
80
+ return Array.from(new Set(candidates)).filter(function (name) { return !TableAccess.isCredentialColumnName(name); });
81
+ };
82
+ /** The guard's own code, after the shared preamble. */
83
+ var generateDriverGuardCode = function (tableName, dataSourceType, searchColumns) { return "\n// GENERATED \u2014 see external-read-guard.ts in teleport-plugin-next-data-source.\nvar __TQ_DRIVER_TABLE = ".concat(JSON.stringify(tableName), ";\nvar __TQ_DRIVER_WINDOW_KEYS = ['limit', 'perPage', 'page', 'offset'];\nvar __TQ_DRIVER_TIMEOUT_MS = ").concat(DataExposure.READ_QUERY_TIMEOUT_MS, ";\n// What a browser's search runs over when it names no columns (the driver's own\n// fallback reads every column, credentials included).\nvar __TQ_DRIVER_SEARCH_COLUMNS = ").concat(JSON.stringify(searchColumns), ";\nvar __TQ_DRIVER_PATTERN_SEARCH = ").concat(PATTERN_SEARCH_STORES.has(dataSourceType) ? 'true' : 'false', ";\n\nasync function __taGuardedDriverRead(req, res, run, kind) {\n var failure = kind === 'count' ? 'Failed to get count' : 'Failed to fetch data';\n var exposure = await __taGuardExposure(req);\n if (exposure) {\n return res.status(exposure.status).json({ success: false, error: exposure.message, timestamp: Date.now() });\n }\n var access = await __taGuardRead(req, __TQ_DRIVER_TABLE, null);\n if (access) {\n return res.status(access.status).json({ success: false, error: access.message, timestamp: Date.now() });\n }\n var window;\n try {\n window = __taReadWindow(req);\n __taAssertReadRequest(req);\n } catch (error) {\n return res.status(400).json({ success: false, error: error && error.status ? error.message : 'Invalid request', timestamp: Date.now() });\n }\n var internal = __taIsInternalRequest(req);\n var query = Object.assign({}, (req && req.query) || {});\n __TQ_DRIVER_WINDOW_KEYS.forEach(function(key) {\n if (window[key] === undefined) delete query[key];\n else query[key] = String(window[key]);\n });\n var searching = query.query !== undefined && query.query !== null && String(query.query) !== '';\n if (searching && !internal && (query.queryColumns === undefined || query.queryColumns === null || query.queryColumns === '')) {\n if (__TQ_DRIVER_SEARCH_COLUMNS.length === 0) {\n return res.status(400).json({ success: false, error: 'Invalid search', timestamp: Date.now() });\n }\n query.queryColumns = JSON.stringify(__TQ_DRIVER_SEARCH_COLUMNS);\n }\n if (searching && __TQ_DRIVER_PATTERN_SEARCH) {\n query.query = String(Array.isArray(query.query) ? query.query[0] : query.query).replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n var forwarded = {\n method: req && req.method,\n headers: (req && req.headers) || {},\n cookies: req && req.cookies,\n // A browser's body never reaches the driver: a REST source configured for\n // POST would send it upstream, under the site's credentials, in place of\n // the configured one. The app's own server code may still supply one.\n body: internal ? req && req.body : undefined,\n query: query,\n __tqServerCall: !!(req && req.__tqServerCall === true),\n __tqOwnerScope: req && req.__tqOwnerScope,\n };\n // A row-owned page's read: the owner condition joins the request's filters.\n __taApplyOwnerScope(forwarded);\n var status = 200;\n var payload = null;\n var proxy = {\n status: function(code) { status = code; return proxy; },\n json: function(data) { payload = data; return proxy; },\n setHeader: function(name, value) {\n if (res && typeof res.setHeader === 'function') res.setHeader(name, value);\n return proxy;\n },\n };\n // No read waits on the source longer than __TQ_DRIVER_TIMEOUT_MS: a driver\n // without a query timeout of its own is answered for when it overruns.\n var timer = null;\n try {\n await Promise.race([\n run(forwarded, proxy),\n new Promise(function(_resolve, reject) {\n timer = setTimeout(function() { reject(new Error('the read timed out')); }, __TQ_DRIVER_TIMEOUT_MS);\n }),\n ]);\n } catch (error) {\n status = 500;\n payload = { success: false, error: error };\n } finally {\n if (timer) clearTimeout(timer);\n }\n if (status !== 200 || !payload || payload.success === false) {\n // The driver's error names tables, columns and values: server log only.\n var id = __taErrorId();\n console.error('[data-source] reading ' + __TQ_DRIVER_TABLE + ' failed (' + id + '):', payload && payload.error);\n return res.status(status >= 400 && status < 500 ? status : 500).json({ success: false, error: failure, id: id, timestamp: Date.now() });\n }\n if (Array.isArray(payload.data)) {\n payload = Object.assign({}, payload, { data: __taWithoutCredentials(payload.data, __TQ_DRIVER_TABLE) });\n }\n return res.status(200).json(payload);\n}\n"); };
84
+ var UNGUARDED_HANDLER = '__tqUnguardedHandler';
85
+ var UNGUARDED_COUNT = '__tqUnguardedGetCount';
86
+ var DRIVER_HANDLER_DECLARATION = 'export default async function handler(';
87
+ var COUNT_DECLARATION = 'async function getCount(req, res)';
88
+ /** The driver module's single-line imports, which must stay at the top of an ES module. */
89
+ var IMPORT_LINE = /^import\s.*$/gm;
90
+ /**
91
+ * The driver's fetcher module with the guard around its handler: same
92
+ * imports, the preamble, the driver renamed, and a guarded `handler` exported
93
+ * in its place.
94
+ */
95
+ export var guardExternalDriverModule = function (driverCode, params) {
96
+ var _a;
97
+ var schema = (_a = params.schema) !== null && _a !== void 0 ? _a : null;
98
+ var schemaColumns = schema ? schema.map(function (column) { return column.name; }) : null;
99
+ if (driverCode.split(DRIVER_HANDLER_DECLARATION).length !== 2) {
100
+ // A driver that is not one handler cannot be wrapped; refusing to generate
101
+ // it is the only answer that does not serve it unguarded.
102
+ throw new Error('a data source read route must declare exactly one handler');
103
+ }
104
+ var imports = driverCode.match(IMPORT_LINE) || [];
105
+ var body = driverCode
106
+ .replace(IMPORT_LINE, '')
107
+ .trim()
108
+ .replace(DRIVER_HANDLER_DECLARATION, "async function ".concat(UNGUARDED_HANDLER, "("));
109
+ return "".concat(imports.join('\n'), "\n\n").concat(generateTableAccessPreamble(params.trustedReaderRoles, params.exposure, driverFieldPolicy(params.dataSourceType, schemaColumns), params.tableName, params.reader)).concat(generateDriverGuardCode(params.tableName, params.dataSourceType, defaultSearchColumns(params.dataSourceType, schema, params.exposure.fields || [])), "\n").concat(body, "\n\nexport default async function handler(req, res) {\n return __taGuardedDriverRead(req, res, ").concat(UNGUARDED_HANDLER, ", 'data')\n}\n");
110
+ };
111
+ /** The driver's count handler behind the same guard (the guard code comes with the handler module). */
112
+ export var guardExternalDriverCount = function (countCode) {
113
+ if (countCode.split(COUNT_DECLARATION).length !== 2) {
114
+ throw new Error('a data source count route must declare exactly one getCount');
115
+ }
116
+ return "".concat(countCode.replace(COUNT_DECLARATION, "async function ".concat(UNGUARDED_COUNT, "(req, res)")), "\n\nasync function getCount(req, res) {\n return __taGuardedDriverRead(req, res, ").concat(UNGUARDED_COUNT, ", 'count')\n}\n");
117
+ };
118
+ //# sourceMappingURL=external-read-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-read-guard.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/external-read-guard.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,83 @@
1
+ import type { DataReadExposure } from '@teleporthq/teleport-types';
1
2
  /**
2
- * The money-table guard for a generated per-table read route
3
+ * The guard of a generated per-table read route
3
4
  * (`/api/teleport-<table>-<source>` and its `-count` twin).
4
5
  *
5
- * Every table a page binds gets such a route, and the route serves the whole
6
- * table — plus any single SELECT through `?rawQuery=` — to whoever asks. For a
7
- * catalogue that is the product; for gift cards and voucher codes it is theft.
8
- * The guard refuses a protected table (see `TableAccess.PROTECTED_TABLES`)
9
- * unless the caller is a server segment presenting the app secret or a
10
- * signed-in member of a trusted role — the generated admin, whose list pages
11
- * are the one browser reader these tables have. It is followed by the
12
- * browser row policy (see `browser-row-policy.ts`): unpublished rows and
13
- * private columns of the public tables, and the admin-only tables.
6
+ * Every table a page binds gets such a route, and the route is a URL anyone
7
+ * can call. Three nets, in this order:
8
+ * 1. the table's EXPOSURE, decided at export time from the pages that bind it
9
+ * (`DataExposure.resolveDataExposure`): a table a public page shows is read
10
+ * by anyone; one only protected pages bind needs a session one of them
11
+ * admits; one no page binds is the app's own server code's;
12
+ * 2. the protected tables (see `TableAccess.PROTECTED_TABLES`): money and
13
+ * customer records, read only by a server segment presenting the app
14
+ * secret or a signed-in member of a trusted role (the generated admin);
15
+ * 3. the browser row policy (see `browser-row-policy.ts`): unpublished rows
16
+ * and private columns of the public tables.
17
+ * A server-side caller (the app secret, or the module's own in-process
18
+ * `fetchData`) passes all three.
19
+ *
20
+ * Every row count a request names is a whole number, and a browser's read is
21
+ * capped (`__taReadWindow`): a missing count gets the table's default, a large
22
+ * one the table's maximum.
23
+ */
24
+ /** No route reads more than this many rows past the first, from a browser. */
25
+ export declare const BROWSER_READ_MAX_OFFSET = 1000000;
26
+ /**
27
+ * What a request may name as a field of the route's table (C1):
28
+ * - `columns`: the columns the export knows the table has (its schema in the
29
+ * data source config, plus every field the project's own bindings of the
30
+ * table name), or null for a source that has none to know (REST,
31
+ * JavaScript, CSV, Google Sheets, Redis: they filter in memory);
32
+ * - `virtualFields` / `virtualPrefixes`: the names the route itself answers
33
+ * with an expression (the products' effective price, rating, variant axes);
34
+ * - `documentStore`: a store that reads a `$`-key as an operator or a dotted
35
+ * key as a path (MongoDB, Firestore, Redis).
36
+ * A table with a schema but no known column answers every named field 400.
37
+ */
38
+ export interface RequestFieldPolicy {
39
+ columns: string[] | null;
40
+ virtualFields?: string[];
41
+ virtualPrefixes?: string[];
42
+ documentStore?: boolean;
43
+ /** The shape every named field must also have (a driver's identifier or label rule). */
44
+ pattern?: RegExp;
45
+ }
46
+ /** A column of `config.selectedTables[tableName]`: its name, and its type when the config gives one. */
47
+ export interface SchemaColumn {
48
+ name: string;
49
+ type?: string;
50
+ }
51
+ /** The columns `config.selectedTables[tableName]` lists, with their types, or null when the config holds no schema for it. */
52
+ export declare const schemaOf: (config: unknown, tableName: string) => SchemaColumn[] | null;
53
+ /** The columns `config.selectedTables[tableName]` lists, or null when the config holds no schema for it. */
54
+ export declare const schemaColumnsOf: (config: unknown, tableName: string) => string[] | null;
55
+ /**
56
+ * The exposure check, the row window and the request-field check, for a
57
+ * module whose table is `exposure`'s. Uses `__taIsInternalRequest`,
58
+ * `__taRoleOf` and `__tqSessionToken` from the preamble.
59
+ */
60
+ export declare const generateRouteExposureCode: (exposure: DataReadExposure | null | undefined, fieldPolicy?: RequestFieldPolicy, tableName?: string) => string;
61
+ /**
62
+ * Where a read route sits and what its session reader checks (see
63
+ * `EntityTransformOptions.routeProjectRoot` / `.sessionRevocation`).
64
+ */
65
+ export interface SessionReaderPlacement {
66
+ /** The route's path back to the project root; absent, two folders. */
67
+ routeProjectRoot?: string;
68
+ /** The project has authentication; absent, the reader checks revocation. */
69
+ sessionRevocation?: boolean;
70
+ }
71
+ /**
72
+ * Declares the session resolver, the `__ta*` guard and the route's exposure
73
+ * once per module.
14
74
  */
15
- /** Declares the session resolver and the `__ta*` guard once per module. */
16
- export declare const generateTableAccessPreamble: (trustedReaderRoles: ReadonlyArray<string>) => string;
75
+ export declare const generateTableAccessPreamble: (trustedReaderRoles: ReadonlyArray<string>, exposure?: DataReadExposure | null, fieldPolicy?: RequestFieldPolicy, tableName?: string, reader?: SessionReaderPlacement) => string;
76
+ /** The products table's virtual filter and sort fields (`product-filter-fields.ts`, `product-price-sort.ts`). */
77
+ export declare const PRODUCT_VIRTUAL_FIELDS: string[];
78
+ export declare const PRODUCT_VIRTUAL_PREFIXES: string[];
79
+ /** What a TeleportHQ / Postgres route's request may name: its schema, plus the products' virtual fields. */
80
+ export declare const sqlRouteFieldPolicy: (config: unknown, tableName: string) => RequestFieldPolicy;
17
81
  /**
18
82
  * The early return at the top of a handler, before the client connects:
19
83
  * `tableName` is the module's table, `rawQueryExpr` the request's raw statement
@@ -1 +1 @@
1
- {"version":3,"file":"table-access-guard.d.ts","sourceRoot":"","sources":["../../../../src/fetchers/utils/table-access-guard.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,uBAAwB,cAAc,MAAM,CAAC,KAAG,MAIvF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,cAAe,MAAM,gBAAgB,MAAM,GAAG,IAAI,KAAG,MAQtF,CAAA"}
1
+ {"version":3,"file":"table-access-guard.d.ts","sourceRoot":"","sources":["../../../../src/fetchers/utils/table-access-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAIlE;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,UAAU,CAAA;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wGAAwG;AACxG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,8HAA8H;AAC9H,eAAO,MAAM,QAAQ,WAAY,OAAO,aAAa,MAAM,KAAG,YAAY,EAAE,GAAG,IAwB9E,CAAA;AAED,4GAA4G;AAC5G,eAAO,MAAM,eAAe,WAAY,OAAO,aAAa,MAAM,KAAG,MAAM,EAAE,GAAG,IAG/E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,aAC1B,gBAAgB,GAAG,IAAI,GAAG,SAAS,gBAChC,kBAAkB,cACpB,MAAM,KAChB,MAuTF,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,uBAClB,cAAc,MAAM,CAAC,aAC9B,gBAAgB,GAAG,IAAI,gBACpB,kBAAkB,cACpB,MAAM,WACV,sBAAsB,KAC7B,MAUF,CAAA;AAED,iHAAiH;AACjH,eAAO,MAAM,sBAAsB,UAA8C,CAAA;AACjF,eAAO,MAAM,wBAAwB,UAAuB,CAAA;AAE5D,4GAA4G;AAC5G,eAAO,MAAM,mBAAmB,WAAY,OAAO,aAAa,MAAM,KAAG,kBASxE,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,cAAe,MAAM,gBAAgB,MAAM,GAAG,IAAI,KAAG,MAqBtF,CAAA"}