@teleporthq/teleport-plugin-next-data-source 0.44.15 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.guardExternalDriverCount = exports.guardExternalDriverModule = exports.defaultSearchColumns = exports.driverFieldPolicy = exports.requestFieldRuleOf = void 0;
15
+ var teleport_shared_1 = require("@teleporthq/teleport-shared");
16
+ var table_access_guard_1 = require("./table-access-guard");
17
+ /**
18
+ * A SQL column: plain, quoted or table-qualified — what the Postgres routes
19
+ * accept (`request-sql-guards.ts`).
20
+ */
21
+ var IDENTIFIER_FIELD_RE = /^"?[A-Za-z_][A-Za-z0-9_]*"?(?:\."?[A-Za-z_][A-Za-z0-9_]*"?)?$/;
22
+ /**
23
+ * A field of a document store or a base whose names are labels: anything but
24
+ * the characters its query language gives a meaning (`{}` closes an Airtable
25
+ * field reference, `$` opens a MongoDB operator, quotes and parentheses open
26
+ * literals and calls).
27
+ */
28
+ var LABEL_FIELD_RE = /^[^{}'"`\\(),;$]{1,128}$/;
29
+ /** SQL drivers splice the field into their statement; document stores read it as a path or an operator. */
30
+ var requestFieldRuleOf = function (dataSourceType) {
31
+ switch (dataSourceType) {
32
+ case 'mysql':
33
+ case 'tidb':
34
+ case 'mariadb':
35
+ case 'amazon-redshift':
36
+ case 'clickhouse':
37
+ case 'turso':
38
+ case 'supabase':
39
+ return 'identifier';
40
+ case 'mongodb':
41
+ case 'firestore':
42
+ case 'airtable':
43
+ return 'label';
44
+ default:
45
+ // REST, JavaScript, CSV, Google Sheets, Redis filter the rows in memory.
46
+ return 'any';
47
+ }
48
+ };
49
+ exports.requestFieldRuleOf = requestFieldRuleOf;
50
+ /** The stores that read a `$`-key as an operator or a dotted key as a path. */
51
+ var DOCUMENT_STORES = new Set(['mongodb', 'firestore', 'redis']);
52
+ /**
53
+ * What a request may name for a driver (see `RequestFieldPolicy`): the
54
+ * export's schema of the table — required for a SQL driver, so a table without
55
+ * one answers every named field 400 — and the driver's own shape rule.
56
+ */
57
+ var driverFieldPolicy = function (dataSourceType, schemaColumns) {
58
+ var rule = (0, exports.requestFieldRuleOf)(dataSourceType);
59
+ 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 }));
60
+ };
61
+ exports.driverFieldPolicy = driverFieldPolicy;
62
+ /**
63
+ * The stores whose search turns the text into a pattern of their own query
64
+ * language (MongoDB's `$regex`): the text is escaped first, so it is matched
65
+ * as text — never an anchored, character-by-character probe, never a pattern
66
+ * that takes the server's time.
67
+ */
68
+ var PATTERN_SEARCH_STORES = new Set(['mongodb']);
69
+ /** A text type, as the sources name theirs (`text`, `varchar(255)`, `character varying`, `string`). */
70
+ var TEXT_COLUMN_TYPE = /char|text|string|clob|enum/i;
71
+ /**
72
+ * The columns a browser's search runs over when it names none (N3): the
73
+ * table's schema — for Supabase, whose PostgREST `ilike` refuses any other
74
+ * type, its text columns — else, for a source without one, the fields the
75
+ * project's own bindings read. Never a credential column: what a search
76
+ * matches, it lets the searcher test character by character.
77
+ */
78
+ var defaultSearchColumns = function (dataSourceType, schema, bindingFields) {
79
+ var textOnly = dataSourceType === 'supabase';
80
+ var candidates = schema
81
+ ? schema
82
+ .filter(function (column) { return !textOnly || !column.type || TEXT_COLUMN_TYPE.test(column.type); })
83
+ .map(function (column) { return column.name; })
84
+ : bindingFields;
85
+ return Array.from(new Set(candidates)).filter(function (name) { return !teleport_shared_1.TableAccess.isCredentialColumnName(name); });
86
+ };
87
+ exports.defaultSearchColumns = defaultSearchColumns;
88
+ /** The guard's own code, after the shared preamble. */
89
+ 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(teleport_shared_1.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"); };
90
+ var UNGUARDED_HANDLER = '__tqUnguardedHandler';
91
+ var UNGUARDED_COUNT = '__tqUnguardedGetCount';
92
+ var DRIVER_HANDLER_DECLARATION = 'export default async function handler(';
93
+ var COUNT_DECLARATION = 'async function getCount(req, res)';
94
+ /** The driver module's single-line imports, which must stay at the top of an ES module. */
95
+ var IMPORT_LINE = /^import\s.*$/gm;
96
+ /**
97
+ * The driver's fetcher module with the guard around its handler: same
98
+ * imports, the preamble, the driver renamed, and a guarded `handler` exported
99
+ * in its place.
100
+ */
101
+ var guardExternalDriverModule = function (driverCode, params) {
102
+ var _a;
103
+ var schema = (_a = params.schema) !== null && _a !== void 0 ? _a : null;
104
+ var schemaColumns = schema ? schema.map(function (column) { return column.name; }) : null;
105
+ if (driverCode.split(DRIVER_HANDLER_DECLARATION).length !== 2) {
106
+ // A driver that is not one handler cannot be wrapped; refusing to generate
107
+ // it is the only answer that does not serve it unguarded.
108
+ throw new Error('a data source read route must declare exactly one handler');
109
+ }
110
+ var imports = driverCode.match(IMPORT_LINE) || [];
111
+ var body = driverCode
112
+ .replace(IMPORT_LINE, '')
113
+ .trim()
114
+ .replace(DRIVER_HANDLER_DECLARATION, "async function ".concat(UNGUARDED_HANDLER, "("));
115
+ return "".concat(imports.join('\n'), "\n\n").concat((0, table_access_guard_1.generateTableAccessPreamble)(params.trustedReaderRoles, params.exposure, (0, exports.driverFieldPolicy)(params.dataSourceType, schemaColumns), params.tableName, params.reader)).concat(generateDriverGuardCode(params.tableName, params.dataSourceType, (0, exports.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");
116
+ };
117
+ exports.guardExternalDriverModule = guardExternalDriverModule;
118
+ /** The driver's count handler behind the same guard (the guard code comes with the handler module). */
119
+ var guardExternalDriverCount = function (countCode) {
120
+ if (countCode.split(COUNT_DECLARATION).length !== 2) {
121
+ throw new Error('a data source count route must declare exactly one getCount');
122
+ }
123
+ 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");
124
+ };
125
+ exports.guardExternalDriverCount = guardExternalDriverCount;
126
+ //# 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":";;;;;;;;;;;;;;AACA,+DAAuE;AACvE,2DAK6B;AAqB7B;;;GAGG;AACH,IAAM,mBAAmB,GAAG,+DAA+D,CAAA;AAE3F;;;;;GAKG;AACH,IAAM,cAAc,GAAG,0BAA0B,CAAA;AAEjD,2GAA2G;AACpG,IAAM,kBAAkB,GAAG,UAAC,cAAsB;IACvD,QAAQ,cAAc,EAAE;QACtB,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,SAAS,CAAC;QACf,KAAK,iBAAiB,CAAC;QACvB,KAAK,YAAY,CAAC;QAClB,KAAK,OAAO,CAAC;QACb,KAAK,UAAU;YACb,OAAO,YAAY,CAAA;QACrB,KAAK,SAAS,CAAC;QACf,KAAK,WAAW,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,OAAO,CAAA;QAChB;YACE,yEAAyE;YACzE,OAAO,KAAK,CAAA;KACf;AACH,CAAC,CAAA;AAlBY,QAAA,kBAAkB,sBAkB9B;AAED,+EAA+E;AAC/E,IAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAA;AAElE;;;;GAIG;AACI,IAAM,iBAAiB,GAAG,UAC/B,cAAsB,EACtB,aAA8B;IAE9B,IAAM,IAAI,GAAG,IAAA,0BAAkB,EAAC,cAAc,CAAC,CAAA;IAC/C,2BACE,OAAO,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC,aAAa,EACpE,aAAa,EAAE,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC,IAC/C,CAAC,IAAI,KAAK,YAAY,IAAI,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,GAC3D,CAAC,IAAI,KAAK,OAAO,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EACrD;AACH,CAAC,CAAA;AAXY,QAAA,iBAAiB,qBAW7B;AAED;;;;;GAKG;AACH,IAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;AAElD,uGAAuG;AACvG,IAAM,gBAAgB,GAAG,6BAA6B,CAAA;AAEtD;;;;;;GAMG;AACI,IAAM,oBAAoB,GAAG,UAClC,cAAsB,EACtB,MAA6B,EAC7B,aAAuB;IAEvB,IAAM,QAAQ,GAAG,cAAc,KAAK,UAAU,CAAA;IAC9C,IAAM,UAAU,GAAG,MAAM;QACvB,CAAC,CAAC,MAAM;aACH,MAAM,CAAC,UAAC,MAAM,IAAK,OAAA,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAA/D,CAA+D,CAAC;aACnF,GAAG,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,CAAC,IAAI,EAAX,CAAW,CAAC;QACjC,CAAC,CAAC,aAAa,CAAA;IACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAC,IAAI,IAAK,OAAA,CAAC,6BAAW,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAzC,CAAyC,CAAC,CAAA;AACpG,CAAC,CAAA;AAZY,QAAA,oBAAoB,wBAYhC;AAED,uDAAuD;AACvD,IAAM,uBAAuB,GAAG,UAC9B,SAAiB,EACjB,cAAsB,EACtB,aAAuB,IACZ,OAAA,yHAEa,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,oHAEpB,8BAAY,CAAC,qBAAqB,0LAG9B,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,iDAC7B,qBAAqB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,m1HAsF9F,EA9FY,CA8FZ,CAAA;AAED,IAAM,iBAAiB,GAAG,sBAAsB,CAAA;AAChD,IAAM,eAAe,GAAG,uBAAuB,CAAA;AAC/C,IAAM,0BAA0B,GAAG,wCAAwC,CAAA;AAC3E,IAAM,iBAAiB,GAAG,mCAAmC,CAAA;AAE7D,2FAA2F;AAC3F,IAAM,WAAW,GAAG,gBAAgB,CAAA;AAEpC;;;;GAIG;AACI,IAAM,yBAAyB,GAAG,UACvC,UAAkB,EAClB,MASC;;IAED,IAAM,MAAM,GAAG,MAAA,MAAM,CAAC,MAAM,mCAAI,IAAI,CAAA;IACpC,IAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,CAAC,IAAI,EAAX,CAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACzE,IAAI,UAAU,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;QAC7D,2EAA2E;QAC3E,0DAA0D;QAC1D,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAA;KAC7E;IACD,IAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;IACnD,IAAM,IAAI,GAAG,UAAU;SACpB,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;SACxB,IAAI,EAAE;SACN,OAAO,CAAC,0BAA0B,EAAE,yBAAkB,iBAAiB,MAAG,CAAC,CAAA;IAE9E,OAAO,UAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iBAE5B,IAAA,gDAA2B,EAC3B,MAAM,CAAC,kBAAkB,EACzB,MAAM,CAAC,QAAQ,EACf,IAAA,yBAAiB,EAAC,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,EACvD,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,MAAM,CACd,SAAG,uBAAuB,CACvB,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,cAAc,EACrB,IAAA,4BAAoB,EAAC,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAClF,eACD,IAAI,6GAGqC,iBAAiB,mBAE3D,CAAA;AACD,CAAC,CAAA;AA7CY,QAAA,yBAAyB,6BA6CrC;AAED,uGAAuG;AAChG,IAAM,wBAAwB,GAAG,UAAC,SAAiB;IACxD,IAAI,SAAS,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE;QACnD,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;KAC/E;IACD,OAAO,UAAG,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,yBAAkB,eAAe,eAAY,CAAC,+FAGpD,eAAe,oBAEzD,CAAA;AACD,CAAC,CAAA;AAVY,QAAA,wBAAwB,4BAUpC"}
@@ -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"}
@@ -1,34 +1,142 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
+ if (ar || !(i in from)) {
16
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
+ ar[i] = from[i];
18
+ }
19
+ }
20
+ return to.concat(ar || Array.prototype.slice.call(from));
21
+ };
2
22
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateReadGuardCall = exports.generateTableAccessPreamble = void 0;
23
+ exports.generateReadGuardCall = exports.sqlRouteFieldPolicy = exports.PRODUCT_VIRTUAL_PREFIXES = exports.PRODUCT_VIRTUAL_FIELDS = exports.generateTableAccessPreamble = exports.generateRouteExposureCode = exports.schemaColumnsOf = exports.schemaOf = exports.BROWSER_READ_MAX_OFFSET = void 0;
4
24
  var teleport_shared_1 = require("@teleporthq/teleport-shared");
5
25
  var browser_row_policy_1 = require("./browser-row-policy");
6
26
  /**
7
- * The money-table guard for a generated per-table read route
27
+ * The guard of a generated per-table read route
8
28
  * (`/api/teleport-<table>-<source>` and its `-count` twin).
9
29
  *
10
- * Every table a page binds gets such a route, and the route serves the whole
11
- * table — plus any single SELECT through `?rawQuery=` — to whoever asks. For a
12
- * catalogue that is the product; for gift cards and voucher codes it is theft.
13
- * The guard refuses a protected table (see `TableAccess.PROTECTED_TABLES`)
14
- * unless the caller is a server segment presenting the app secret or a
15
- * signed-in member of a trusted role — the generated admin, whose list pages
16
- * are the one browser reader these tables have. It is followed by the
17
- * browser row policy (see `browser-row-policy.ts`): unpublished rows and
18
- * private columns of the public tables, and the admin-only tables.
30
+ * Every table a page binds gets such a route, and the route is a URL anyone
31
+ * can call. Three nets, in this order:
32
+ * 1. the table's EXPOSURE, decided at export time from the pages that bind it
33
+ * (`DataExposure.resolveDataExposure`): a table a public page shows is read
34
+ * by anyone; one only protected pages bind needs a session one of them
35
+ * admits; one no page binds is the app's own server code's;
36
+ * 2. the protected tables (see `TableAccess.PROTECTED_TABLES`): money and
37
+ * customer records, read only by a server segment presenting the app
38
+ * secret or a signed-in member of a trusted role (the generated admin);
39
+ * 3. the browser row policy (see `browser-row-policy.ts`): unpublished rows
40
+ * and private columns of the public tables.
41
+ * A server-side caller (the app secret, or the module's own in-process
42
+ * `fetchData`) passes all three.
43
+ *
44
+ * Every row count a request names is a whole number, and a browser's read is
45
+ * capped (`__taReadWindow`): a missing count gets the table's default, a large
46
+ * one the table's maximum.
19
47
  */
20
- /** Declares the session resolver and the `__ta*` guard once per module. */
21
- var generateTableAccessPreamble = function (trustedReaderRoles) {
22
- return "".concat(teleport_shared_1.SessionCookieResolver.generateCommonJsSessionTokenResolverCode(), "\n").concat(teleport_shared_1.TableAccess.generateTableAccessHelperCode({ trustedReaderRoles: trustedReaderRoles }), "\n").concat((0, browser_row_policy_1.generateBrowserRowPolicyCode)());
48
+ /** No route reads more than this many rows past the first, from a browser. */
49
+ exports.BROWSER_READ_MAX_OFFSET = 1000000;
50
+ /** The columns `config.selectedTables[tableName]` lists, with their types, or null when the config holds no schema for it. */
51
+ var schemaOf = function (config, tableName) {
52
+ var selected = config === null || config === void 0 ? void 0 : config.selectedTables;
53
+ if (!selected || typeof selected !== 'object') {
54
+ return null;
55
+ }
56
+ var bare = teleport_shared_1.DataExposure.bareTableName(tableName);
57
+ var table = selected[tableName] ||
58
+ Object.keys(selected)
59
+ .filter(function (key) { return teleport_shared_1.DataExposure.bareTableName(key) === bare; })
60
+ .map(function (key) { return selected[key]; })[0];
61
+ if (!table || !Array.isArray(table.columns)) {
62
+ return null;
63
+ }
64
+ return table.columns
65
+ .filter(function (column) { return column && typeof column.name === 'string' && column.name.length > 0; })
66
+ .map(function (column) { return (__assign({ name: column.name }, (typeof column.type === 'string' && { type: column.type }))); });
67
+ };
68
+ exports.schemaOf = schemaOf;
69
+ /** The columns `config.selectedTables[tableName]` lists, or null when the config holds no schema for it. */
70
+ var schemaColumnsOf = function (config, tableName) {
71
+ var schema = (0, exports.schemaOf)(config, tableName);
72
+ return schema ? schema.map(function (column) { return column.name; }) : null;
73
+ };
74
+ exports.schemaColumnsOf = schemaColumnsOf;
75
+ /**
76
+ * The exposure check, the row window and the request-field check, for a
77
+ * module whose table is `exposure`'s. Uses `__taIsInternalRequest`,
78
+ * `__taRoleOf` and `__tqSessionToken` from the preamble.
79
+ */
80
+ var generateRouteExposureCode = function (exposure, fieldPolicy, tableName) {
81
+ if (fieldPolicy === void 0) { fieldPolicy = { columns: [] }; }
82
+ if (tableName === void 0) { tableName = ''; }
83
+ var routeExposure = exposure || teleport_shared_1.DataExposure.CLOSED_READ_EXPOSURE;
84
+ var subscriberRules = routeExposure.subscriberRules || [];
85
+ var ownerRules = routeExposure.ownerRules || [];
86
+ var knownColumns = fieldPolicy.columns === null
87
+ ? null
88
+ : Array.from(new Set(__spreadArray(__spreadArray([], fieldPolicy.columns, true), (routeExposure.fields || []), true).map(function (column) {
89
+ return String(column).toLowerCase();
90
+ }))).sort();
91
+ return "// GENERATED \u2014 see generateRouteExposureCode in teleport-plugin-next-data-source.\n// Who may read this route's table from a browser, decided at export time from\n// the pages that bind it: anyone when a page every visitor may open does;\n// otherwise a session one of the binding pages admits \u2014 with an entitled\n// subscription, when that page is subscriber-only. The app's own server code\n// always may.\nvar __TA_ROUTE_EXPOSURE = ".concat(JSON.stringify({
92
+ public: routeExposure.public === true,
93
+ anySession: routeExposure.anySession === true,
94
+ roles: routeExposure.roles || [],
95
+ subscriberRules: subscriberRules,
96
+ ownerRules: ownerRules,
97
+ defaultLimit: routeExposure.defaultLimit,
98
+ maxLimit: routeExposure.maxLimit,
99
+ }), ";\nvar __TA_MAX_OFFSET = ").concat(exports.BROWSER_READ_MAX_OFFSET, ";\nvar __TA_ROUTE_TABLE = ").concat(JSON.stringify(teleport_shared_1.DataExposure.bareTableName(tableName)), ";\n// The fields a request may name (see RequestFieldPolicy): null columns = a source\n// without a schema, checked for shape only.\nvar __TA_FIELD_POLICY = ").concat(JSON.stringify({
100
+ columns: knownColumns,
101
+ virtualFields: (fieldPolicy.virtualFields || []).map(function (field) { return field.toLowerCase(); }),
102
+ virtualPrefixes: (fieldPolicy.virtualPrefixes || []).map(function (prefix) { return prefix.toLowerCase(); }),
103
+ documentStore: fieldPolicy.documentStore === true,
104
+ }), ";\nvar __TA_FIELD_PATTERN = ").concat(fieldPolicy.pattern ? fieldPolicy.pattern.toString() : 'null', ";\n").concat(subscriberRules.length > 0 ? teleport_shared_1.DataExposure.generateEntitlementCheckCode() : '', "\n// null when the request may read the table, else { status, message }.\nasync function __taGuardExposure(req) {\n if (__TA_ROUTE_EXPOSURE.public === true) return null;\n if (__taIsInternalRequest(req)) return null;\n // A page's own data, read in-process to render it (`fetchData(params, { as:\n // 'visitor' })`): the page's access guard already admitted whoever opened it,\n // and the read is served as an anonymous visitor's (__taGuardRead, the row\n // policy). It carries no session to check here \u2014 a protected page would\n // otherwise render nothing.\n if (__taIsVisitorView(req)) return null;\n // No page binds the table: no session could read it from a browser.\n if (\n __TA_ROUTE_EXPOSURE.anySession !== true &&\n __TA_ROUTE_EXPOSURE.roles.length === 0 &&\n __TA_ROUTE_EXPOSURE.subscriberRules.length === 0 &&\n __TA_ROUTE_EXPOSURE.ownerRules.length === 0\n ) {\n return { status: 403, message: 'Forbidden' };\n }\n var token = null;\n try {\n token = await __tqSessionToken(req);\n } catch (e) {\n token = null;\n }\n if (!token) return { status: 401, message: 'Unauthenticated' };\n if (__TA_ROUTE_EXPOSURE.anySession === true) return null;\n var role = __taRoleOf(token);\n if (role && __TA_ROUTE_EXPOSURE.roles.indexOf(role) !== -1) return null;\n // A row-owned page: the session reads its own rows only \u2014 the condition is\n // added to the read by the server (__taApplyOwnerScope).\n if (__TA_ROUTE_EXPOSURE.ownerRules.length > 0) {\n var ownerId = token.id || token.sub;\n if (!ownerId) return { status: 403, message: 'Forbidden' };\n req.__tqOwnerScope = { userId: String(ownerId) };\n return null;\n }\n // A subscriber-only page that admits the session: the products its rules\n // name (any product when one rule names none).\n var products = null;\n for (var i = 0; i < __TA_ROUTE_EXPOSURE.subscriberRules.length; i++) {\n var rule = __TA_ROUTE_EXPOSURE.subscriberRules[i];\n if (rule.roles.length > 0 && (!role || rule.roles.indexOf(role) === -1)) continue;\n products = rule.productIds.length === 0 || (products && products.length === 0)\n ? []\n : (products || []).concat(rule.productIds);\n }\n if (products && (await __dxEntitled(token, products))) return null;\n return { status: 403, message: 'Forbidden' };\n}\n\nfunction __taRefuseRequest(label) {\n var err = new Error('Invalid ' + label);\n err.status = 400;\n throw err;\n}\n\n// A row count from the request: a whole number, or nothing. Anything else\n// (`1;--`, `1 OR 1=1`, `-5`, `1e9`) is refused, never parsed into one.\nfunction __taWholeNumber(value, label) {\n if (Array.isArray(value)) value = value[0];\n if (value === undefined || value === null || value === '') return undefined;\n var text = String(value).trim();\n if (!/^[0-9]{1,15}$/.test(text)) __taRefuseRequest(label);\n return parseInt(text, 10);\n}\n\n// The rows a read may ask for. A server-side caller gets what it names; a\n// browser gets the table's default when it names no count, never more than the\n// table's maximum, and starts no further in than __TA_MAX_OFFSET.\nfunction __taReadWindow(req) {\n var q = (req && req.query) || {};\n var limit = __taWholeNumber(q.limit, 'limit');\n var perPage = __taWholeNumber(q.perPage, 'perPage');\n var page = __taWholeNumber(q.page, 'page');\n var offset = __taWholeNumber(q.offset, 'offset');\n if (!__taIsInternalRequest(req)) {\n var max = __TA_ROUTE_EXPOSURE.maxLimit;\n if (limit !== undefined) limit = Math.min(limit, max);\n if (perPage !== undefined) perPage = Math.min(perPage, max);\n if (!limit && !perPage) limit = __TA_ROUTE_EXPOSURE.defaultLimit;\n if (offset !== undefined) offset = Math.min(offset, __TA_MAX_OFFSET);\n if (page !== undefined) {\n page = Math.max(1, Math.min(page, Math.floor(__TA_MAX_OFFSET / Math.max(perPage || 1, 1)) + 1));\n }\n }\n return { limit: limit, perPage: perPage, page: page, offset: offset };\n}\n\n// The parsed value of a JSON request parameter: undefined when absent, and a\n// refusal when it is text that is not JSON (a driver would read it char by char).\nfunction __taJsonParam(value, label) {\n if (value === undefined || value === null || value === '') return undefined;\n if (Array.isArray(value)) __taRefuseRequest(label);\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch (e) {\n __taRefuseRequest(label);\n }\n}\n\n// Every field a filter names, in every shape the drivers accept\n// (normalizeFilterTree): a list of conditions and groups, or an object whose\n// KEYS are the fields. `values` collects what each field is compared with.\nfunction __taFilterFields(parsed, out, values) {\n if (parsed === undefined) return out;\n if (Array.isArray(parsed)) {\n for (var i = 0; i < parsed.length; i++) __taFilterNodeFields(parsed[i], out, values);\n return out;\n }\n if (parsed && typeof parsed === 'object') {\n Object.keys(parsed).forEach(function(key) {\n out.push(key);\n values.push(parsed[key]);\n });\n return out;\n }\n __taRefuseRequest('filters');\n}\n\nfunction __taFilterNodeFields(entry, out, values) {\n if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return;\n if (entry.type === 'group') {\n var children = Array.isArray(entry.children) ? entry.children : [];\n for (var i = 0; i < children.length; i++) __taFilterNodeFields(children[i], out, values);\n return;\n }\n if (entry.source !== undefined) {\n out.push(entry.source);\n values.push(entry.destination);\n }\n}\n\n// What a document store compares a field with: a plain value, or a list of\n// plain values (an \"in\" filter). An object would reach the store as an\n// operator (`{ \"$ne\": null }`, `{ \"$regex\": \u2026 }`) and widen the read.\nfunction __taAssertPlainValue(value) {\n if (value === null || value === undefined) return;\n var type = typeof value;\n if (type === 'string' || type === 'number' || type === 'boolean') return;\n if (Array.isArray(value)) {\n for (var i = 0; i < value.length; i++) {\n if (value[i] !== null && typeof value[i] === 'object') __taRefuseRequest('filters');\n }\n return;\n }\n __taRefuseRequest('filters');\n}\n\n// The columns a request's projection names (`select`, which Supabase hands\n// PostgREST): the bare star, or a comma list of plain column names. An alias\n// (`name:password`), a cast or an embedded table (`users(email)`) is\n// refused \u2014 it reads a column under another name, or a table no page binds.\nfunction __taSelectFields(select) {\n if (select === undefined || select === null || select === '') return [];\n if (typeof select !== 'string') __taRefuseRequest('select');\n var text = select.trim();\n if (text === '*') return [];\n var parts = text.split(',');\n var out = [];\n for (var i = 0; i < parts.length; i++) {\n var name = parts[i].trim();\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) __taRefuseRequest('select');\n out.push(name);\n }\n return out;\n}\n\nvar __TA_UNSAFE_KEYS = ['__proto__', 'constructor', 'prototype'];\n\n// One field a request names: a column the export knows for the table (or a\n// field the route answers itself), of a safe shape, and \u2014 for a browser \u2014\n// never a credential column.\nfunction __taAssertField(field, browser) {\n if (typeof field !== 'string' || field.length === 0 || field.length > 128) __taRefuseRequest('field');\n if (field.charAt(0) === '$' || __TA_UNSAFE_KEYS.indexOf(field) !== -1) __taRefuseRequest('field');\n if (__TA_FIELD_POLICY.documentStore && field.indexOf('.') !== -1) __taRefuseRequest('field');\n if (__TA_FIELD_PATTERN && !__TA_FIELD_PATTERN.test(field)) __taRefuseRequest('field');\n var name = field.replace(/\"/g, '').toLowerCase();\n if (browser) {\n var column = name.split('.').pop();\n if (__taIsCredentialColumn(column)) __taRefuseRequest('field');\n }\n if (__TA_FIELD_POLICY.columns === null) return;\n if (__TA_FIELD_POLICY.virtualFields.indexOf(name) !== -1) return;\n for (var i = 0; i < __TA_FIELD_POLICY.virtualPrefixes.length; i++) {\n if (name.indexOf(__TA_FIELD_POLICY.virtualPrefixes[i]) === 0) return;\n }\n var parts = name.split('.');\n if (parts.length > 2) __taRefuseRequest('field');\n if (parts.length === 2 && parts[0] !== __TA_ROUTE_TABLE) __taRefuseRequest('field');\n if (__TA_FIELD_POLICY.columns.indexOf(parts[parts.length - 1]) === -1) __taRefuseRequest('field');\n}\n\n// A sort order: ascending or descending, or none.\nfunction __taAssertOrder(order) {\n if (order === undefined || order === null || order === '') return;\n if (typeof order !== 'string' || !/^(asc|desc)$/i.test(order)) __taRefuseRequest('sort order');\n}\n\n// Every field a request filters, sorts or searches by, checked before any\n// driver call: one sort field with asc|desc, no repeated parameter.\nfunction __taAssertReadRequest(req) {\n var q = (req && req.query) || {};\n var browser = !__taIsInternalRequest(req);\n var values = [];\n var fields = __taFilterFields(__taJsonParam(q.filters, 'filters'), [], values);\n if (__TA_FIELD_POLICY.documentStore) {\n for (var v = 0; v < values.length; v++) __taAssertPlainValue(values[v]);\n }\n fields = fields.concat(__taSelectFields(q.select));\n var sorts = __taJsonParam(q.sorts, 'sorts');\n if (sorts !== undefined) {\n if (!Array.isArray(sorts) || sorts.length > 1) __taRefuseRequest('sorts');\n for (var i = 0; i < sorts.length; i++) {\n if (!sorts[i] || typeof sorts[i] !== 'object') __taRefuseRequest('sorts');\n fields.push(sorts[i].field);\n __taAssertOrder(sorts[i].order);\n }\n }\n if (q.sortBy !== undefined && q.sortBy !== '') {\n if (typeof q.sortBy !== 'string') __taRefuseRequest('sortBy');\n fields.push(q.sortBy);\n }\n if (Array.isArray(q.sortOrder)) __taRefuseRequest('sortOrder');\n __taAssertOrder(q.sortOrder);\n var queryColumns = q.queryColumns;\n if (typeof queryColumns === 'string' && queryColumns.length > 0 && queryColumns.charAt(0) !== '[' && queryColumns.charAt(0) !== '\"') {\n queryColumns = JSON.stringify(queryColumns);\n }\n var searchColumns = __taJsonParam(queryColumns, 'queryColumns');\n if (searchColumns !== undefined) {\n var list = Array.isArray(searchColumns) ? searchColumns : [searchColumns];\n for (var c = 0; c < list.length; c++) fields.push(list[c]);\n }\n for (var f = 0; f < fields.length; f++) __taAssertField(fields[f], browser);\n}\n\n// A row-owned page's read (see __taGuardExposure): the owner condition joins\n// whatever the request filters by, so no filter can widen it.\nfunction __taApplyOwnerScope(req) {\n var scope = req && req.__tqOwnerScope;\n if (!scope) return req;\n var q = (req && req.query) || {};\n var parsed = __taJsonParam(q.filters, 'filters');\n var original = Array.isArray(parsed)\n ? parsed\n : parsed && typeof parsed === 'object'\n ? Object.keys(parsed).map(function(key) { return { source: key, destination: parsed[key], operand: '=' }; })\n : [];\n var owners = __TA_ROUTE_EXPOSURE.ownerRules.map(function(rule) {\n return { type: 'condition', source: rule.column, destination: scope.userId, operand: '=' };\n });\n var tree = [{ type: 'group', operator: 'or', children: owners }];\n if (original.length > 0) tree.push({ type: 'group', operator: 'and', children: original });\n req.query = Object.assign({}, q, { filters: JSON.stringify(tree) });\n return req;\n}\n\n// An opaque reference for a refused read: the client gets it, the server log\n// gets the detail under the same reference.\nfunction __taErrorId() {\n try {\n return require('crypto').randomBytes(8).toString('hex');\n } catch (e) {\n return Math.floor(Math.random() * 0xffffffff).toString(16);\n }\n}\n");
105
+ };
106
+ exports.generateRouteExposureCode = generateRouteExposureCode;
107
+ /**
108
+ * Declares the session resolver, the `__ta*` guard and the route's exposure
109
+ * once per module.
110
+ */
111
+ var generateTableAccessPreamble = function (trustedReaderRoles, exposure, fieldPolicy, tableName, reader) {
112
+ if (reader === void 0) { reader = {}; }
113
+ // The fetcher lives in utils/data-sources/ or pages/api/ (two folders below
114
+ // the root) unless the caller says otherwise (pages/api/global-state/).
115
+ var projectRoot = reader.routeProjectRoot || '../..';
116
+ return "".concat(teleport_shared_1.SessionCookieResolver.generateCommonJsSessionTokenResolverCode(projectRoot, {
117
+ withRevocation: reader.sessionRevocation !== false,
118
+ }), "\n").concat(teleport_shared_1.TableAccess.generateTableAccessHelperCode({ trustedReaderRoles: trustedReaderRoles, projectRoot: projectRoot }), "\n").concat((0, browser_row_policy_1.generateBrowserRowPolicyCode)(), "\n").concat((0, exports.generateRouteExposureCode)(exposure, fieldPolicy, tableName || ''));
23
119
  };
24
120
  exports.generateTableAccessPreamble = generateTableAccessPreamble;
121
+ /** The products table's virtual filter and sort fields (`product-filter-fields.ts`, `product-price-sort.ts`). */
122
+ exports.PRODUCT_VIRTUAL_FIELDS = ['rating', 'on_sale', 'price', 'discounts'];
123
+ exports.PRODUCT_VIRTUAL_PREFIXES = ['variant_options.'];
124
+ /** What a TeleportHQ / Postgres route's request may name: its schema, plus the products' virtual fields. */
125
+ var sqlRouteFieldPolicy = function (config, tableName) {
126
+ var products = teleport_shared_1.DataExposure.bareTableName(tableName) === 'teleport_products';
127
+ return __assign({ columns: (0, exports.schemaColumnsOf)(config, tableName) || [] }, (products && {
128
+ virtualFields: exports.PRODUCT_VIRTUAL_FIELDS,
129
+ virtualPrefixes: exports.PRODUCT_VIRTUAL_PREFIXES,
130
+ }));
131
+ };
132
+ exports.sqlRouteFieldPolicy = sqlRouteFieldPolicy;
25
133
  /**
26
134
  * The early return at the top of a handler, before the client connects:
27
135
  * `tableName` is the module's table, `rawQueryExpr` the request's raw statement
28
136
  * (or `null` where the handler accepts none).
29
137
  */
30
138
  var generateReadGuardCall = function (tableName, rawQueryExpr) {
31
- return " const __access = await __taGuardRead(req, ".concat(JSON.stringify(tableName), ", ").concat(rawQueryExpr || 'null', ")\n if (__access) {\n return res.status(__access.status).json({ success: false, error: __access.message, timestamp: Date.now() })\n }\n").concat((0, browser_row_policy_1.generateBrowserRowAccessCall)(tableName, rawQueryExpr));
139
+ return " const __exposure = await __taGuardExposure(req)\n if (__exposure) {\n return res.status(__exposure.status).json({ success: false, error: __exposure.message, timestamp: Date.now() })\n }\n const __access = await __taGuardRead(req, ".concat(JSON.stringify(tableName), ", ").concat(rawQueryExpr || 'null', ")\n if (__access) {\n return res.status(__access.status).json({ success: false, error: __access.message, timestamp: Date.now() })\n }\n").concat((0, browser_row_policy_1.generateBrowserRowAccessCall)(tableName, rawQueryExpr), " // Every field the request names is one the export knows; a row-owned page's\n // owner condition joins the request's own filters.\n try {\n __taAssertReadRequest(req)\n } catch (__invalid) {\n return res.status(400).json({ success: false, error: __invalid && __invalid.status ? __invalid.message : 'Invalid request', timestamp: Date.now() })\n }\n __taApplyOwnerScope(req)\n");
32
140
  };
33
141
  exports.generateReadGuardCall = generateReadGuardCall;
34
142
  //# sourceMappingURL=table-access-guard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"table-access-guard.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/table-access-guard.ts"],"names":[],"mappings":";;;AAAA,+DAAgF;AAChF,2DAAiG;AAEjG;;;;;;;;;;;;;GAaG;AAEH,2EAA2E;AACpE,IAAM,2BAA2B,GAAG,UAAC,kBAAyC;IACnF,OAAO,UAAG,uCAAqB,CAAC,wCAAwC,EAAE,eAC1E,6BAAW,CAAC,6BAA6B,CAAC,EAAE,kBAAkB,oBAAA,EAAE,CAAC,eACjE,IAAA,iDAA4B,GAAE,CAAE,CAAA;AAClC,CAAC,CAAA;AAJY,QAAA,2BAA2B,+BAIvC;AAED;;;;GAIG;AACI,IAAM,qBAAqB,GAAG,UAAC,SAAiB,EAAE,YAA2B;IAClF,OAAO,sDAA+C,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAC7E,YAAY,IAAI,MAAM,yJAKxB,IAAA,iDAA4B,EAAC,SAAS,EAAE,YAAY,CAAC,CAAE,CAAA;AACzD,CAAC,CAAA;AARY,QAAA,qBAAqB,yBAQjC"}
1
+ {"version":3,"file":"table-access-guard.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/table-access-guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA,+DAA8F;AAC9F,2DAAiG;AAEjG;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,8EAA8E;AACjE,QAAA,uBAAuB,GAAG,OAAO,CAAA;AA6B9C,8HAA8H;AACvH,IAAM,QAAQ,GAAG,UAAC,MAAe,EAAE,SAAiB;IACzD,IAAM,QAAQ,GACZ,MAGD,aAHC,MAAM,uBAAN,MAAM,CAGL,cAAc,CAAA;IACjB,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;QAC7C,OAAO,IAAI,CAAA;KACZ;IACD,IAAM,IAAI,GAAG,8BAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;IAClD,IAAM,KAAK,GACT,QAAQ,CAAC,SAAS,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;aAClB,MAAM,CAAC,UAAC,GAAG,IAAK,OAAA,8BAAY,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,IAAI,EAAxC,CAAwC,CAAC;aACzD,GAAG,CAAC,UAAC,GAAG,IAAK,OAAA,QAAQ,CAAC,GAAG,CAAC,EAAb,CAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IACnC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;QAC3C,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,KAAK,CAAC,OAAO;SACjB,MAAM,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAnE,CAAmE,CAAC;SACvF,GAAG,CAAC,UAAC,MAAM,IAAK,OAAA,YACf,IAAI,EAAE,MAAM,CAAC,IAAc,IACxB,CAAC,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,EAC7D,EAHe,CAGf,CAAC,CAAA;AACP,CAAC,CAAA;AAxBY,QAAA,QAAQ,YAwBpB;AAED,4GAA4G;AACrG,IAAM,eAAe,GAAG,UAAC,MAAe,EAAE,SAAiB;IAChE,IAAM,MAAM,GAAG,IAAA,gBAAQ,EAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,CAAC,IAAI,EAAX,CAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC5D,CAAC,CAAA;AAHY,QAAA,eAAe,mBAG3B;AAED;;;;GAIG;AACI,IAAM,yBAAyB,GAAG,UACvC,QAA6C,EAC7C,WAAiD,EACjD,SAAsB;IADtB,4BAAA,EAAA,gBAAoC,OAAO,EAAE,EAAE,EAAE;IACjD,0BAAA,EAAA,cAAsB;IAEtB,IAAM,aAAa,GAAG,QAAQ,IAAI,8BAAY,CAAC,oBAAoB,CAAA;IACnE,IAAM,eAAe,GAAG,aAAa,CAAC,eAAe,IAAI,EAAE,CAAA;IAC3D,IAAM,UAAU,GAAG,aAAa,CAAC,UAAU,IAAI,EAAE,CAAA;IACjD,IAAM,YAAY,GAChB,WAAW,CAAC,OAAO,KAAK,IAAI;QAC1B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,KAAK,CAAC,IAAI,CACR,IAAI,GAAG,CACL,gCAAI,WAAW,CAAC,OAAO,SAAK,CAAC,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC,QAAE,GAAG,CAAC,UAAC,MAAM;YACnE,OAAA,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE;QAA5B,CAA4B,CAC7B,CACF,CACF,CAAC,IAAI,EAAE,CAAA;IACd,OAAO,ucAMmB,IAAI,CAAC,SAAS,CAAC;QACvC,MAAM,EAAE,aAAa,CAAC,MAAM,KAAK,IAAI;QACrC,UAAU,EAAE,aAAa,CAAC,UAAU,KAAK,IAAI;QAC7C,KAAK,EAAE,aAAa,CAAC,KAAK,IAAI,EAAE;QAChC,eAAe,iBAAA;QACf,UAAU,YAAA;QACV,YAAY,EAAE,aAAa,CAAC,YAAY;QACxC,QAAQ,EAAE,aAAa,CAAC,QAAQ;KACjC,CAAC,sCACoB,+BAAuB,uCACtB,IAAI,CAAC,SAAS,CAAC,8BAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,0KAGpD,IAAI,CAAC,SAAS,CAAC;QACrC,OAAO,EAAE,YAAY;QACrB,aAAa,EAAE,CAAC,WAAW,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,UAAC,KAAK,IAAK,OAAA,KAAK,CAAC,WAAW,EAAE,EAAnB,CAAmB,CAAC;QACpF,eAAe,EAAE,CAAC,WAAW,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,CAAC,WAAW,EAAE,EAApB,CAAoB,CAAC;QAC1F,aAAa,EAAE,WAAW,CAAC,aAAa,KAAK,IAAI;KAClD,CAAC,yCACuB,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,gBACtF,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,8BAAY,CAAC,4BAA4B,EAAE,CAAC,CAAC,CAAC,EAAE,+jXA8Q9E,CAAA;AACD,CAAC,CAAA;AA3TY,QAAA,yBAAyB,6BA2TrC;AAaD;;;GAGG;AACI,IAAM,2BAA2B,GAAG,UACzC,kBAAyC,EACzC,QAAkC,EAClC,WAAgC,EAChC,SAAkB,EAClB,MAAmC;IAAnC,uBAAA,EAAA,WAAmC;IAEnC,4EAA4E;IAC5E,wEAAwE;IACxE,IAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,IAAI,OAAO,CAAA;IACtD,OAAO,UAAG,uCAAqB,CAAC,wCAAwC,CAAC,WAAW,EAAE;QACpF,cAAc,EAAE,MAAM,CAAC,iBAAiB,KAAK,KAAK;KACnD,CAAC,eACF,6BAAW,CAAC,6BAA6B,CAAC,EAAE,kBAAkB,oBAAA,EAAE,WAAW,aAAA,EAAE,CAAC,eAC9E,IAAA,iDAA4B,GAAE,eAC9B,IAAA,iCAAyB,EAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,IAAI,EAAE,CAAC,CAAE,CAAA;AACrE,CAAC,CAAA;AAhBY,QAAA,2BAA2B,+BAgBvC;AAED,iHAAiH;AACpG,QAAA,sBAAsB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;AACpE,QAAA,wBAAwB,GAAG,CAAC,kBAAkB,CAAC,CAAA;AAE5D,4GAA4G;AACrG,IAAM,mBAAmB,GAAG,UAAC,MAAe,EAAE,SAAiB;IACpE,IAAM,QAAQ,GAAG,8BAAY,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,mBAAmB,CAAA;IAC9E,kBACE,OAAO,EAAE,IAAA,uBAAe,EAAC,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,IAC9C,CAAC,QAAQ,IAAI;QACd,aAAa,EAAE,8BAAsB;QACrC,eAAe,EAAE,gCAAwB;KAC1C,CAAC,EACH;AACH,CAAC,CAAA;AATY,QAAA,mBAAmB,uBAS/B;AAED;;;;GAIG;AACI,IAAM,qBAAqB,GAAG,UAAC,SAAiB,EAAE,YAA2B;IAClF,OAAO,wPAIqC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAAK,YAAY,IAAI,MAAM,yJAIhG,IAAA,iDAA4B,EAC5B,SAAS,EACT,YAAY,CACb,yYAQA,CAAA;AACD,CAAC,CAAA;AArBY,QAAA,qBAAqB,yBAqBjC"}
package/dist/cjs/index.js CHANGED
@@ -226,7 +226,7 @@ function wrapDataSourceExpressionsInAttributes(astNode, dataSourceInfo, context,
226
226
  dependencies.DataProvider = {
227
227
  type: 'package',
228
228
  path: '@teleporthq/react-components',
229
- version: 'latest',
229
+ version: '1.0.13',
230
230
  meta: {
231
231
  namedImport: true,
232
232
  },
@@ -32,7 +32,10 @@ export type PaginationControlKind = 'first' | 'previous' | 'pages' | 'page' | 'e
32
32
  * (`array-mapper-pagination.ts`) copies.
33
33
  */
34
34
  export declare const PAGINATION_FOR_ATTR = "data-tq-pagination-for";
35
- /** The words of a `range` control, with `{from}`, `{to}` and `{total}` placeholders. */
35
+ /**
36
+ * The words of a `range` control, with `{from}`, `{to}`, `{total}`, `{page}`,
37
+ * `{pages}` and `{perPage}` placeholders — see `range-control.ts`.
38
+ */
36
39
  export declare const RANGE_TEMPLATE_ATTR = "data-tq-range-template";
37
40
  /** What a `range` control reads when it carries no template. */
38
41
  export declare const DEFAULT_RANGE_TEMPLATE = "{from}\u2013{to} of {total}";
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-controls.d.ts","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,+BAA+B,CAAA;AAEnE;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC7B,OAAO,GACP,UAAU,GACV,OAAO,GACP,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,WAAW,GACX,UAAU,GACV,OAAO,CAAA;AAEX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAE3D,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAE3D,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,gCAA2B,CAAA;AAO9D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,qBAAqB,EAC3B,eAAe,CAAC,EAAE,MAAM,GACvB,GAAG,CA2BL;AAED,6GAA6G;AAC7G,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,qBAAqB,GAAG,GAAG,EAAE,CAkBvF;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAWtD;AAED,wEAAwE;AACxE,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,CAAC,UAAU,GAC3B,IAAI,CAON;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,GAAG,EACnB,WAAW,EAAE,qBAAqB,EAAE,GACnC,IAAI,CAgBN"}
1
+ {"version":3,"file":"pagination-controls.d.ts","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,+BAA+B,CAAA;AAEnE;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC7B,OAAO,GACP,UAAU,GACV,OAAO,GACP,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,WAAW,GACX,UAAU,GACV,OAAO,CAAA;AAEX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAE3D;;;GAGG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAA;AAE3D,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,gCAA2B,CAAA;AAO9D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,GAAG,EACT,IAAI,EAAE,qBAAqB,EAC3B,eAAe,CAAC,EAAE,MAAM,GACvB,GAAG,CA2BL;AAED,6GAA6G;AAC7G,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,qBAAqB,GAAG,GAAG,EAAE,CAkBvF;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAWtD;AAED,wEAAwE;AACxE,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,CAAC,UAAU,GAC3B,IAAI,CAON;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,GAAG,EACnB,WAAW,EAAE,qBAAqB,EAAE,GACnC,IAAI,CAgBN"}
@@ -58,7 +58,10 @@ exports.PAGINATION_CONTROL_ATTR = 'data-tq-pagination-control';
58
58
  * (`array-mapper-pagination.ts`) copies.
59
59
  */
60
60
  exports.PAGINATION_FOR_ATTR = 'data-tq-pagination-for';
61
- /** The words of a `range` control, with `{from}`, `{to}` and `{total}` placeholders. */
61
+ /**
62
+ * The words of a `range` control, with `{from}`, `{to}`, `{total}`, `{page}`,
63
+ * `{pages}` and `{perPage}` placeholders — see `range-control.ts`.
64
+ */
62
65
  exports.RANGE_TEMPLATE_ATTR = 'data-tq-range-template';
63
66
  /** What a `range` control reads when it carries no template. */
64
67
  exports.DEFAULT_RANGE_TEMPLATE = '{from}–{to} of {total}';
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-controls.js","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAqC;AAErC;;;;;;;;;;GAUG;AACU,QAAA,uBAAuB,GAAG,4BAA4B,CAAA;AAsBnE;;;;;;;;;;GAUG;AACU,QAAA,mBAAmB,GAAG,wBAAwB,CAAA;AAE3D,wFAAwF;AAC3E,QAAA,mBAAmB,GAAG,wBAAwB,CAAA;AAE3D,gEAAgE;AACnD,QAAA,sBAAsB,GAAG,wBAAwB,CAAA;AAE9D,wBAAwB;AAExB,wEAAwE;AACxE,gFAAgF;AAChF,8BAA8B;AAC9B,SAAgB,sBAAsB,CAAC,IAAS,EAAE,QAAgB;;IAChE,IAAM,IAAI,GAAG,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc,0CAAE,UAAU,0CAAE,IAAI,CACjD,UAAC,SAAc,YAAK,OAAA,SAAS,CAAC,IAAI,KAAK,cAAc,IAAI,CAAA,MAAA,SAAS,CAAC,IAAI,0CAAE,IAAI,MAAK,QAAQ,CAAA,EAAA,CAC3F,CAAA;IACD,OAAO,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,0CAAE,KAAK,MAAI,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,0CAAE,UAAU,0CAAE,KAAK,CAAA,IAAI,EAAE,CAAA;AACnE,CAAC;AALD,wDAKC;AAED;;;;;;;GAOG;AACH,SAAgB,qBAAqB,CACnC,IAAS,EACT,IAA2B,EAC3B,eAAwB;IAExB,IAAM,MAAM,GAAG,UAAC,IAAS,EAAE,OAAoC;QAC7D,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,IAAI,CAAA;SACZ;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;YAC/C,OAAO,IAAI,CAAA;SACZ;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAChC,KAAoB,UAAa,EAAb,KAAA,IAAI,CAAC,QAAQ,EAAb,cAAa,EAAb,IAAa,EAAE;gBAA9B,IAAM,KAAK,SAAA;gBACd,IAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;gBACpC,IAAI,KAAK,EAAE;oBACT,OAAO,KAAK,CAAA;iBACb;aACF;SACF;QACD,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,IAAM,QAAQ,GAAG,MAAM,CACrB,IAAI,EACJ,UAAC,IAAI,IAAK,OAAA,sBAAsB,CAAC,IAAI,EAAE,+BAAuB,CAAC,KAAK,IAAI,EAA9D,CAA8D,CACzE,CAAA;IACD,IAAI,QAAQ,IAAI,CAAC,eAAe,EAAE;QAChC,OAAO,QAAQ,CAAA;KAChB;IACD,OAAO,MAAM,CAAC,IAAI,EAAE,UAAC,IAAI,IAAK,OAAA,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAnE,CAAmE,CAAC,CAAA;AACpG,CAAC;AA/BD,sDA+BC;AAED,6GAA6G;AAC7G,SAAgB,yBAAyB,CAAC,IAAS,EAAE,IAA2B;IAC9E,IAAM,KAAK,GAAU,EAAE,CAAA;IACvB,IAAM,QAAQ,GAAG,UAAC,IAAS;QACzB,IAAI,CAAC,IAAI,EAAE;YACT,OAAM;SACP;QACD,IACE,IAAI,CAAC,IAAI,KAAK,YAAY;YAC1B,sBAAsB,CAAC,IAAI,EAAE,+BAAuB,CAAC,KAAK,IAAI,EAC9D;YACA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;SACjB;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;SAChC;IACH,CAAC,CAAA;IACD,QAAQ,CAAC,IAAI,CAAC,CAAA;IACd,OAAO,KAAK,CAAA;AACd,CAAC;AAlBD,8DAkBC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CAAC,IAAS;IAC9C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAA;IACxC,IAAI,IAAI,CAAC,cAAc,EAAE;QACvB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAA;KACzC;IACD,IAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,UAAC,IAAS,YAAK,OAAA,CAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,IAAI,MAAK,MAAM,CAAA,EAAA,CAAC,CAAA;IAC9F,IAAI,CAAC,OAAO,EAAE;QACZ,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CACjC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAC/E,CAAA;KACF;AACH,CAAC;AAXD,wDAWC;AAED,wEAAwE;AACxE,SAAgB,yBAAyB,CACvC,IAAS,EACT,QAAgB,EAChB,UAA4B;IAE5B,IAAI,CAAC,cAAc,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CACpE,UAAC,IAAS,YAAK,OAAA,CAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,IAAI,MAAK,QAAQ,CAAA,EAAA,CAC5C,CAAA;IACD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CACjC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC,CAC5F,CAAA;AACH,CAAC;AAXD,8DAWC;AAED,0CAA0C;AAC1C,SAAgB,kBAAkB,CAAC,IAAS,EAAE,QAAgB;IAC5D,IAAI,CAAC,cAAc,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CACpE,UAAC,IAAS,YAAK,OAAA,CAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,IAAI,MAAK,QAAQ,CAAA,EAAA,CAC5C,CAAA;AACH,CAAC;AAJD,gDAIC;AAED;;;;;;;;;GASG;AACH,SAAgB,8BAA8B,CAC5C,cAAmB,EACnB,WAAoC;IAEpC,IAAM,MAAM,GAAG,IAAI,GAAG,iCAAa,WAAW,UAAE,OAAO,UAAE,CAAA;IACzD,IAAM,KAAK,GAAG,UAAC,IAAS;QACtB,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC1C,OAAM;SACP;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAC,KAAU;YAC9C,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,MAAK,YAAY,EAAE;gBAChC,OAAO,IAAI,CAAA;aACZ;YACD,IAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,EAAE,+BAAuB,CAAC,CAAA;YACrE,OAAO,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC5C,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC,CAAA;IACD,KAAK,CAAC,cAAc,CAAC,CAAA;AACvB,CAAC;AAnBD,wEAmBC"}
1
+ {"version":3,"file":"pagination-controls.js","sourceRoot":"","sources":["../../src/pagination-controls.ts"],"names":[],"mappings":"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"}
@@ -2112,6 +2112,7 @@ function wireRangeControlFor(control, usage, vars) {
2112
2112
  (0, range_control_1.wireRangeControl)(control, {
2113
2113
  totalVar: vars.totalStateVar,
2114
2114
  currentPageExpr: currentPageExpr(),
2115
+ maxPagesVar: vars.maxPagesStateVar,
2115
2116
  perPage: usage.perPage,
2116
2117
  infiniteScroll: usage.infiniteScroll,
2117
2118
  });