@teleporthq/teleport-plugin-next-data-source 0.43.67 → 0.43.68
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.
- package/__tests__/array-overlap-sql.test.ts +53 -0
- package/__tests__/blog-post-page-enrichment.test.ts +214 -0
- package/__tests__/browser-row-policy.test.ts +503 -0
- package/__tests__/data-source-cache-wrapping.test.ts +18 -2
- package/__tests__/ecommerce-product-options.test.ts +206 -0
- package/__tests__/ecommerce-product-pages.test.ts +82 -0
- package/__tests__/ecommerce-product-pre-options.golden.json +505 -0
- package/__tests__/ecommerce-product-storefront-contract.test.ts +293 -0
- package/__tests__/ecommerce-product-subscriptions.test.ts +121 -0
- package/__tests__/fetchers.test.ts +2 -2
- package/__tests__/items-path.test.ts +150 -0
- package/__tests__/product-options-storefront.fixture.json +2510 -0
- package/__tests__/product-page-url-fixtures.json +25 -0
- package/__tests__/product-price-sort.ts +4 -2
- package/__tests__/raw-rows-mode.test.ts +111 -0
- package/__tests__/rest-api-response-cache.test.ts +434 -0
- package/__tests__/table-read-route-protected-tables.test.ts +493 -0
- package/dist/cjs/array-overlap-sql.d.ts +21 -0
- package/dist/cjs/array-overlap-sql.d.ts.map +1 -0
- package/dist/cjs/array-overlap-sql.js +25 -0
- package/dist/cjs/array-overlap-sql.js.map +1 -0
- package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
- package/dist/cjs/data-source-fetchers.js +10 -4
- package/dist/cjs/data-source-fetchers.js.map +1 -1
- package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
- package/dist/cjs/fetchers/javascript.js +1 -1
- package/dist/cjs/fetchers/javascript.js.map +1 -1
- package/dist/cjs/fetchers/postgresql.d.ts +1 -1
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
- package/dist/cjs/fetchers/postgresql.js +8 -4
- package/dist/cjs/fetchers/postgresql.js.map +1 -1
- package/dist/cjs/fetchers/raw-query.d.ts +8 -1
- package/dist/cjs/fetchers/raw-query.d.ts.map +1 -1
- package/dist/cjs/fetchers/raw-query.js +42 -4
- package/dist/cjs/fetchers/raw-query.js.map +1 -1
- package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
- package/dist/cjs/fetchers/rest-api.js +7 -2
- package/dist/cjs/fetchers/rest-api.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +8 -5
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.d.ts +43 -0
- package/dist/cjs/fetchers/utils/browser-row-policy.d.ts.map +1 -0
- package/dist/cjs/fetchers/utils/browser-row-policy.js +66 -0
- package/dist/cjs/fetchers/utils/browser-row-policy.js.map +1 -0
- package/dist/cjs/fetchers/utils/request-sql-guards.d.ts +8 -0
- package/dist/cjs/fetchers/utils/request-sql-guards.d.ts.map +1 -0
- package/dist/cjs/fetchers/utils/request-sql-guards.js +12 -0
- package/dist/cjs/fetchers/utils/request-sql-guards.js.map +1 -0
- package/dist/cjs/fetchers/utils/rest-api-response-cache.d.ts +40 -0
- package/dist/cjs/fetchers/utils/rest-api-response-cache.d.ts.map +1 -0
- package/dist/cjs/fetchers/utils/rest-api-response-cache.js +64 -0
- package/dist/cjs/fetchers/utils/rest-api-response-cache.js.map +1 -0
- package/dist/cjs/fetchers/utils/table-access-guard.d.ts +23 -0
- package/dist/cjs/fetchers/utils/table-access-guard.d.ts.map +1 -0
- package/dist/cjs/fetchers/utils/table-access-guard.js +34 -0
- package/dist/cjs/fetchers/utils/table-access-guard.js.map +1 -0
- package/dist/cjs/items-path.d.ts +10 -0
- package/dist/cjs/items-path.d.ts.map +1 -0
- package/dist/cjs/items-path.js +86 -0
- package/dist/cjs/items-path.js.map +1 -0
- package/dist/cjs/localized-columns.d.ts.map +1 -1
- package/dist/cjs/localized-columns.js +13 -0
- package/dist/cjs/localized-columns.js.map +1 -1
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +17 -5
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/transformations/blog-adjacent-posts.d.ts +16 -0
- package/dist/cjs/transformations/blog-adjacent-posts.d.ts.map +1 -0
- package/dist/cjs/transformations/blog-adjacent-posts.js +25 -0
- package/dist/cjs/transformations/blog-adjacent-posts.js.map +1 -0
- package/dist/cjs/transformations/blog-comments.d.ts +30 -0
- package/dist/cjs/transformations/blog-comments.d.ts.map +1 -0
- package/dist/cjs/transformations/blog-comments.js +34 -0
- package/dist/cjs/transformations/blog-comments.js.map +1 -0
- package/dist/cjs/transformations/blog-post.d.ts +2 -0
- package/dist/cjs/transformations/blog-post.d.ts.map +1 -1
- package/dist/cjs/transformations/blog-post.js +4 -1
- package/dist/cjs/transformations/blog-post.js.map +1 -1
- package/dist/cjs/transformations/ecommerce-product.d.ts +9 -1
- package/dist/cjs/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/cjs/transformations/ecommerce-product.js +28 -1
- package/dist/cjs/transformations/ecommerce-product.js.map +1 -1
- package/dist/cjs/transformations/heading-anchors.d.ts +25 -0
- package/dist/cjs/transformations/heading-anchors.d.ts.map +1 -0
- package/dist/cjs/transformations/heading-anchors.js +29 -0
- package/dist/cjs/transformations/heading-anchors.js.map +1 -0
- package/dist/cjs/transformations/index.d.ts +47 -4
- package/dist/cjs/transformations/index.d.ts.map +1 -1
- package/dist/cjs/transformations/index.js +56 -18
- package/dist/cjs/transformations/index.js.map +1 -1
- package/dist/cjs/transformations/shared-utils.d.ts.map +1 -1
- package/dist/cjs/transformations/shared-utils.js +1 -1
- package/dist/cjs/transformations/shared-utils.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +1 -1
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/array-overlap-sql.d.ts +21 -0
- package/dist/esm/array-overlap-sql.d.ts.map +1 -0
- package/dist/esm/array-overlap-sql.js +21 -0
- package/dist/esm/array-overlap-sql.js.map +1 -0
- package/dist/esm/data-source-fetchers.d.ts.map +1 -1
- package/dist/esm/data-source-fetchers.js +11 -5
- package/dist/esm/data-source-fetchers.js.map +1 -1
- package/dist/esm/fetchers/javascript.d.ts.map +1 -1
- package/dist/esm/fetchers/javascript.js +1 -1
- package/dist/esm/fetchers/javascript.js.map +1 -1
- package/dist/esm/fetchers/postgresql.d.ts +1 -1
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
- package/dist/esm/fetchers/postgresql.js +8 -4
- package/dist/esm/fetchers/postgresql.js.map +1 -1
- package/dist/esm/fetchers/raw-query.d.ts +8 -1
- package/dist/esm/fetchers/raw-query.d.ts.map +1 -1
- package/dist/esm/fetchers/raw-query.js +42 -4
- package/dist/esm/fetchers/raw-query.js.map +1 -1
- package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
- package/dist/esm/fetchers/rest-api.js +7 -2
- package/dist/esm/fetchers/rest-api.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +8 -5
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/fetchers/utils/browser-row-policy.d.ts +43 -0
- package/dist/esm/fetchers/utils/browser-row-policy.d.ts.map +1 -0
- package/dist/esm/fetchers/utils/browser-row-policy.js +60 -0
- package/dist/esm/fetchers/utils/browser-row-policy.js.map +1 -0
- package/dist/esm/fetchers/utils/request-sql-guards.d.ts +8 -0
- package/dist/esm/fetchers/utils/request-sql-guards.d.ts.map +1 -0
- package/dist/esm/fetchers/utils/request-sql-guards.js +8 -0
- package/dist/esm/fetchers/utils/request-sql-guards.js.map +1 -0
- package/dist/esm/fetchers/utils/rest-api-response-cache.d.ts +40 -0
- package/dist/esm/fetchers/utils/rest-api-response-cache.d.ts.map +1 -0
- package/dist/esm/fetchers/utils/rest-api-response-cache.js +59 -0
- package/dist/esm/fetchers/utils/rest-api-response-cache.js.map +1 -0
- package/dist/esm/fetchers/utils/table-access-guard.d.ts +23 -0
- package/dist/esm/fetchers/utils/table-access-guard.d.ts.map +1 -0
- package/dist/esm/fetchers/utils/table-access-guard.js +29 -0
- package/dist/esm/fetchers/utils/table-access-guard.js.map +1 -0
- package/dist/esm/items-path.d.ts +10 -0
- package/dist/esm/items-path.d.ts.map +1 -0
- package/dist/esm/items-path.js +58 -0
- package/dist/esm/items-path.js.map +1 -0
- package/dist/esm/localized-columns.d.ts.map +1 -1
- package/dist/esm/localized-columns.js +13 -0
- package/dist/esm/localized-columns.js.map +1 -1
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +17 -5
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/transformations/blog-adjacent-posts.d.ts +16 -0
- package/dist/esm/transformations/blog-adjacent-posts.d.ts.map +1 -0
- package/dist/esm/transformations/blog-adjacent-posts.js +21 -0
- package/dist/esm/transformations/blog-adjacent-posts.js.map +1 -0
- package/dist/esm/transformations/blog-comments.d.ts +30 -0
- package/dist/esm/transformations/blog-comments.d.ts.map +1 -0
- package/dist/esm/transformations/blog-comments.js +30 -0
- package/dist/esm/transformations/blog-comments.js.map +1 -0
- package/dist/esm/transformations/blog-post.d.ts +2 -0
- package/dist/esm/transformations/blog-post.d.ts.map +1 -1
- package/dist/esm/transformations/blog-post.js +4 -1
- package/dist/esm/transformations/blog-post.js.map +1 -1
- package/dist/esm/transformations/ecommerce-product.d.ts +9 -1
- package/dist/esm/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/esm/transformations/ecommerce-product.js +29 -2
- package/dist/esm/transformations/ecommerce-product.js.map +1 -1
- package/dist/esm/transformations/heading-anchors.d.ts +25 -0
- package/dist/esm/transformations/heading-anchors.d.ts.map +1 -0
- package/dist/esm/transformations/heading-anchors.js +25 -0
- package/dist/esm/transformations/heading-anchors.js.map +1 -0
- package/dist/esm/transformations/index.d.ts +47 -4
- package/dist/esm/transformations/index.d.ts.map +1 -1
- package/dist/esm/transformations/index.js +56 -18
- package/dist/esm/transformations/index.js.map +1 -1
- package/dist/esm/transformations/shared-utils.d.ts.map +1 -1
- package/dist/esm/transformations/shared-utils.js +1 -1
- package/dist/esm/transformations/shared-utils.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/array-overlap-sql.ts +41 -0
- package/src/data-source-fetchers.ts +41 -5
- package/src/fetchers/javascript.ts +9 -1
- package/src/fetchers/postgresql.ts +37 -10
- package/src/fetchers/raw-query.ts +60 -5
- package/src/fetchers/rest-api.ts +27 -5
- package/src/fetchers/teleport.ts +37 -13
- package/src/fetchers/utils/browser-row-policy.ts +212 -0
- package/src/fetchers/utils/request-sql-guards.ts +25 -0
- package/src/fetchers/utils/rest-api-response-cache.ts +188 -0
- package/src/fetchers/utils/table-access-guard.ts +39 -0
- package/src/items-path.ts +74 -0
- package/src/localized-columns.ts +13 -0
- package/src/pagination-plugin.ts +29 -7
- package/src/transformations/blog-adjacent-posts.ts +74 -0
- package/src/transformations/blog-comments.ts +132 -0
- package/src/transformations/blog-post.ts +38 -5
- package/src/transformations/ecommerce-product.ts +568 -5
- package/src/transformations/heading-anchors.ts +85 -0
- package/src/transformations/index.ts +165 -22
- package/src/transformations/shared-utils.ts +6 -0
- package/src/utils.ts +26 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teleport.js","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":";;;AAAA,kCAMiB;AACjB,sDAK2B;AAC3B,4DAI8B;AAC9B,kEAA4E;AAC5E,0DAA8F;AAC9F,oDAAwD;
|
|
1
|
+
{"version":3,"file":"teleport.js","sourceRoot":"","sources":["../../../src/fetchers/teleport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a per-table read route (`/api/teleport-<table>-<source>` and its count
|
|
3
|
+
* twin) serves a BROWSER of the tables whose unpublished rows sit beside the
|
|
4
|
+
* public ones. (The tables it serves a browser not at all — the AI assistant's
|
|
5
|
+
* among them — are `TableAccess.PROTECTED_TABLES`, guarded by `__taGuardRead`.)
|
|
6
|
+
*
|
|
7
|
+
* The route answers whoever asks, with the whole table. For the blog that was
|
|
8
|
+
* every draft, scheduled and archived post — and each author's email address;
|
|
9
|
+
* for the catalogue, every draft and inactive product. The storefront's own
|
|
10
|
+
* bindings ask for the public rows, but the route is a URL anyone can call
|
|
11
|
+
* without them. So a caller that is not the store itself (its server code, or a
|
|
12
|
+
* signed-in administrator — the generated admin edits drafts through these
|
|
13
|
+
* routes) is served only the rows the storefront publishes, never a hidden
|
|
14
|
+
* column, and may neither filter, sort nor search by a hidden column: a filter
|
|
15
|
+
* is an oracle for a column it never returns.
|
|
16
|
+
*/
|
|
17
|
+
export interface BrowserRowPolicy {
|
|
18
|
+
/** SQL every browser read of the table is narrowed with. */
|
|
19
|
+
predicate: string;
|
|
20
|
+
/** Keys never served to a browser, wherever they sit in a row (raw and transformed names). */
|
|
21
|
+
hiddenColumns: ReadonlyArray<string>;
|
|
22
|
+
}
|
|
23
|
+
export declare const BROWSER_ROW_POLICIES: Readonly<Record<string, BrowserRowPolicy>>;
|
|
24
|
+
/**
|
|
25
|
+
* ES5 source inlined after the table-access preamble (it uses `__ta*` and
|
|
26
|
+
* `__tqSessionToken`). Declares `__brpAccess(req, tableName, rawQuery)`, which
|
|
27
|
+
* resolves to `{ denied, policy }`: `denied` a `{ status, message }` refusal or
|
|
28
|
+
* null, `policy` the narrowing to apply to this read or null (the caller reads
|
|
29
|
+
* the table whole). Plus the helpers that apply a policy to a request and to
|
|
30
|
+
* its rows.
|
|
31
|
+
*/
|
|
32
|
+
export declare const generateBrowserRowPolicyCode: () => string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether a per-table read route's answer depends on who asks — the rows it
|
|
35
|
+
* narrows, the tables it guards — so its response cache must be split by view.
|
|
36
|
+
*/
|
|
37
|
+
export declare const isViewDependentTable: (tableName: string, protectedTables: ReadonlyArray<string>) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The early return right after the table-access guard, plus the policy
|
|
40
|
+
* (`__rowPolicy`, null or a policy) the handler narrows the rest of its read by.
|
|
41
|
+
*/
|
|
42
|
+
export declare const generateBrowserRowAccessCall: (tableName: string, rawQueryExpr: string | null) => string;
|
|
43
|
+
//# sourceMappingURL=browser-row-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-row-policy.d.ts","sourceRoot":"","sources":["../../../../src/fetchers/utils/browser-row-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAA;IACjB,8FAA8F;IAC9F,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACrC;AAED,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAa3E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,QACnC,MA8HL,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,cACpB,MAAM,mBACA,cAAc,MAAM,CAAC,KACrC,OAUF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,cAC5B,MAAM,gBACH,MAAM,GAAG,IAAI,KAC1B,MASF,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* What a per-table read route (`/api/teleport-<table>-<source>` and its count
|
|
4
|
+
* twin) serves a BROWSER of the tables whose unpublished rows sit beside the
|
|
5
|
+
* public ones. (The tables it serves a browser not at all — the AI assistant's
|
|
6
|
+
* among them — are `TableAccess.PROTECTED_TABLES`, guarded by `__taGuardRead`.)
|
|
7
|
+
*
|
|
8
|
+
* The route answers whoever asks, with the whole table. For the blog that was
|
|
9
|
+
* every draft, scheduled and archived post — and each author's email address;
|
|
10
|
+
* for the catalogue, every draft and inactive product. The storefront's own
|
|
11
|
+
* bindings ask for the public rows, but the route is a URL anyone can call
|
|
12
|
+
* without them. So a caller that is not the store itself (its server code, or a
|
|
13
|
+
* signed-in administrator — the generated admin edits drafts through these
|
|
14
|
+
* routes) is served only the rows the storefront publishes, never a hidden
|
|
15
|
+
* column, and may neither filter, sort nor search by a hidden column: a filter
|
|
16
|
+
* is an oracle for a column it never returns.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.generateBrowserRowAccessCall = exports.isViewDependentTable = exports.generateBrowserRowPolicyCode = exports.BROWSER_ROW_POLICIES = void 0;
|
|
20
|
+
exports.BROWSER_ROW_POLICIES = {
|
|
21
|
+
// ONLY `published` is public — the blog's own rule (see the GUI's
|
|
22
|
+
// `blog-post-status.ts`): drafts, scheduled and archived posts are not.
|
|
23
|
+
teleport_blog_posts: {
|
|
24
|
+
predicate: "status = 'published'",
|
|
25
|
+
hiddenColumns: ['author_email', 'authorEmail'],
|
|
26
|
+
},
|
|
27
|
+
// The storefront sells `active` products; a draft or inactive one is the
|
|
28
|
+
// merchant's, spelled in any case the admin form stored it in.
|
|
29
|
+
teleport_products: {
|
|
30
|
+
predicate: "LOWER(TRIM(status)) = 'active'",
|
|
31
|
+
hiddenColumns: [],
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* ES5 source inlined after the table-access preamble (it uses `__ta*` and
|
|
36
|
+
* `__tqSessionToken`). Declares `__brpAccess(req, tableName, rawQuery)`, which
|
|
37
|
+
* resolves to `{ denied, policy }`: `denied` a `{ status, message }` refusal or
|
|
38
|
+
* null, `policy` the narrowing to apply to this read or null (the caller reads
|
|
39
|
+
* the table whole). Plus the helpers that apply a policy to a request and to
|
|
40
|
+
* its rows.
|
|
41
|
+
*/
|
|
42
|
+
var generateBrowserRowPolicyCode = function () { return "// GENERATED \u2014 see browser-row-policy.ts in teleport-plugin-next-data-source.\nvar __BRP_POLICIES = ".concat(JSON.stringify(exports.BROWSER_ROW_POLICIES), ";\n\n// Who is asking: the store's own server code and its administrators read every\n// row; anyone else is a visitor.\nasync function __brpReader(req) {\n if (__taIsInternalRequest(req)) return { trusted: true };\n var token = null;\n try {\n token = await __tqSessionToken(req);\n } catch (e) {\n token = null;\n }\n var role = token ? __taRoleOf(token) : null;\n return { trusted: !!role && __TA_TRUSTED_READER_ROLES.indexOf(role) !== -1 };\n}\n\nfunction __brpMentionsAny(rawQuery, tables) {\n for (var i = 0; i < tables.length; i++) {\n if (__taSqlMentionsTable(rawQuery, tables[i])) return true;\n }\n return false;\n}\n\n// A raw statement cannot be narrowed, so a visitor's statement that names a\n// narrowed table is refused whole. The session is only decoded when the read\n// touches one of these tables.\nasync function __brpAccess(req, tableName, rawQuery) {\n var raw = typeof rawQuery === 'string' && rawQuery.length > 0 ? rawQuery : null;\n var bare = __taNormalizeTable(tableName);\n var rawNarrowed = !!raw && __brpMentionsAny(raw, Object.keys(__BRP_POLICIES));\n var policy = raw ? null : (Object.prototype.hasOwnProperty.call(__BRP_POLICIES, bare) ? __BRP_POLICIES[bare] : null);\n if (!rawNarrowed && !policy) return { denied: null, policy: null };\n var reader = await __brpReader(req);\n if (reader.trusted) return { denied: null, policy: null };\n if (rawNarrowed) {\n return { denied: { status: 403, message: 'Forbidden: raw queries over this table are only available to server-side calls' }, policy: null };\n }\n return { denied: null, policy: policy };\n}\n\nfunction __brpColumnName(field) {\n var parts = String(field == null ? '' : field).replace(/\"/g, '').trim().split('.');\n return parts[parts.length - 1];\n}\n\nfunction __brpIsHidden(policy, field) {\n var name = __brpColumnName(field).toLowerCase();\n for (var i = 0; i < policy.hiddenColumns.length; i++) {\n if (policy.hiddenColumns[i].toLowerCase() === name) return true;\n }\n return false;\n}\n\n// Every field a request filters, sorts or searches by, however deep a filter\n// group nests it. A condition's value is data, not a field.\nfunction __brpRequestFields(value, out) {\n if (Array.isArray(value)) {\n for (var i = 0; i < value.length; i++) __brpRequestFields(value[i], out);\n } else if (value && typeof value === 'object') {\n if (typeof value.source === 'string') out.push(value.source);\n if (typeof value.field === 'string') out.push(value.field);\n var keys = Object.keys(value);\n for (var k = 0; k < keys.length; k++) {\n if (keys[k] === 'destination' || keys[k] === 'value') continue;\n if (value[keys[k]] && typeof value[keys[k]] === 'object') __brpRequestFields(value[keys[k]], out);\n }\n } else if (typeof value === 'string' && value) {\n out.push(value);\n }\n return out;\n}\n\nfunction __brpParse(value) {\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch (e) {\n return value;\n }\n}\n\nfunction __brpAssertVisibleFields(policy, query) {\n var q = query || {};\n var fields = [];\n __brpRequestFields(__brpParse(q.filters), fields);\n __brpRequestFields(__brpParse(q.sorts), fields);\n __brpRequestFields(__brpParse(q.queryColumns), fields);\n if (typeof q.sortBy === 'string') fields.push(q.sortBy);\n for (var i = 0; i < fields.length; i++) {\n if (__brpIsHidden(policy, fields[i])) {\n var err = new Error('Forbidden: ' + __brpColumnName(fields[i]) + ' is not readable');\n err.status = 403;\n throw err;\n }\n }\n}\n\nfunction __brpVisibleColumns(policy, columns) {\n return columns.filter(function(column) { return !__brpIsHidden(policy, column); });\n}\n\n// The rows without a hidden key, at any depth: a transformed row nests related\n// rows (a post's related and adjacent posts) built the same way.\nfunction __brpStripHidden(policy, value) {\n if (Array.isArray(value)) {\n return value.map(function(entry) { return __brpStripHidden(policy, entry); });\n }\n if (!value || typeof value !== 'object') return value;\n var copy = {};\n Object.keys(value).forEach(function(key) {\n if (!__brpIsHidden(policy, key)) copy[key] = __brpStripHidden(policy, value[key]);\n });\n return copy;\n}\n\n// Whether this request is answered exactly as an anonymous visitor's would be,\n// so a response cached for one may serve the other. A read whose answer depends\n// on who asks (`viewDependent`: a narrowed, protected or admin-only table) or\n// that runs a raw statement differs for the store's own server code and its\n// administrators, and must never share a cache entry with a visitor.\nasync function __brpSharesPublicView(req, viewDependent) {\n var raw = !!(req && req.query && typeof req.query.rawQuery === 'string' && req.query.rawQuery.length > 0);\n if (!viewDependent && !raw) return true;\n return !(await __brpReader(req)).trusted;\n}\n"); };
|
|
43
|
+
exports.generateBrowserRowPolicyCode = generateBrowserRowPolicyCode;
|
|
44
|
+
/**
|
|
45
|
+
* Whether a per-table read route's answer depends on who asks — the rows it
|
|
46
|
+
* narrows, the tables it guards — so its response cache must be split by view.
|
|
47
|
+
*/
|
|
48
|
+
var isViewDependentTable = function (tableName, protectedTables) {
|
|
49
|
+
var parts = String(tableName || '')
|
|
50
|
+
.trim()
|
|
51
|
+
.toLowerCase()
|
|
52
|
+
.split('.');
|
|
53
|
+
var bare = parts[parts.length - 1].replace(/"/g, '');
|
|
54
|
+
return (Object.prototype.hasOwnProperty.call(exports.BROWSER_ROW_POLICIES, bare) ||
|
|
55
|
+
protectedTables.indexOf(bare) !== -1);
|
|
56
|
+
};
|
|
57
|
+
exports.isViewDependentTable = isViewDependentTable;
|
|
58
|
+
/**
|
|
59
|
+
* The early return right after the table-access guard, plus the policy
|
|
60
|
+
* (`__rowPolicy`, null or a policy) the handler narrows the rest of its read by.
|
|
61
|
+
*/
|
|
62
|
+
var generateBrowserRowAccessCall = function (tableName, rawQueryExpr) {
|
|
63
|
+
return " const __rowAccess = await __brpAccess(req, ".concat(JSON.stringify(tableName), ", ").concat(rawQueryExpr || 'null', ")\n if (__rowAccess.denied) {\n return res.status(__rowAccess.denied.status).json({ success: false, error: __rowAccess.denied.message, timestamp: Date.now() })\n }\n const __rowPolicy = __rowAccess.policy\n");
|
|
64
|
+
};
|
|
65
|
+
exports.generateBrowserRowAccessCall = generateBrowserRowAccessCall;
|
|
66
|
+
//# sourceMappingURL=browser-row-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-row-policy.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/browser-row-policy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AASU,QAAA,oBAAoB,GAA+C;IAC9E,kEAAkE;IAClE,wEAAwE;IACxE,mBAAmB,EAAE;QACnB,SAAS,EAAE,sBAAsB;QACjC,aAAa,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC;KAC/C;IACD,yEAAyE;IACzE,+DAA+D;IAC/D,iBAAiB,EAAE;QACjB,SAAS,EAAE,gCAAgC;QAC3C,aAAa,EAAE,EAAE;KAClB;CACF,CAAA;AAED;;;;;;;GAOG;AACI,IAAM,4BAA4B,GACvC,cAAc,OAAA,mHACO,IAAI,CAAC,SAAS,CAAC,4BAAoB,CAAC,y1JA6H1D,EA9He,CA8Hf,CAAA;AA/HY,QAAA,4BAA4B,gCA+HxC;AAED;;;GAGG;AACI,IAAM,oBAAoB,GAAG,UAClC,SAAiB,EACjB,eAAsC;IAEtC,IAAM,KAAK,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;SAClC,IAAI,EAAE;SACN,WAAW,EAAE;SACb,KAAK,CAAC,GAAG,CAAC,CAAA;IACb,IAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACtD,OAAO,CACL,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,4BAAoB,EAAE,IAAI,CAAC;QAChE,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CACrC,CAAA;AACH,CAAC,CAAA;AAbY,QAAA,oBAAoB,wBAahC;AAED;;;GAGG;AACI,IAAM,4BAA4B,GAAG,UAC1C,SAAiB,EACjB,YAA2B;IAE3B,OAAO,uDAAgD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,eAC9E,YAAY,IAAI,MAAM,yNAMzB,CAAA;AACD,CAAC,CAAA;AAZY,QAAA,4BAA4B,gCAYxC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a per-table read route takes from its query string and splices into
|
|
3
|
+
* SQL: filter columns, sort columns and a row count. Values are bound as
|
|
4
|
+
* parameters; these three are not, so each is checked for the one shape it
|
|
5
|
+
* may have before it reaches the statement.
|
|
6
|
+
*/
|
|
7
|
+
export declare const generateRequestSqlGuardsCode: () => string;
|
|
8
|
+
//# sourceMappingURL=request-sql-guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-sql-guards.d.ts","sourceRoot":"","sources":["../../../../src/fetchers/utils/request-sql-guards.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,QAAO,MAkB/C,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateRequestSqlGuardsCode = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* What a per-table read route takes from its query string and splices into
|
|
6
|
+
* SQL: filter columns, sort columns and a row count. Values are bound as
|
|
7
|
+
* parameters; these three are not, so each is checked for the one shape it
|
|
8
|
+
* may have before it reaches the statement.
|
|
9
|
+
*/
|
|
10
|
+
var generateRequestSqlGuardsCode = function () { return "\n// A column name as this route accepts one from a request: plain, optionally\n// quoted or table-qualified. Anything else - an expression, a sub-select - is\n// SQL the caller wrote, and it would run as part of this statement.\nconst REQUEST_COLUMN_RE = /^\"?[A-Za-z_][A-Za-z0-9_]*\"?(?:\\.\"?[A-Za-z_][A-Za-z0-9_]*\"?)?$/\nfunction assertRequestColumn(field, label) {\n if (typeof field !== 'string' || !REQUEST_COLUMN_RE.test(field)) {\n const error = new Error('Invalid ' + label)\n error.status = 400\n throw error\n }\n}\n\n// A row count from a request, as a whole number or nothing.\nfunction requestRowCount(value) {\n const parsed = parseInt(value, 10)\n return isNaN(parsed) || parsed < 0 ? undefined : parsed\n}\n"; };
|
|
11
|
+
exports.generateRequestSqlGuardsCode = generateRequestSqlGuardsCode;
|
|
12
|
+
//# sourceMappingURL=request-sql-guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-sql-guards.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/request-sql-guards.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACI,IAAM,4BAA4B,GAAG,cAAc,OAAA,quBAkBzD,EAlByD,CAkBzD,CAAA;AAlBY,QAAA,4BAA4B,gCAkBxC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The REST API data source's response cache: `config.cache` as the editor
|
|
3
|
+
* stores it on the data source.
|
|
4
|
+
*/
|
|
5
|
+
export interface RESTAPICacheConfig {
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
ttlSeconds?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The window, in whole seconds, a REST API data source caches its upstream
|
|
11
|
+
* response for — or `undefined` when caching is off, which keeps the emitted
|
|
12
|
+
* fetcher exactly what it was before this option existed.
|
|
13
|
+
*/
|
|
14
|
+
export declare const resolveRESTAPICacheTTLSeconds: (cache: RESTAPICacheConfig | undefined) => number | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Runtime helpers of a cached REST API fetcher.
|
|
17
|
+
*
|
|
18
|
+
* The cache sits under the handler, around the upstream `fetch` only: every
|
|
19
|
+
* caller — the API route, `getStaticProps` through `fetchData`, the count
|
|
20
|
+
* route, the global-state route — asks the same URL, and search, filters, sort
|
|
21
|
+
* and paging are applied to the cached payload afterwards. One upstream call
|
|
22
|
+
* per window therefore serves every page, filter and visitor.
|
|
23
|
+
*
|
|
24
|
+
* - The store lives on `globalThis`, so every data-source module in the
|
|
25
|
+
* process (each API route is its own bundle) shares it. On a serverless host
|
|
26
|
+
* that is one store per warm instance; the `s-maxage` header below is what
|
|
27
|
+
* carries the window to the CDN in front of all of them.
|
|
28
|
+
* - Entries are keyed by the whole upstream request (method, URL, headers,
|
|
29
|
+
* body) and hold the response TEXT: every reader parses its own copy, so a
|
|
30
|
+
* handler that sorts in place can never reorder another request's rows.
|
|
31
|
+
* - Freshness is judged by the READER's window, so two data sources calling
|
|
32
|
+
* the same URL with different windows each get what they asked for.
|
|
33
|
+
* - Only a 2xx JSON response is kept. Errors, non-JSON bodies and network
|
|
34
|
+
* failures reach the caller as before and are retried by the next request.
|
|
35
|
+
*
|
|
36
|
+
* Emitted inside a template literal: no backticks or template placeholders in
|
|
37
|
+
* here, not even in comments.
|
|
38
|
+
*/
|
|
39
|
+
export declare const generateRESTAPIResponseCacheCode: (ttlSeconds: number) => string;
|
|
40
|
+
//# sourceMappingURL=rest-api-response-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest-api-response-cache.d.ts","sourceRoot":"","sources":["../../../../src/fetchers/utils/rest-api-response-cache.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAoBD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,UACjC,kBAAkB,GAAG,SAAS,KACpC,MAAM,GAAG,SAYX,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gCAAgC,eAAgB,MAAM,KAAG,MAiHrE,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateRESTAPIResponseCacheCode = exports.resolveRESTAPICacheTTLSeconds = void 0;
|
|
4
|
+
var teleport_shared_1 = require("@teleporthq/teleport-shared");
|
|
5
|
+
/** A year: past that, the window only ever ends with the next deployment. */
|
|
6
|
+
var MAX_TTL_SECONDS = 31536000;
|
|
7
|
+
/**
|
|
8
|
+
* Bounds for the one store every REST API data source in a server process
|
|
9
|
+
* shares. Entries are raw JSON text, so the character budget is close to the
|
|
10
|
+
* memory the cache holds.
|
|
11
|
+
*/
|
|
12
|
+
var MAX_ENTRIES = 100;
|
|
13
|
+
var MAX_CHARS = 33554432;
|
|
14
|
+
/**
|
|
15
|
+
* How long a request may wait on an upstream call another request started.
|
|
16
|
+
* An older call is treated as stuck and a new one is made, so one hung socket
|
|
17
|
+
* cannot hold every later visitor.
|
|
18
|
+
*/
|
|
19
|
+
var IN_FLIGHT_JOIN_MS = 10000;
|
|
20
|
+
/**
|
|
21
|
+
* The window, in whole seconds, a REST API data source caches its upstream
|
|
22
|
+
* response for — or `undefined` when caching is off, which keeps the emitted
|
|
23
|
+
* fetcher exactly what it was before this option existed.
|
|
24
|
+
*/
|
|
25
|
+
var resolveRESTAPICacheTTLSeconds = function (cache) {
|
|
26
|
+
if (!cache || typeof cache !== 'object' || cache.enabled !== true) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
var ttlSeconds = cache.ttlSeconds;
|
|
30
|
+
var seconds = typeof ttlSeconds === 'number' && Number.isFinite(ttlSeconds) && ttlSeconds > 0
|
|
31
|
+
? Math.max(1, Math.floor(ttlSeconds))
|
|
32
|
+
: teleport_shared_1.DataCache.DEFAULT_CACHE_TTL_SECONDS;
|
|
33
|
+
return Math.min(seconds, MAX_TTL_SECONDS);
|
|
34
|
+
};
|
|
35
|
+
exports.resolveRESTAPICacheTTLSeconds = resolveRESTAPICacheTTLSeconds;
|
|
36
|
+
/**
|
|
37
|
+
* Runtime helpers of a cached REST API fetcher.
|
|
38
|
+
*
|
|
39
|
+
* The cache sits under the handler, around the upstream `fetch` only: every
|
|
40
|
+
* caller — the API route, `getStaticProps` through `fetchData`, the count
|
|
41
|
+
* route, the global-state route — asks the same URL, and search, filters, sort
|
|
42
|
+
* and paging are applied to the cached payload afterwards. One upstream call
|
|
43
|
+
* per window therefore serves every page, filter and visitor.
|
|
44
|
+
*
|
|
45
|
+
* - The store lives on `globalThis`, so every data-source module in the
|
|
46
|
+
* process (each API route is its own bundle) shares it. On a serverless host
|
|
47
|
+
* that is one store per warm instance; the `s-maxage` header below is what
|
|
48
|
+
* carries the window to the CDN in front of all of them.
|
|
49
|
+
* - Entries are keyed by the whole upstream request (method, URL, headers,
|
|
50
|
+
* body) and hold the response TEXT: every reader parses its own copy, so a
|
|
51
|
+
* handler that sorts in place can never reorder another request's rows.
|
|
52
|
+
* - Freshness is judged by the READER's window, so two data sources calling
|
|
53
|
+
* the same URL with different windows each get what they asked for.
|
|
54
|
+
* - Only a 2xx JSON response is kept. Errors, non-JSON bodies and network
|
|
55
|
+
* failures reach the caller as before and are retried by the next request.
|
|
56
|
+
*
|
|
57
|
+
* Emitted inside a template literal: no backticks or template placeholders in
|
|
58
|
+
* here, not even in comments.
|
|
59
|
+
*/
|
|
60
|
+
var generateRESTAPIResponseCacheCode = function (ttlSeconds) {
|
|
61
|
+
return "const REST_API_CACHE_TTL_MS = ".concat(ttlSeconds * 1000, "\nconst REST_API_CACHE_MAX_ENTRIES = ").concat(MAX_ENTRIES, "\nconst REST_API_CACHE_MAX_CHARS = ").concat(MAX_CHARS, "\nconst REST_API_IN_FLIGHT_JOIN_MS = ").concat(IN_FLIGHT_JOIN_MS, "\n\n// One store per server process, shared by every REST API data source module.\nif (!globalThis.__tqRestApiCache) {\n globalThis.__tqRestApiCache = { entries: new Map(), inFlight: new Map(), chars: 0 }\n}\nconst restApiCache = globalThis.__tqRestApiCache\n\nfunction restApiCacheKey(url, options) {\n return JSON.stringify([options.method, url, options.headers, options.body === undefined ? null : options.body])\n}\n\nfunction forgetRestApiResponse(key) {\n const entry = restApiCache.entries.get(key)\n if (entry) {\n restApiCache.entries.delete(key)\n restApiCache.chars -= entry.bodyText.length\n }\n}\n\nfunction rememberRestApiResponse(key, entry) {\n forgetRestApiResponse(key)\n if (entry.bodyText.length > REST_API_CACHE_MAX_CHARS) {\n return\n }\n restApiCache.entries.set(key, entry)\n restApiCache.chars += entry.bodyText.length\n // A Map iterates in insertion order and every hit re-inserts its entry, so\n // the first key is always the least recently used one.\n while (\n restApiCache.entries.size > REST_API_CACHE_MAX_ENTRIES ||\n restApiCache.chars > REST_API_CACHE_MAX_CHARS\n ) {\n forgetRestApiResponse(restApiCache.entries.keys().next().value)\n }\n}\n\nasync function requestRestApi(url, options) {\n const response = await fetch(url, options)\n if (!response.ok) {\n return { ok: false, status: response.status, statusText: response.statusText }\n }\n const bodyText = await response.text()\n // Parsed once here so a body that is not JSON fails this request, as\n // response.json() would, instead of being cached and failing every request\n // until the window ends.\n JSON.parse(bodyText)\n return {\n ok: true,\n status: response.status,\n statusText: response.statusText,\n bodyText,\n fetchedAt: Date.now(),\n }\n}\n\nfunction fetchRestApiWithCache(url, options) {\n const key = restApiCacheKey(url, options)\n const now = Date.now()\n\n const cached = restApiCache.entries.get(key)\n if (cached && now >= cached.fetchedAt && now - cached.fetchedAt < REST_API_CACHE_TTL_MS) {\n restApiCache.entries.delete(key)\n restApiCache.entries.set(key, cached)\n return Promise.resolve(cached)\n }\n\n // Concurrent misses share one upstream call instead of each making their own.\n const pending = restApiCache.inFlight.get(key)\n if (pending && now - pending.startedAt < REST_API_IN_FLIGHT_JOIN_MS) {\n return pending.promise\n }\n\n const flight = { startedAt: now, promise: null }\n const release = () => {\n if (restApiCache.inFlight.get(key) === flight) {\n restApiCache.inFlight.delete(key)\n }\n }\n flight.promise = requestRestApi(url, options).then(\n (result) => {\n release()\n if (result.ok) {\n rememberRestApiResponse(key, result)\n }\n return result\n },\n (error) => {\n release()\n throw error\n }\n )\n restApiCache.inFlight.set(key, flight)\n return flight.promise\n}\n\n// Lets the CDN answer this exact URL until the upstream response it was built\n// from expires, so neither layer serves it longer than the window. Only a real\n// GET response gets the header: fetchData, fetchCount and tqWithCache call the\n// handler with a bare { status, json } object.\nfunction applyRestApiCacheHeaders(req, res, fetchedAt) {\n if (!req || req.method !== 'GET' || !res || typeof res.setHeader !== 'function') {\n return\n }\n const remainingSeconds = Math.floor((fetchedAt + REST_API_CACHE_TTL_MS - Date.now()) / 1000)\n if (remainingSeconds > 0) {\n res.setHeader('Cache-Control', 'public, max-age=0, s-maxage=' + remainingSeconds)\n }\n}");
|
|
62
|
+
};
|
|
63
|
+
exports.generateRESTAPIResponseCacheCode = generateRESTAPIResponseCacheCode;
|
|
64
|
+
//# sourceMappingURL=rest-api-response-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest-api-response-cache.js","sourceRoot":"","sources":["../../../../src/fetchers/utils/rest-api-response-cache.ts"],"names":[],"mappings":";;;AAAA,+DAAuD;AAWvD,6EAA6E;AAC7E,IAAM,eAAe,GAAG,QAAU,CAAA;AAElC;;;;GAIG;AACH,IAAM,WAAW,GAAG,GAAG,CAAA;AACvB,IAAM,SAAS,GAAG,QAAU,CAAA;AAE5B;;;;GAIG;AACH,IAAM,iBAAiB,GAAG,KAAM,CAAA;AAEhC;;;;GAIG;AACI,IAAM,6BAA6B,GAAG,UAC3C,KAAqC;IAErC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE;QACjE,OAAO,SAAS,CAAA;KACjB;IAEO,IAAA,UAAU,GAAK,KAAK,WAAV,CAAU;IAC5B,IAAM,OAAO,GACX,OAAO,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC;QAC7E,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC,CAAC,2BAAS,CAAC,yBAAyB,CAAA;IAEzC,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;AAC3C,CAAC,CAAA;AAdY,QAAA,6BAA6B,iCAczC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACI,IAAM,gCAAgC,GAAG,UAAC,UAAkB;IACjE,OAAO,wCAAiC,UAAU,GAAG,IAAI,kDACtB,WAAW,gDACb,SAAS,kDACP,iBAAiB,yjHA4GpD,CAAA;AACF,CAAC,CAAA;AAjHY,QAAA,gCAAgC,oCAiH5C"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The money-table guard for a generated per-table read route
|
|
3
|
+
* (`/api/teleport-<table>-<source>` and its `-count` twin).
|
|
4
|
+
*
|
|
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.
|
|
14
|
+
*/
|
|
15
|
+
/** Declares the session resolver and the `__ta*` guard once per module. */
|
|
16
|
+
export declare const generateTableAccessPreamble: (trustedReaderRoles: ReadonlyArray<string>) => string;
|
|
17
|
+
/**
|
|
18
|
+
* The early return at the top of a handler, before the client connects:
|
|
19
|
+
* `tableName` is the module's table, `rawQueryExpr` the request's raw statement
|
|
20
|
+
* (or `null` where the handler accepts none).
|
|
21
|
+
*/
|
|
22
|
+
export declare const generateReadGuardCall: (tableName: string, rawQueryExpr: string | null) => string;
|
|
23
|
+
//# sourceMappingURL=table-access-guard.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateReadGuardCall = exports.generateTableAccessPreamble = void 0;
|
|
4
|
+
var teleport_shared_1 = require("@teleporthq/teleport-shared");
|
|
5
|
+
var browser_row_policy_1 = require("./browser-row-policy");
|
|
6
|
+
/**
|
|
7
|
+
* The money-table guard for a generated per-table read route
|
|
8
|
+
* (`/api/teleport-<table>-<source>` and its `-count` twin).
|
|
9
|
+
*
|
|
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.
|
|
19
|
+
*/
|
|
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)());
|
|
23
|
+
};
|
|
24
|
+
exports.generateTableAccessPreamble = generateTableAccessPreamble;
|
|
25
|
+
/**
|
|
26
|
+
* The early return at the top of a handler, before the client connects:
|
|
27
|
+
* `tableName` is the module's table, `rawQueryExpr` the request's raw statement
|
|
28
|
+
* (or `null` where the handler accepts none).
|
|
29
|
+
*/
|
|
30
|
+
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));
|
|
32
|
+
};
|
|
33
|
+
exports.generateReadGuardCall = generateReadGuardCall;
|
|
34
|
+
//# sourceMappingURL=table-access-guard.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as types from '@babel/types';
|
|
2
|
+
export declare const extractItemsPath: (source: unknown, dataSourceIdentifier: string, dataSourceType: string) => string[] | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* Push `<key>: '["templates"]'` onto a params object. Fetch calls send it as
|
|
5
|
+
* `itemsPath` (process the inner array, keep the wrapper the page reads back
|
|
6
|
+
* through); count calls send it as `collectionPath`, so the count handler
|
|
7
|
+
* measures the inner array instead of the wrapper.
|
|
8
|
+
*/
|
|
9
|
+
export declare const appendItemsPathParam: (paramsProps: types.ObjectProperty[], itemsPath: string[] | undefined, key: 'itemsPath' | 'collectionPath') => void;
|
|
10
|
+
//# sourceMappingURL=items-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"items-path.d.ts","sourceRoot":"","sources":["../../src/items-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAsBrC,eAAO,MAAM,gBAAgB,WACnB,OAAO,wBACO,MAAM,kBACZ,MAAM,KACrB,MAAM,EAAE,GAAG,SA4Bb,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,gBAClB,MAAM,cAAc,EAAE,aACxB,MAAM,EAAE,GAAG,SAAS,OAC1B,WAAW,GAAG,gBAAgB,KAClC,IAOF,CAAA"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.appendItemsPathParam = exports.extractItemsPath = void 0;
|
|
27
|
+
var types = __importStar(require("@babel/types"));
|
|
28
|
+
/**
|
|
29
|
+
* Where a paginated/searchable list's rows sit inside the payload its data
|
|
30
|
+
* source returns, read off the repeater's `source` expression.
|
|
31
|
+
*
|
|
32
|
+
* A REST API or JavaScript source may answer `{ templates: [...], total }`, and
|
|
33
|
+
* the editor binds the list to `All_Templates_data_data?.templates || []`. The
|
|
34
|
+
* generated fetcher only searches, filters, sorts and slices a payload that IS
|
|
35
|
+
* an array, so without this every row came back on every page (the canvas
|
|
36
|
+
* slices on the client and looked right) and the count measured the wrapper as
|
|
37
|
+
* 0 rows, disabling "Next".
|
|
38
|
+
*
|
|
39
|
+
* Returns undefined when the list is bound to the payload itself, or when the
|
|
40
|
+
* source is anything other than a plain property chain off the data source's
|
|
41
|
+
* render prop — an expression this cannot read is left exactly as before.
|
|
42
|
+
*/
|
|
43
|
+
var SEGMENT_RE = /^(?:\?\.([A-Za-z_$][\w$]*)|\.([A-Za-z_$][\w$]*)|(?:\?\.)?\[\s*(?:"([^"]*)"|'([^']*)')\s*\])/;
|
|
44
|
+
var PATH_AWARE_SOURCE_TYPES = new Set(['rest-api', 'javascript']);
|
|
45
|
+
var extractItemsPath = function (source, dataSourceIdentifier, dataSourceType) {
|
|
46
|
+
var _a, _b, _c;
|
|
47
|
+
if (typeof source !== 'string' || !dataSourceIdentifier) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
if (!PATH_AWARE_SOURCE_TYPES.has(dataSourceType)) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
var rest = source
|
|
54
|
+
.trim()
|
|
55
|
+
.replace(/\s*\|\|\s*\[\s*\]$/, '')
|
|
56
|
+
.trim();
|
|
57
|
+
if (!rest.startsWith(dataSourceIdentifier)) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
rest = rest.slice(dataSourceIdentifier.length);
|
|
61
|
+
var path = [];
|
|
62
|
+
while (rest.length > 0) {
|
|
63
|
+
var match = rest.match(SEGMENT_RE);
|
|
64
|
+
if (!match) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
path.push((_c = (_b = (_a = match[1]) !== null && _a !== void 0 ? _a : match[2]) !== null && _b !== void 0 ? _b : match[3]) !== null && _c !== void 0 ? _c : match[4]);
|
|
68
|
+
rest = rest.slice(match[0].length);
|
|
69
|
+
}
|
|
70
|
+
return path.length > 0 ? path : undefined;
|
|
71
|
+
};
|
|
72
|
+
exports.extractItemsPath = extractItemsPath;
|
|
73
|
+
/**
|
|
74
|
+
* Push `<key>: '["templates"]'` onto a params object. Fetch calls send it as
|
|
75
|
+
* `itemsPath` (process the inner array, keep the wrapper the page reads back
|
|
76
|
+
* through); count calls send it as `collectionPath`, so the count handler
|
|
77
|
+
* measures the inner array instead of the wrapper.
|
|
78
|
+
*/
|
|
79
|
+
var appendItemsPathParam = function (paramsProps, itemsPath, key) {
|
|
80
|
+
if (!itemsPath || itemsPath.length === 0) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
paramsProps.push(types.objectProperty(types.identifier(key), types.stringLiteral(JSON.stringify(itemsPath))));
|
|
84
|
+
};
|
|
85
|
+
exports.appendItemsPathParam = appendItemsPathParam;
|
|
86
|
+
//# sourceMappingURL=items-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"items-path.js","sourceRoot":"","sources":["../../src/items-path.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAqC;AAErC;;;;;;;;;;;;;;GAcG;AACH,IAAM,UAAU,GACd,6FAA6F,CAAA;AAE/F,IAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAA;AAE5D,IAAM,gBAAgB,GAAG,UAC9B,MAAe,EACf,oBAA4B,EAC5B,cAAsB;;IAEtB,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,oBAAoB,EAAE;QACvD,OAAO,SAAS,CAAA;KACjB;IACD,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE;QAChD,OAAO,SAAS,CAAA;KACjB;IAED,IAAI,IAAI,GAAG,MAAM;SACd,IAAI,EAAE;SACN,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;SACjC,IAAI,EAAE,CAAA;IACT,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE;QAC1C,OAAO,SAAS,CAAA;KACjB;IACD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAA;IAE9C,IAAM,IAAI,GAAa,EAAE,CAAA;IACzB,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;QACtB,IAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QACpC,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,SAAS,CAAA;SACjB;QACD,IAAI,CAAC,IAAI,CAAC,MAAA,MAAA,MAAA,KAAK,CAAC,CAAC,CAAC,mCAAI,KAAK,CAAC,CAAC,CAAC,mCAAI,KAAK,CAAC,CAAC,CAAC,mCAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACvD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;KACnC;IAED,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AAC3C,CAAC,CAAA;AAhCY,QAAA,gBAAgB,oBAgC5B;AAED;;;;;GAKG;AACI,IAAM,oBAAoB,GAAG,UAClC,WAAmC,EACnC,SAA+B,EAC/B,GAAmC;IAEnC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;QACxC,OAAM;KACP;IACD,WAAW,CAAC,IAAI,CACd,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAC5F,CAAA;AACH,CAAC,CAAA;AAXY,QAAA,oBAAoB,wBAWhC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localized-columns.d.ts","sourceRoot":"","sources":["../../src/localized-columns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEjE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAQvE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,gBACrB,MAAM,EAAE,gBACP,mBAAmB,GAAG,SAAS,KAC5C,kBAmBF,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,aAAc,kBAAkB,KAAG,
|
|
1
|
+
{"version":3,"file":"localized-columns.d.ts","sourceRoot":"","sources":["../../src/localized-columns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAEjE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAQvE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,gBACrB,MAAM,EAAE,gBACP,mBAAmB,GAAG,SAAS,KAC5C,kBAmBF,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,aAAc,kBAAkB,KAAG,MA2D7E,CAAA"}
|
|
@@ -107,6 +107,19 @@ var generateLocalizedColumnsHelper = function (families) {
|
|
|
107
107
|
" return '(' + clauses.join(' OR ') + ')'",
|
|
108
108
|
'}',
|
|
109
109
|
'',
|
|
110
|
+
'// A translatable list (tags) and its per-language copies, for a filter that',
|
|
111
|
+
'// matches a value in ANY language (a localized tag link resolves under every',
|
|
112
|
+
'// locale, like a localized slug). Null for a column with no copies.',
|
|
113
|
+
'function localizedColumnList(field) {',
|
|
114
|
+
' var copies = LOCALIZED_COLUMNS[field]',
|
|
115
|
+
' if (!copies) return null',
|
|
116
|
+
' var columns = [quoteLocalizedColumn(field)]',
|
|
117
|
+
' for (var locale in copies) {',
|
|
118
|
+
' if (Object.prototype.hasOwnProperty.call(copies, locale)) columns.push(quoteLocalizedColumn(copies[locale]))',
|
|
119
|
+
' }',
|
|
120
|
+
' return columns',
|
|
121
|
+
'}',
|
|
122
|
+
'',
|
|
110
123
|
"// ORDER BY a translatable column in the request's language, falling back to",
|
|
111
124
|
'// the base column for a row with no translation — the same resolution the',
|
|
112
125
|
'// row transform applies to what is displayed. Null when the field or the',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localized-columns.js","sourceRoot":"","sources":["../../src/localized-columns.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;;AAUH,oGAAoG;AACpG,IAAM,sBAAsB,GAAG,0BAA0B,CAAA;AAEzD,kFAAkF;AAClF,IAAM,mBAAmB,GAAG,UAAC,MAAc,EAAE,MAAc,IAAa,OAAA,UAAG,MAAM,cAAI,MAAM,CAAE,EAArB,CAAqB,CAAA;AAE7F;;;;GAIG;AACI,IAAM,uBAAuB,GAAG,UACrC,WAAqB,EACrB,YAA6C;IAE7C,IAAM,QAAQ,GAAuB,EAAE,CAAA;IACvC,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/D,OAAO,QAAQ,CAAA;KAChB;IACD,IAAM,OAAO,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,UAAC,IAAI,IAAK,OAAA,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAjC,CAAiC,CAAC,CAAC,CAAA;IACxF,OAAO,CAAC,OAAO,CAAC,UAAC,MAAM;QACrB,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAC,MAAM;YAC3C,IAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YAChD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBACtB,OAAM;aACP;YACD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBACrB,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;aACtB;YACD,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;QACjC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAtBY,QAAA,uBAAuB,2BAsBnC;AAED;;;;;;;GAOG;AACI,IAAM,8BAA8B,GAAG,UAAC,QAA4B;IACzE,IAAM,KAAK,GAAG;QACZ,oFAAoF;QACpF,8EAA8E;QAC9E,kCAA2B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAE;QACrD,EAAE;QACF,yCAAyC;QACzC,+BAA+B;QAC/B,GAAG;QACH,EAAE;QACF,8EAA8E;QAC9E,4EAA4E;QAC5E,+EAA+E;QAC/E,sEAAsE;QACtE,yCAAyC;QACzC,wFAAwF;QACxF,+EAA+E;QAC/E,+DAA+D;QAC/D,yBAAyB;QACzB,gCAAgC;QAChC,4FAA4F;QAC5F,KAAK;QACL,sFAAsF;QACtF,oBAAoB;QACpB,8CAA8C;QAC9C,mBAAmB;QACnB,4BAA4B;QAC5B,oFAAoF;QACpF,4DAA4D;QAC5D,OAAO;QACP,KAAK;QACL,2CAA2C;QAC3C,GAAG;QACH,EAAE;QACF,8EAA8E;QAC9E,4EAA4E;QAC5E,2EAA2E;QAC3E,mDAAmD;QACnD,iDAAiD;QACjD,yCAAyC;QACzC,2EAA2E;QAC3E,0BAA0B;QAC1B,4GAA4G;QAC5G,GAAG;KACJ,CAAA;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"localized-columns.js","sourceRoot":"","sources":["../../src/localized-columns.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;;AAUH,oGAAoG;AACpG,IAAM,sBAAsB,GAAG,0BAA0B,CAAA;AAEzD,kFAAkF;AAClF,IAAM,mBAAmB,GAAG,UAAC,MAAc,EAAE,MAAc,IAAa,OAAA,UAAG,MAAM,cAAI,MAAM,CAAE,EAArB,CAAqB,CAAA;AAE7F;;;;GAIG;AACI,IAAM,uBAAuB,GAAG,UACrC,WAAqB,EACrB,YAA6C;IAE7C,IAAM,QAAQ,GAAuB,EAAE,CAAA;IACvC,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/D,OAAO,QAAQ,CAAA;KAChB;IACD,IAAM,OAAO,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,UAAC,IAAI,IAAK,OAAA,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAjC,CAAiC,CAAC,CAAC,CAAA;IACxF,OAAO,CAAC,OAAO,CAAC,UAAC,MAAM;QACrB,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAC,MAAM;YAC3C,IAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;YAChD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBACtB,OAAM;aACP;YACD,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBACrB,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAA;aACtB;YACD,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;QACjC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAtBY,QAAA,uBAAuB,2BAsBnC;AAED;;;;;;;GAOG;AACI,IAAM,8BAA8B,GAAG,UAAC,QAA4B;IACzE,IAAM,KAAK,GAAG;QACZ,oFAAoF;QACpF,8EAA8E;QAC9E,kCAA2B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAE;QACrD,EAAE;QACF,yCAAyC;QACzC,+BAA+B;QAC/B,GAAG;QACH,EAAE;QACF,8EAA8E;QAC9E,4EAA4E;QAC5E,+EAA+E;QAC/E,sEAAsE;QACtE,yCAAyC;QACzC,wFAAwF;QACxF,+EAA+E;QAC/E,+DAA+D;QAC/D,yBAAyB;QACzB,gCAAgC;QAChC,4FAA4F;QAC5F,KAAK;QACL,sFAAsF;QACtF,oBAAoB;QACpB,8CAA8C;QAC9C,mBAAmB;QACnB,4BAA4B;QAC5B,oFAAoF;QACpF,4DAA4D;QAC5D,OAAO;QACP,KAAK;QACL,2CAA2C;QAC3C,GAAG;QACH,EAAE;QACF,8EAA8E;QAC9E,+EAA+E;QAC/E,sEAAsE;QACtE,uCAAuC;QACvC,yCAAyC;QACzC,4BAA4B;QAC5B,+CAA+C;QAC/C,gCAAgC;QAChC,kHAAkH;QAClH,KAAK;QACL,kBAAkB;QAClB,GAAG;QACH,EAAE;QACF,8EAA8E;QAC9E,4EAA4E;QAC5E,2EAA2E;QAC3E,mDAAmD;QACnD,iDAAiD;QACjD,yCAAyC;QACzC,2EAA2E;QAC3E,0BAA0B;QAC1B,4GAA4G;QAC5G,GAAG;KACJ,CAAA;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC,CAAA;AA3DY,QAAA,8BAA8B,kCA2D1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"pagination-plugin.d.ts","sourceRoot":"","sources":["../../src/pagination-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,EAGvB,MAAM,4BAA4B,CAAA;AAqkCnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CAs1B5E,CAAA"}
|