@teleporthq/teleport-plugin-next-data-source 0.43.66 → 0.43.67
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-mapper-cache-wiring.test.ts +11 -0
- package/__tests__/data-source-request-locale.test.ts +313 -0
- package/__tests__/gated-data-provider.test.ts +88 -0
- package/__tests__/localized-columns.test.ts +217 -0
- package/__tests__/numbered-pagination.test.ts +15 -0
- package/__tests__/product-filter-fields.ts +230 -0
- package/__tests__/product-filter-sql.fixture.json +7 -0
- package/__tests__/refetch-loading-state.test.ts +23 -0
- package/__tests__/search-clear-button.test.ts +122 -0
- package/dist/cjs/content-localization.d.ts +37 -0
- package/dist/cjs/content-localization.d.ts.map +1 -0
- package/dist/cjs/content-localization.js +29 -0
- package/dist/cjs/content-localization.js.map +1 -0
- package/dist/cjs/count-effect.d.ts +11 -1
- package/dist/cjs/count-effect.d.ts.map +1 -1
- package/dist/cjs/count-effect.js +30 -2
- package/dist/cjs/count-effect.js.map +1 -1
- package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
- package/dist/cjs/fetchers/airtable.js +1 -1
- package/dist/cjs/fetchers/airtable.js.map +1 -1
- package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
- package/dist/cjs/fetchers/clickhouse.js +1 -1
- package/dist/cjs/fetchers/clickhouse.js.map +1 -1
- package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
- package/dist/cjs/fetchers/firestore.js +1 -1
- package/dist/cjs/fetchers/firestore.js.map +1 -1
- package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
- package/dist/cjs/fetchers/mariadb.js +1 -1
- package/dist/cjs/fetchers/mariadb.js.map +1 -1
- package/dist/cjs/fetchers/mongodb.d.ts.map +1 -1
- package/dist/cjs/fetchers/mongodb.js +1 -1
- package/dist/cjs/fetchers/mongodb.js.map +1 -1
- package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
- package/dist/cjs/fetchers/mysql.js +1 -1
- package/dist/cjs/fetchers/mysql.js.map +1 -1
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
- package/dist/cjs/fetchers/postgresql.js +2 -1
- package/dist/cjs/fetchers/postgresql.js.map +1 -1
- package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
- package/dist/cjs/fetchers/redshift.js +1 -1
- package/dist/cjs/fetchers/redshift.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +10 -3
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/fetchers/turso.d.ts.map +1 -1
- package/dist/cjs/fetchers/turso.js +1 -1
- package/dist/cjs/fetchers/turso.js.map +1 -1
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +60 -8
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/loading-state.d.ts +16 -1
- package/dist/cjs/loading-state.d.ts.map +1 -1
- package/dist/cjs/loading-state.js +69 -3
- package/dist/cjs/loading-state.js.map +1 -1
- package/dist/cjs/localized-columns.d.ts +56 -0
- package/dist/cjs/localized-columns.d.ts.map +1 -0
- package/dist/cjs/localized-columns.js +124 -0
- package/dist/cjs/localized-columns.js.map +1 -0
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +123 -45
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/product-filter-fields.d.ts +87 -0
- package/dist/cjs/product-filter-fields.d.ts.map +1 -0
- package/dist/cjs/product-filter-fields.js +161 -0
- package/dist/cjs/product-filter-fields.js.map +1 -0
- package/dist/cjs/request-locale.d.ts +49 -0
- package/dist/cjs/request-locale.d.ts.map +1 -0
- package/dist/cjs/request-locale.js +130 -0
- package/dist/cjs/request-locale.js.map +1 -0
- package/dist/cjs/search-clear.d.ts +31 -0
- package/dist/cjs/search-clear.d.ts.map +1 -0
- package/dist/cjs/search-clear.js +103 -0
- package/dist/cjs/search-clear.js.map +1 -0
- package/dist/cjs/transformations/index.d.ts +16 -2
- package/dist/cjs/transformations/index.d.ts.map +1 -1
- package/dist/cjs/transformations/index.js +14 -2
- package/dist/cjs/transformations/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +11 -1
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +59 -15
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/content-localization.d.ts +37 -0
- package/dist/esm/content-localization.d.ts.map +1 -0
- package/dist/esm/content-localization.js +24 -0
- package/dist/esm/content-localization.js.map +1 -0
- package/dist/esm/count-effect.d.ts +11 -1
- package/dist/esm/count-effect.d.ts.map +1 -1
- package/dist/esm/count-effect.js +28 -1
- package/dist/esm/count-effect.js.map +1 -1
- package/dist/esm/fetchers/airtable.d.ts.map +1 -1
- package/dist/esm/fetchers/airtable.js +1 -1
- package/dist/esm/fetchers/airtable.js.map +1 -1
- package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
- package/dist/esm/fetchers/clickhouse.js +1 -1
- package/dist/esm/fetchers/clickhouse.js.map +1 -1
- package/dist/esm/fetchers/firestore.d.ts.map +1 -1
- package/dist/esm/fetchers/firestore.js +1 -1
- package/dist/esm/fetchers/firestore.js.map +1 -1
- package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
- package/dist/esm/fetchers/mariadb.js +1 -1
- package/dist/esm/fetchers/mariadb.js.map +1 -1
- package/dist/esm/fetchers/mongodb.d.ts.map +1 -1
- package/dist/esm/fetchers/mongodb.js +1 -1
- package/dist/esm/fetchers/mongodb.js.map +1 -1
- package/dist/esm/fetchers/mysql.d.ts.map +1 -1
- package/dist/esm/fetchers/mysql.js +1 -1
- package/dist/esm/fetchers/mysql.js.map +1 -1
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
- package/dist/esm/fetchers/postgresql.js +2 -1
- package/dist/esm/fetchers/postgresql.js.map +1 -1
- package/dist/esm/fetchers/redshift.d.ts.map +1 -1
- package/dist/esm/fetchers/redshift.js +1 -1
- package/dist/esm/fetchers/redshift.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +10 -3
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/fetchers/turso.d.ts.map +1 -1
- package/dist/esm/fetchers/turso.js +1 -1
- package/dist/esm/fetchers/turso.js.map +1 -1
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +55 -7
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/loading-state.d.ts +16 -1
- package/dist/esm/loading-state.d.ts.map +1 -1
- package/dist/esm/loading-state.js +69 -3
- package/dist/esm/loading-state.js.map +1 -1
- package/dist/esm/localized-columns.d.ts +56 -0
- package/dist/esm/localized-columns.d.ts.map +1 -0
- package/dist/esm/localized-columns.js +119 -0
- package/dist/esm/localized-columns.js.map +1 -0
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +124 -46
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/product-filter-fields.d.ts +87 -0
- package/dist/esm/product-filter-fields.d.ts.map +1 -0
- package/dist/esm/product-filter-fields.js +154 -0
- package/dist/esm/product-filter-fields.js.map +1 -0
- package/dist/esm/request-locale.d.ts +49 -0
- package/dist/esm/request-locale.d.ts.map +1 -0
- package/dist/esm/request-locale.js +98 -0
- package/dist/esm/request-locale.js.map +1 -0
- package/dist/esm/search-clear.d.ts +31 -0
- package/dist/esm/search-clear.d.ts.map +1 -0
- package/dist/esm/search-clear.js +74 -0
- package/dist/esm/search-clear.js.map +1 -0
- package/dist/esm/transformations/index.d.ts +16 -2
- package/dist/esm/transformations/index.d.ts.map +1 -1
- package/dist/esm/transformations/index.js +14 -2
- package/dist/esm/transformations/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +11 -1
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +59 -15
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/content-localization.ts +53 -0
- package/src/count-effect.ts +53 -2
- package/src/fetchers/airtable.ts +4 -2
- package/src/fetchers/clickhouse.ts +4 -2
- package/src/fetchers/firestore.ts +4 -2
- package/src/fetchers/mariadb.ts +4 -2
- package/src/fetchers/mongodb.ts +4 -2
- package/src/fetchers/mysql.ts +4 -2
- package/src/fetchers/postgresql.ts +16 -2
- package/src/fetchers/redshift.ts +4 -2
- package/src/fetchers/teleport.ts +48 -9
- package/src/fetchers/turso.ts +4 -2
- package/src/index.ts +79 -11
- package/src/loading-state.ts +134 -3
- package/src/localized-columns.ts +133 -0
- package/src/pagination-plugin.ts +177 -53
- package/src/product-filter-fields.ts +173 -0
- package/src/request-locale.ts +113 -0
- package/src/search-clear.ts +102 -0
- package/src/transformations/index.ts +30 -5
- package/src/utils.ts +83 -15
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filtering and sorting a translatable column in the visitor's language.
|
|
3
|
+
*
|
|
4
|
+
* A translatable column of a platform table exists once per language:
|
|
5
|
+
* `slug` holds the main language and `es_slug` the Spanish copy (see
|
|
6
|
+
* `ContentLocalization`). The row transform resolves what a page DISPLAYS —
|
|
7
|
+
* a Spanish listing shows `es_name` and links to `es_slug` — but the SQL a
|
|
8
|
+
* fetch runs still names the base column, so without this file:
|
|
9
|
+
*
|
|
10
|
+
* - the details page a Spanish card links to (`/es/products/<es_slug>`)
|
|
11
|
+
* looks the row up with `slug = $1` and answers 404;
|
|
12
|
+
* - "sort by name" on the Spanish listing orders the Spanish names by
|
|
13
|
+
* their ENGLISH counterparts.
|
|
14
|
+
*
|
|
15
|
+
* The teleport fetcher (`fetchers/teleport.ts`) therefore embeds the helper
|
|
16
|
+
* emitted here:
|
|
17
|
+
*
|
|
18
|
+
* - equality on a translatable column matches the value in ANY language:
|
|
19
|
+
* `("slug" = $1 OR "es_slug" = $1)`. Deliberately every language, not the
|
|
20
|
+
* request's: the language switcher keeps the URL and changes the locale,
|
|
21
|
+
* so `/products/<es_slug>` (English page, Spanish slug) has to resolve as
|
|
22
|
+
* well as `/es/products/<slug>`. Only `=` (and the `in` it is normalised
|
|
23
|
+
* to) — a translatable column is never compared with `<`, and `!=` on one
|
|
24
|
+
* has no sensible cross-language reading;
|
|
25
|
+
* - ordering by a translatable column orders by the REQUEST's language,
|
|
26
|
+
* falling back to the base column exactly like the transform does:
|
|
27
|
+
* `COALESCE(NULLIF("es_name", ''), "name")`.
|
|
28
|
+
*
|
|
29
|
+
* Which columns take part is decided at GENERATION time from the table's
|
|
30
|
+
* schema and the project's languages — never by prefix-sniffing column names,
|
|
31
|
+
* which would mistake `og_title` for a translation. A copy the schema does not
|
|
32
|
+
* list (a language added before a column became translatable) is simply not
|
|
33
|
+
* referenced, so the SQL can only ever name columns that exist.
|
|
34
|
+
*/
|
|
35
|
+
/** The only identifiers the generated SQL is allowed to quote — same rule as the search columns. */
|
|
36
|
+
var SQL_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
37
|
+
/** The column holding `column` in `locale` — the editor's `getI18nColumnName`. */
|
|
38
|
+
var localizedColumnName = function (locale, column) { return "".concat(locale, "_").concat(column); };
|
|
39
|
+
/**
|
|
40
|
+
* Pairs every column with the per-language copies the schema actually holds.
|
|
41
|
+
* Empty (no families) when the project has one language or the table has no
|
|
42
|
+
* translated column — the emitted helper is then inert.
|
|
43
|
+
*/
|
|
44
|
+
export var collectLocalizedColumns = function (columnNames, localization) {
|
|
45
|
+
var families = {};
|
|
46
|
+
if (!localization || localization.secondaryLocales.length === 0) {
|
|
47
|
+
return families;
|
|
48
|
+
}
|
|
49
|
+
var present = new Set(columnNames.filter(function (name) { return SQL_IDENTIFIER_PATTERN.test(name); }));
|
|
50
|
+
present.forEach(function (column) {
|
|
51
|
+
localization.secondaryLocales.forEach(function (locale) {
|
|
52
|
+
var copy = localizedColumnName(locale, column);
|
|
53
|
+
if (!present.has(copy)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (!families[column]) {
|
|
57
|
+
families[column] = {};
|
|
58
|
+
}
|
|
59
|
+
families[column][locale] = copy;
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
return families;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The `localizedEqualityClause` / `localizedSortFieldSql` helpers a fetcher
|
|
66
|
+
* embeds, with the column map baked in.
|
|
67
|
+
*
|
|
68
|
+
* Emitted as plain source with no backtick and no `${`, because the fetcher
|
|
69
|
+
* interpolates it into a template literal. Every identifier it quotes comes
|
|
70
|
+
* from the baked map, so a request can only ever name a column the schema had.
|
|
71
|
+
*/
|
|
72
|
+
export var generateLocalizedColumnsHelper = function (families) {
|
|
73
|
+
var lines = [
|
|
74
|
+
'// Per-language copies of the translatable columns, base column -> locale -> copy.',
|
|
75
|
+
'// Baked from the table schema and the project languages at generation time.',
|
|
76
|
+
"var LOCALIZED_COLUMNS = ".concat(JSON.stringify(families)),
|
|
77
|
+
'',
|
|
78
|
+
'function quoteLocalizedColumn(column) {',
|
|
79
|
+
" return '\"' + column + '\"'",
|
|
80
|
+
'}',
|
|
81
|
+
'',
|
|
82
|
+
'// Equality on a translatable column matches the value in ANY language, so a',
|
|
83
|
+
'// localized slug resolves whichever locale the URL is under. Answers null',
|
|
84
|
+
'// for every other column and operand, leaving them to the ordinary branches.',
|
|
85
|
+
'function localizedEqualityClause(field, operand, value, pushParam) {',
|
|
86
|
+
' var copies = LOCALIZED_COLUMNS[field]',
|
|
87
|
+
" if (!copies || operand !== '=' || value === null || value === undefined) return null",
|
|
88
|
+
' // An empty set means "no filter", as it does in the ordinary array branch.',
|
|
89
|
+
' if (Array.isArray(value) && value.length === 0) return null',
|
|
90
|
+
' var columns = [field]',
|
|
91
|
+
' for (var locale in copies) {',
|
|
92
|
+
' if (Object.prototype.hasOwnProperty.call(copies, locale)) columns.push(copies[locale])',
|
|
93
|
+
' }',
|
|
94
|
+
' var param = Array.isArray(value) ? pushParam(value.map(String)) : pushParam(value)',
|
|
95
|
+
' var clauses = []',
|
|
96
|
+
' for (var i = 0; i < columns.length; i++) {',
|
|
97
|
+
' clauses.push(',
|
|
98
|
+
' Array.isArray(value)',
|
|
99
|
+
" ? quoteLocalizedColumn(columns[i]) + '::text = ANY(' + param + '::text[])'",
|
|
100
|
+
" : quoteLocalizedColumn(columns[i]) + ' = ' + param",
|
|
101
|
+
' )',
|
|
102
|
+
' }',
|
|
103
|
+
" return '(' + clauses.join(' OR ') + ')'",
|
|
104
|
+
'}',
|
|
105
|
+
'',
|
|
106
|
+
"// ORDER BY a translatable column in the request's language, falling back to",
|
|
107
|
+
'// the base column for a row with no translation — the same resolution the',
|
|
108
|
+
'// row transform applies to what is displayed. Null when the field or the',
|
|
109
|
+
'// locale has no copy, so the ordinary sort runs.',
|
|
110
|
+
'function localizedSortFieldSql(field, locale) {',
|
|
111
|
+
' var copies = LOCALIZED_COLUMNS[field]',
|
|
112
|
+
" var copy = copies && typeof locale === 'string' ? copies[locale] : null",
|
|
113
|
+
' if (!copy) return null',
|
|
114
|
+
" return 'COALESCE(NULLIF(' + quoteLocalizedColumn(copy) + \", ''), \" + quoteLocalizedColumn(field) + ')'",
|
|
115
|
+
'}',
|
|
116
|
+
];
|
|
117
|
+
return lines.join('\n');
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=localized-columns.js.map
|
|
@@ -0,0 +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;AACH,MAAM,CAAC,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;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,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 +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;AA4jCnC,eAAO,MAAM,qCAAqC,EAAE,sBAAsB,CAAC,EAAE,CAo1B5E,CAAA"}
|
|
@@ -57,11 +57,14 @@ import { applyLoadingStateToDataProvider, buildLoadingStateDeclarations, getLoad
|
|
|
57
57
|
import { mergeServerCacheOptions, resolveCacheFromRepeaterContent } from './cache/config';
|
|
58
58
|
import { buildCacheHydrationEffect, buildCacheStoreThen, buildCachedFetchBody, buildCachedParamsDeclarations, registerCacheClientImports, } from './cache/ast';
|
|
59
59
|
import { convertControlToButton, dropInactivePaginationControls, findPaginationControl, setJSXExpressionAttribute, } from './pagination-controls';
|
|
60
|
-
import { buildCountFetchEffect } from './count-effect';
|
|
60
|
+
import { buildCountFetchEffect, buildCountSeqDeclaration } from './count-effect';
|
|
61
|
+
import { findAllSearchClearButtonsInJSX, findSiblingSearchInput, wireSearchClearButton, } from './search-clear';
|
|
61
62
|
import { buildPageTokensDeclaration, wireNumberedPagination, } from './numbered-pagination';
|
|
62
63
|
import { buildAccumulatingResponseHandler, buildInfiniteScrollDeclarations, buildSentinelElement, buildSentinelObserverEffect, getInfiniteScrollVars, } from './infinite-scroll';
|
|
63
64
|
import { buildFilterSortPageResetEffect, buildPageResetRefDeclaration, hasNoPageResetDeps, } from './page-reset';
|
|
64
65
|
import { buildPageUrlRefDeclaration, buildPageUrlSyncEffect } from './page-url-sync';
|
|
66
|
+
import { isLocalizedProject } from './content-localization';
|
|
67
|
+
import { appendClientLocaleParam, buildClientLocaleExpression, buildServerLocaleParam, ensureRouterDeclaration, hasLocaleParam, } from './request-locale';
|
|
65
68
|
// tslint:disable-next-line:no-any
|
|
66
69
|
function parseSearchDefaultValue(raw) {
|
|
67
70
|
if (!raw || typeof raw !== 'object') {
|
|
@@ -531,6 +534,7 @@ function getStateVarsForUsage(usage) {
|
|
|
531
534
|
combinedStateVar: "ds_".concat(idx, "_state"),
|
|
532
535
|
setCombinedStateVar: "setDs_".concat(idx, "_state"),
|
|
533
536
|
skipDebounceRefVar: "ds_".concat(idx, "_skipDebounce"),
|
|
537
|
+
countSeqRefVar: "ds_".concat(idx, "_countSeq"),
|
|
534
538
|
propsPrefix: "".concat(usage.dataSourceIdentifier, "_ds_").concat(idx),
|
|
535
539
|
};
|
|
536
540
|
}
|
|
@@ -743,7 +747,7 @@ function pushFilterSortPageResetEffect(stateDeclarations, effectStatements, usag
|
|
|
743
747
|
// ==================== MAIN PLUGIN ====================
|
|
744
748
|
export var createNextArrayMapperPaginationPlugin = function () {
|
|
745
749
|
var paginationPlugin = function (structure) { return __awaiter(void 0, void 0, void 0, function () {
|
|
746
|
-
var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, stateDeclarations, effectStatements, needsUseRouter,
|
|
750
|
+
var uidl, chunks, dependencies, options, componentChunk, variableDeclaration, declarator, arrowFunction, blockStatement, registry, getStaticPropsChunk, isPage, localized, stateDeclarations, effectStatements, needsUseRouter, returnIndex, insertIndex, dataProviders, dataProvidersWithRepeaters, usageIndexByDataSourceId, loadingStateDeclarations, usagesWithLoadingState, usageByProviderNode, cacheDeclarations, sharedOptions, cachedScopes, dataProvidersWithoutRepeaters, searchInputs, searchEnabledUsages, usageBySearchInput;
|
|
747
751
|
var _a, _b;
|
|
748
752
|
return __generator(this, function (_c) {
|
|
749
753
|
uidl = structure.uidl, chunks = structure.chunks, dependencies = structure.dependencies, options = structure.options;
|
|
@@ -773,6 +777,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
773
777
|
}
|
|
774
778
|
getStaticPropsChunk = chunks.find(function (chunk) { return chunk.name === 'getStaticProps'; });
|
|
775
779
|
isPage = !!getStaticPropsChunk;
|
|
780
|
+
localized = isLocalizedProject(options);
|
|
776
781
|
// Add React dependencies
|
|
777
782
|
if (!dependencies.useState) {
|
|
778
783
|
dependencies.useState = {
|
|
@@ -934,12 +939,14 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
934
939
|
pushPropIdsAsDeps(countEffectDeps, countEffectSeen, usage.filterPropIds);
|
|
935
940
|
// Same goes for URL-driven filters (already documented above).
|
|
936
941
|
pushUrlSearchParamMemoDeps(countEffectDeps, usage);
|
|
942
|
+
stateDeclarations.push(buildCountSeqDeclaration(vars.countSeqRefVar));
|
|
937
943
|
effectStatements.push(buildCountFetchEffect({
|
|
938
944
|
fileName: fileName,
|
|
939
945
|
perPage: usage.perPage,
|
|
940
946
|
setMaxPagesVar: vars.setMaxPagesStateVar,
|
|
941
947
|
urlParams: urlParams,
|
|
942
948
|
deps: countEffectDeps,
|
|
949
|
+
countSeqRefVar: vars.countSeqRefVar,
|
|
943
950
|
}));
|
|
944
951
|
// Two-way URL sync for the search input when bound to a URL param.
|
|
945
952
|
pushSearchUrlSyncEffects(effectStatements, usage, vars);
|
|
@@ -999,12 +1006,14 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
999
1006
|
pushStateIdsAsDeps(countDeps, countDepsSeen, usage.filterStateIds);
|
|
1000
1007
|
pushPropIdsAsDeps(countDeps, countDepsSeen, usage.filterPropIds);
|
|
1001
1008
|
pushUrlSearchParamMemoDeps(countDeps, usage);
|
|
1009
|
+
stateDeclarations.push(buildCountSeqDeclaration(vars.countSeqRefVar));
|
|
1002
1010
|
effectStatements.push(buildCountFetchEffect({
|
|
1003
1011
|
fileName: fileName,
|
|
1004
1012
|
perPage: usage.perPage,
|
|
1005
1013
|
setMaxPagesVar: vars.setMaxPagesStateVar,
|
|
1006
1014
|
urlParams: countUrlParams,
|
|
1007
1015
|
deps: countDeps,
|
|
1016
|
+
countSeqRefVar: vars.countSeqRefVar,
|
|
1008
1017
|
}));
|
|
1009
1018
|
}
|
|
1010
1019
|
// Visible page numbers, when this mapper draws a numbered strip.
|
|
@@ -1061,35 +1070,10 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1061
1070
|
});
|
|
1062
1071
|
// Insert state declarations at the beginning
|
|
1063
1072
|
stateDeclarations.reverse().forEach(function (s) { return blockStatement.body.unshift(s); });
|
|
1064
|
-
needsUseRouter =
|
|
1073
|
+
needsUseRouter = localized ||
|
|
1074
|
+
registry.usages.some(function (u) { return hasUrlSearchParamFilters(u) || usageHasSearchUrlSync(u) || usageHasPageUrlSync(u); });
|
|
1065
1075
|
if (needsUseRouter) {
|
|
1066
|
-
|
|
1067
|
-
// Match the shape the sibling Next.js plugins use (i18n locale mapper,
|
|
1068
|
-
// search-params plugin) so the deduped import line is identical and
|
|
1069
|
-
// the dependency-resolver merges instead of emitting a second one.
|
|
1070
|
-
dependencies.useRouter = {
|
|
1071
|
-
type: 'library',
|
|
1072
|
-
path: 'next/router',
|
|
1073
|
-
version: '^12.1.10',
|
|
1074
|
-
meta: { namedImport: true },
|
|
1075
|
-
};
|
|
1076
|
-
}
|
|
1077
|
-
hasRouterDecl = blockStatement.body.some(function (statement) {
|
|
1078
|
-
return statement.type === 'VariableDeclaration' &&
|
|
1079
|
-
statement.declarations.some(function (decl) {
|
|
1080
|
-
var _a;
|
|
1081
|
-
return decl.id.type === 'Identifier' &&
|
|
1082
|
-
decl.id.name === 'router' &&
|
|
1083
|
-
((_a = decl.init) === null || _a === void 0 ? void 0 : _a.type) === 'CallExpression' &&
|
|
1084
|
-
decl.init.callee.type === 'Identifier' &&
|
|
1085
|
-
decl.init.callee.name === 'useRouter';
|
|
1086
|
-
});
|
|
1087
|
-
});
|
|
1088
|
-
if (!hasRouterDecl) {
|
|
1089
|
-
blockStatement.body.unshift(types.variableDeclaration('const', [
|
|
1090
|
-
types.variableDeclarator(types.identifier('router'), types.callExpression(types.identifier('useRouter'), [])),
|
|
1091
|
-
]));
|
|
1092
|
-
}
|
|
1076
|
+
ensureRouterDeclaration(blockStatement.body, dependencies);
|
|
1093
1077
|
}
|
|
1094
1078
|
// Both the search write-back and the page ⇄ URL effect write the URL through
|
|
1095
1079
|
// the shared `URLQueryWriter`, so the ref + helper they close over must be in
|
|
@@ -1131,16 +1115,16 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1131
1115
|
var fileName = generateSafeFileName(usage.resourceDefinition.dataSourceType, usage.resourceDefinition.tableName, usage.resourceDefinition.dataSourceId);
|
|
1132
1116
|
// Update DataProvider based on category
|
|
1133
1117
|
if (usage.category === 'paginated+search') {
|
|
1134
|
-
updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations);
|
|
1118
|
+
updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized);
|
|
1135
1119
|
}
|
|
1136
1120
|
else if (usage.category === 'paginated-only') {
|
|
1137
|
-
updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations);
|
|
1121
|
+
updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized);
|
|
1138
1122
|
}
|
|
1139
1123
|
else if (usage.category === 'search-only') {
|
|
1140
|
-
updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations);
|
|
1124
|
+
updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations, localized);
|
|
1141
1125
|
}
|
|
1142
1126
|
else if (usage.category === 'plain') {
|
|
1143
|
-
updateDataProviderForPlain(dp, fileName, usage);
|
|
1127
|
+
updateDataProviderForPlain(dp, fileName, usage, localized);
|
|
1144
1128
|
}
|
|
1145
1129
|
// Show the array mapper's loading state while a category/sort/search
|
|
1146
1130
|
// change refetches, instead of leaving the previous rows on screen with
|
|
@@ -1200,7 +1184,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1200
1184
|
});
|
|
1201
1185
|
searchInputs = findAllSearchInputsInJSX(blockStatement);
|
|
1202
1186
|
searchEnabledUsages = registry.usages.filter(function (u) { return u.searchEnabled; });
|
|
1203
|
-
|
|
1187
|
+
usageBySearchInput = new Map();
|
|
1204
1188
|
searchInputs.forEach(function (input, idx) {
|
|
1205
1189
|
if (idx >= searchEnabledUsages.length) {
|
|
1206
1190
|
return;
|
|
@@ -1208,6 +1192,15 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1208
1192
|
var usage = searchEnabledUsages[idx];
|
|
1209
1193
|
var vars = getStateVarsForUsage(usage);
|
|
1210
1194
|
wireSearchInput(input.node, vars);
|
|
1195
|
+
usageBySearchInput.set(input.node, usage);
|
|
1196
|
+
});
|
|
1197
|
+
// STEP 4.5: Wire the clear buttons, each to the input it shares a parent with.
|
|
1198
|
+
findAllSearchClearButtonsInJSX(blockStatement).forEach(function (button) {
|
|
1199
|
+
var input = findSiblingSearchInput(button, searchInputs.map(function (entry) { return entry.node; }));
|
|
1200
|
+
var usage = input ? usageBySearchInput.get(input) : undefined;
|
|
1201
|
+
if (usage) {
|
|
1202
|
+
wireSearchClearButton(button, getStateVarsForUsage(usage));
|
|
1203
|
+
}
|
|
1211
1204
|
});
|
|
1212
1205
|
// STEP 5: Wire pagination widgets
|
|
1213
1206
|
//
|
|
@@ -1229,7 +1222,7 @@ export var createNextArrayMapperPaginationPlugin = function () {
|
|
|
1229
1222
|
});
|
|
1230
1223
|
// STEP 6: Update getStaticProps if this is a page
|
|
1231
1224
|
if (isPage) {
|
|
1232
|
-
updateGetStaticProps(chunks, registry, dependencies, (_b = uidl.outputOptions) === null || _b === void 0 ? void 0 : _b.folderPath);
|
|
1225
|
+
updateGetStaticProps(chunks, registry, dependencies, (_b = uidl.outputOptions) === null || _b === void 0 ? void 0 : _b.folderPath, localized);
|
|
1233
1226
|
}
|
|
1234
1227
|
return [2 /*return*/, structure];
|
|
1235
1228
|
});
|
|
@@ -1278,6 +1271,20 @@ function insertSentinelAfterProvider(blockStatement, provider, sentinel) {
|
|
|
1278
1271
|
if (node.alternate) {
|
|
1279
1272
|
traverse(node.alternate);
|
|
1280
1273
|
}
|
|
1274
|
+
// `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
|
|
1275
|
+
// panel, a gated section: the provider sits on the RIGHT of a logical
|
|
1276
|
+
// expression (or in a ternary's `test`), which is not a child, a body or
|
|
1277
|
+
// an argument. Left unvisited, the products list under the first tab of
|
|
1278
|
+
// a shop was never paginated or seeded, and rendered nothing.
|
|
1279
|
+
if (node.left) {
|
|
1280
|
+
traverse(node.left);
|
|
1281
|
+
}
|
|
1282
|
+
if (node.right) {
|
|
1283
|
+
traverse(node.right);
|
|
1284
|
+
}
|
|
1285
|
+
if (node.test) {
|
|
1286
|
+
traverse(node.test);
|
|
1287
|
+
}
|
|
1281
1288
|
if (node.expression) {
|
|
1282
1289
|
traverse(node.expression);
|
|
1283
1290
|
}
|
|
@@ -1315,6 +1322,20 @@ function findAllDataProvidersInJSX(blockStatement) {
|
|
|
1315
1322
|
if (node.alternate) {
|
|
1316
1323
|
traverse(node.alternate);
|
|
1317
1324
|
}
|
|
1325
|
+
// `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
|
|
1326
|
+
// panel, a gated section: the provider sits on the RIGHT of a logical
|
|
1327
|
+
// expression (or in a ternary's `test`), which is not a child, a body or
|
|
1328
|
+
// an argument. Left unvisited, the products list under the first tab of
|
|
1329
|
+
// a shop was never paginated or seeded, and rendered nothing.
|
|
1330
|
+
if (node.left) {
|
|
1331
|
+
traverse(node.left);
|
|
1332
|
+
}
|
|
1333
|
+
if (node.right) {
|
|
1334
|
+
traverse(node.right);
|
|
1335
|
+
}
|
|
1336
|
+
if (node.test) {
|
|
1337
|
+
traverse(node.test);
|
|
1338
|
+
}
|
|
1318
1339
|
if (node.expression) {
|
|
1319
1340
|
traverse(node.expression);
|
|
1320
1341
|
}
|
|
@@ -1397,6 +1418,20 @@ function findAllSearchInputsInJSX(blockStatement) {
|
|
|
1397
1418
|
if (node.alternate) {
|
|
1398
1419
|
traverse(node.alternate);
|
|
1399
1420
|
}
|
|
1421
|
+
// `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
|
|
1422
|
+
// panel, a gated section: the provider sits on the RIGHT of a logical
|
|
1423
|
+
// expression (or in a ternary's `test`), which is not a child, a body or
|
|
1424
|
+
// an argument. Left unvisited, the products list under the first tab of
|
|
1425
|
+
// a shop was never paginated or seeded, and rendered nothing.
|
|
1426
|
+
if (node.left) {
|
|
1427
|
+
traverse(node.left);
|
|
1428
|
+
}
|
|
1429
|
+
if (node.right) {
|
|
1430
|
+
traverse(node.right);
|
|
1431
|
+
}
|
|
1432
|
+
if (node.test) {
|
|
1433
|
+
traverse(node.test);
|
|
1434
|
+
}
|
|
1400
1435
|
if (node.expression) {
|
|
1401
1436
|
traverse(node.expression);
|
|
1402
1437
|
}
|
|
@@ -1452,6 +1487,20 @@ function findPaginationNodesWithOwners(blockStatement, usageByProviderNode) {
|
|
|
1452
1487
|
if (node.alternate) {
|
|
1453
1488
|
traverse(node.alternate);
|
|
1454
1489
|
}
|
|
1490
|
+
// `{activeTabIndex === 0 && (<div>…<DataProvider/>…</div>)}` — a tab
|
|
1491
|
+
// panel, a gated section: the provider sits on the RIGHT of a logical
|
|
1492
|
+
// expression (or in a ternary's `test`), which is not a child, a body or
|
|
1493
|
+
// an argument. Left unvisited, the products list under the first tab of
|
|
1494
|
+
// a shop was never paginated or seeded, and rendered nothing.
|
|
1495
|
+
if (node.left) {
|
|
1496
|
+
traverse(node.left);
|
|
1497
|
+
}
|
|
1498
|
+
if (node.right) {
|
|
1499
|
+
traverse(node.right);
|
|
1500
|
+
}
|
|
1501
|
+
if (node.test) {
|
|
1502
|
+
traverse(node.test);
|
|
1503
|
+
}
|
|
1455
1504
|
if (node.expression) {
|
|
1456
1505
|
traverse(node.expression);
|
|
1457
1506
|
}
|
|
@@ -1494,7 +1543,7 @@ dp, usage, paramsProps, memoDeps, cacheDeclarations) {
|
|
|
1494
1543
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.identifier(hoisted.paramsIdentifier))));
|
|
1495
1544
|
return hoisted.cachedIdentifier;
|
|
1496
1545
|
}
|
|
1497
|
-
function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations) {
|
|
1546
|
+
function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDeclarations, localized) {
|
|
1498
1547
|
var attrs = dp.openingElement.attributes;
|
|
1499
1548
|
// Remove existing params, key, initialData, fetchData, persistDataDuringLoading
|
|
1500
1549
|
dp.openingElement.attributes = attrs.filter(function (attr) {
|
|
@@ -1523,6 +1572,9 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
|
|
|
1523
1572
|
pushStateIdsAsDeps(memoDeps, seenDeps, usage.dynamicSort.depStateIds);
|
|
1524
1573
|
}
|
|
1525
1574
|
pushUrlSearchParamMemoDeps(memoDeps, usage);
|
|
1575
|
+
if (localized) {
|
|
1576
|
+
appendClientLocaleParam(paramsProps, memoDeps);
|
|
1577
|
+
}
|
|
1526
1578
|
var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
|
|
1527
1579
|
// Add initialData. Skip the server-prefetched data entirely when a dynamic
|
|
1528
1580
|
// state-bound sort is active — the prefetch ran without sort parameters, so
|
|
@@ -1574,7 +1626,7 @@ function updateDataProviderForPaginatedSearch(dp, usage, vars, fileName, cacheDe
|
|
|
1574
1626
|
// Add persistDataDuringLoading
|
|
1575
1627
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1576
1628
|
}
|
|
1577
|
-
function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations) {
|
|
1629
|
+
function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDeclarations, localized) {
|
|
1578
1630
|
var attrs = dp.openingElement.attributes;
|
|
1579
1631
|
dp.openingElement.attributes = attrs.filter(function (attr) {
|
|
1580
1632
|
var _a;
|
|
@@ -1598,6 +1650,9 @@ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDec
|
|
|
1598
1650
|
pushStateIdsAsDeps(memoDeps, seenDeps, usage.dynamicSort.depStateIds);
|
|
1599
1651
|
}
|
|
1600
1652
|
pushUrlSearchParamMemoDeps(memoDeps, usage);
|
|
1653
|
+
if (localized) {
|
|
1654
|
+
appendClientLocaleParam(paramsProps, memoDeps);
|
|
1655
|
+
}
|
|
1601
1656
|
// Add params
|
|
1602
1657
|
var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
|
|
1603
1658
|
// Add initialData. See paginated+search updater for why we skip prefetch
|
|
@@ -1623,7 +1678,7 @@ function updateDataProviderForPaginationOnly(dp, usage, vars, fileName, cacheDec
|
|
|
1623
1678
|
dp.openingElement.attributes.push(buildFetchDataForUsage(fileName, usage));
|
|
1624
1679
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1625
1680
|
}
|
|
1626
|
-
function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations) {
|
|
1681
|
+
function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclarations, localized) {
|
|
1627
1682
|
var _a;
|
|
1628
1683
|
var attrs = dp.openingElement.attributes;
|
|
1629
1684
|
dp.openingElement.attributes = attrs.filter(function (attr) {
|
|
@@ -1650,6 +1705,9 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
|
|
|
1650
1705
|
pushStateIdsAsDeps(memoDeps, seenDeps, usage.dynamicSort.depStateIds);
|
|
1651
1706
|
}
|
|
1652
1707
|
pushUrlSearchParamMemoDeps(memoDeps, usage);
|
|
1708
|
+
if (localized) {
|
|
1709
|
+
appendClientLocaleParam(paramsProps, memoDeps);
|
|
1710
|
+
}
|
|
1653
1711
|
var cachedInitialData = pushParamsAttribute(dp, usage, paramsProps, memoDeps, cacheDeclarations);
|
|
1654
1712
|
// Add initialData. See paginated+search updater for why we skip prefetch
|
|
1655
1713
|
// reuse when a dynamic state-bound sort is active.
|
|
@@ -1665,7 +1723,7 @@ function updateDataProviderForSearchOnly(dp, usage, vars, fileName, cacheDeclara
|
|
|
1665
1723
|
dp.openingElement.attributes.push(createFetchDataAttribute(fileName, ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined));
|
|
1666
1724
|
dp.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1667
1725
|
}
|
|
1668
|
-
function updateDataProviderForPlain(dp, fileName, usage) {
|
|
1726
|
+
function updateDataProviderForPlain(dp, fileName, usage, localized) {
|
|
1669
1727
|
var _a, _b, _c, _d;
|
|
1670
1728
|
var attrs = dp.openingElement.attributes;
|
|
1671
1729
|
var clientCache = ((_a = usage.cache) === null || _a === void 0 ? void 0 : _a.client) ? usage.cache : undefined;
|
|
@@ -1687,10 +1745,16 @@ function updateDataProviderForPlain(dp, fileName, usage) {
|
|
|
1687
1745
|
if (!hasPersistData) {
|
|
1688
1746
|
attrs.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
1689
1747
|
}
|
|
1690
|
-
// Find the params attribute
|
|
1748
|
+
// Find the params attribute. A plain list may have none at all — but the
|
|
1749
|
+
// fetch it was just given sends `params` regardless, and in a localized
|
|
1750
|
+
// project those have to carry the locale, so the attribute is created.
|
|
1691
1751
|
var paramsAttrIndex = attrs.findIndex(function (attr) { return attr.type === 'JSXAttribute' && attr.name.name === 'params'; });
|
|
1692
1752
|
if (paramsAttrIndex === -1) {
|
|
1693
|
-
|
|
1753
|
+
if (!localized) {
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
attrs.push(types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(types.objectExpression([]))));
|
|
1757
|
+
paramsAttrIndex = attrs.length - 1;
|
|
1694
1758
|
}
|
|
1695
1759
|
var paramsAttr = attrs[paramsAttrIndex];
|
|
1696
1760
|
// Check if params is already wrapped in useMemo
|
|
@@ -1713,6 +1777,9 @@ function updateDataProviderForPlain(dp, fileName, usage) {
|
|
|
1713
1777
|
pushStateIdsAsDeps(memoDeps, memoSeen, usage.filterStateIds);
|
|
1714
1778
|
pushPropIdsAsDeps(memoDeps, memoSeen, usage.filterPropIds);
|
|
1715
1779
|
pushUrlSearchParamMemoDeps(memoDeps, usage);
|
|
1780
|
+
if (localized && paramsExpression.type === 'ObjectExpression') {
|
|
1781
|
+
appendClientLocaleParam(paramsExpression.properties, memoDeps);
|
|
1782
|
+
}
|
|
1716
1783
|
// Wrap params in useMemo with filter state dependencies
|
|
1717
1784
|
var memoizedParams = types.callExpression(types.identifier('useMemo'), [
|
|
1718
1785
|
types.arrowFunctionExpression([], paramsExpression),
|
|
@@ -1744,11 +1811,18 @@ function stabilizeDataProviderWithoutRepeater(dp) {
|
|
|
1744
1811
|
if (!paramsExpression) {
|
|
1745
1812
|
return;
|
|
1746
1813
|
}
|
|
1747
|
-
// Wrap params in useMemo with empty dependencies array
|
|
1748
|
-
//
|
|
1814
|
+
// Wrap params in useMemo with an empty dependencies array so the object
|
|
1815
|
+
// reference stays stable across re-renders. The one thing that may vary is
|
|
1816
|
+
// the locale a client-fetched item carries (put there by the data-source
|
|
1817
|
+
// plugin): a locale switch must rebuild the params, or the item would keep
|
|
1818
|
+
// its previous language.
|
|
1819
|
+
var memoDeps = [];
|
|
1820
|
+
if (paramsExpression.type === 'ObjectExpression' && hasLocaleParam(paramsExpression.properties)) {
|
|
1821
|
+
memoDeps.push(buildClientLocaleExpression());
|
|
1822
|
+
}
|
|
1749
1823
|
var memoizedParams = types.callExpression(types.identifier('useMemo'), [
|
|
1750
1824
|
types.arrowFunctionExpression([], paramsExpression),
|
|
1751
|
-
types.arrayExpression(
|
|
1825
|
+
types.arrayExpression(memoDeps),
|
|
1752
1826
|
]);
|
|
1753
1827
|
// Replace the params attribute
|
|
1754
1828
|
attrs[paramsAttrIndex] = types.jsxAttribute(types.jsxIdentifier('params'), types.jsxExpressionContainer(memoizedParams));
|
|
@@ -2060,7 +2134,7 @@ function ensureAPIRouteExists(extractedResources, usage, dataSources, transformO
|
|
|
2060
2134
|
};
|
|
2061
2135
|
}
|
|
2062
2136
|
}
|
|
2063
|
-
function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
|
|
2137
|
+
function updateGetStaticProps(chunks, registry, dependencies, folderPath, localized) {
|
|
2064
2138
|
var _a;
|
|
2065
2139
|
var getStaticPropsChunk = chunks.find(function (c) { return c.name === 'getStaticProps'; });
|
|
2066
2140
|
if (!getStaticPropsChunk || getStaticPropsChunk.type !== ChunkType.AST) {
|
|
@@ -2155,6 +2229,10 @@ function updateGetStaticProps(chunks, registry, dependencies, folderPath) {
|
|
|
2155
2229
|
})),
|
|
2156
2230
|
])));
|
|
2157
2231
|
}
|
|
2232
|
+
// The prefetch is per locale — getStaticProps runs once per language.
|
|
2233
|
+
if (localized) {
|
|
2234
|
+
fetchParams.push(buildServerLocaleParam());
|
|
2235
|
+
}
|
|
2158
2236
|
// Check if this fetch already exists
|
|
2159
2237
|
var existingFetchIndex = arrayPattern.elements.findIndex(function (el) { return (el === null || el === void 0 ? void 0 : el.type) === 'Identifier' && el.name === vars.propsPrefix; });
|
|
2160
2238
|
if (existingFetchIndex === -1) {
|