@teleporthq/teleport-plugin-next-data-source 0.40.15
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/ARRAY_MAPPER_PAGINATION.md +1128 -0
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/SEARCH_IMPLEMENTATION_SUMMARY.md +983 -0
- package/__tests__/fetchers.test.ts +545 -0
- package/__tests__/integration.test.ts +561 -0
- package/__tests__/mocks.ts +241 -0
- package/__tests__/pagination.test.ts +31 -0
- package/__tests__/plugin.test.ts +577 -0
- package/__tests__/utils.test.ts +430 -0
- package/__tests__/validation.test.ts +348 -0
- package/dist/cjs/array-mapper-pagination.d.ts +32 -0
- package/dist/cjs/array-mapper-pagination.d.ts.map +1 -0
- package/dist/cjs/array-mapper-pagination.js +77 -0
- package/dist/cjs/array-mapper-pagination.js.map +1 -0
- package/dist/cjs/count-fetchers.d.ts +12 -0
- package/dist/cjs/count-fetchers.d.ts.map +1 -0
- package/dist/cjs/count-fetchers.js +46 -0
- package/dist/cjs/count-fetchers.js.map +1 -0
- package/dist/cjs/data-source-fetchers.d.ts +14 -0
- package/dist/cjs/data-source-fetchers.d.ts.map +1 -0
- package/dist/cjs/data-source-fetchers.js +185 -0
- package/dist/cjs/data-source-fetchers.js.map +1 -0
- package/dist/cjs/fetchers/airtable.d.ts +6 -0
- package/dist/cjs/fetchers/airtable.d.ts.map +1 -0
- package/dist/cjs/fetchers/airtable.js +27 -0
- package/dist/cjs/fetchers/airtable.js.map +1 -0
- package/dist/cjs/fetchers/clickhouse.d.ts +6 -0
- package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -0
- package/dist/cjs/fetchers/clickhouse.js +29 -0
- package/dist/cjs/fetchers/clickhouse.js.map +1 -0
- package/dist/cjs/fetchers/csv-file.d.ts +7 -0
- package/dist/cjs/fetchers/csv-file.d.ts.map +1 -0
- package/dist/cjs/fetchers/csv-file.js +36 -0
- package/dist/cjs/fetchers/csv-file.js.map +1 -0
- package/dist/cjs/fetchers/firestore.d.ts +6 -0
- package/dist/cjs/fetchers/firestore.d.ts.map +1 -0
- package/dist/cjs/fetchers/firestore.js +35 -0
- package/dist/cjs/fetchers/firestore.js.map +1 -0
- package/dist/cjs/fetchers/google-sheets.d.ts +6 -0
- package/dist/cjs/fetchers/google-sheets.d.ts.map +1 -0
- package/dist/cjs/fetchers/google-sheets.js +30 -0
- package/dist/cjs/fetchers/google-sheets.js.map +1 -0
- package/dist/cjs/fetchers/index.d.ts +17 -0
- package/dist/cjs/fetchers/index.d.ts.map +1 -0
- package/dist/cjs/fetchers/index.js +56 -0
- package/dist/cjs/fetchers/index.js.map +1 -0
- package/dist/cjs/fetchers/javascript.d.ts +7 -0
- package/dist/cjs/fetchers/javascript.d.ts.map +1 -0
- package/dist/cjs/fetchers/javascript.js +40 -0
- package/dist/cjs/fetchers/javascript.js.map +1 -0
- package/dist/cjs/fetchers/mariadb.d.ts +3 -0
- package/dist/cjs/fetchers/mariadb.d.ts.map +1 -0
- package/dist/cjs/fetchers/mariadb.js +23 -0
- package/dist/cjs/fetchers/mariadb.js.map +1 -0
- package/dist/cjs/fetchers/mongodb.d.ts +7 -0
- package/dist/cjs/fetchers/mongodb.d.ts.map +1 -0
- package/dist/cjs/fetchers/mongodb.js +52 -0
- package/dist/cjs/fetchers/mongodb.js.map +1 -0
- package/dist/cjs/fetchers/mysql.d.ts +3 -0
- package/dist/cjs/fetchers/mysql.d.ts.map +1 -0
- package/dist/cjs/fetchers/mysql.js +30 -0
- package/dist/cjs/fetchers/mysql.js.map +1 -0
- package/dist/cjs/fetchers/postgresql.d.ts +3 -0
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -0
- package/dist/cjs/fetchers/postgresql.js +25 -0
- package/dist/cjs/fetchers/postgresql.js.map +1 -0
- package/dist/cjs/fetchers/redis.d.ts +6 -0
- package/dist/cjs/fetchers/redis.d.ts.map +1 -0
- package/dist/cjs/fetchers/redis.js +46 -0
- package/dist/cjs/fetchers/redis.js.map +1 -0
- package/dist/cjs/fetchers/redshift.d.ts +2 -0
- package/dist/cjs/fetchers/redshift.d.ts.map +1 -0
- package/dist/cjs/fetchers/redshift.js +24 -0
- package/dist/cjs/fetchers/redshift.js.map +1 -0
- package/dist/cjs/fetchers/rest-api.d.ts +6 -0
- package/dist/cjs/fetchers/rest-api.d.ts.map +1 -0
- package/dist/cjs/fetchers/rest-api.js +58 -0
- package/dist/cjs/fetchers/rest-api.js.map +1 -0
- package/dist/cjs/fetchers/static-collection.d.ts +7 -0
- package/dist/cjs/fetchers/static-collection.d.ts.map +1 -0
- package/dist/cjs/fetchers/static-collection.js +24 -0
- package/dist/cjs/fetchers/static-collection.js.map +1 -0
- package/dist/cjs/fetchers/supabase.d.ts +7 -0
- package/dist/cjs/fetchers/supabase.d.ts.map +1 -0
- package/dist/cjs/fetchers/supabase.js +42 -0
- package/dist/cjs/fetchers/supabase.js.map +1 -0
- package/dist/cjs/fetchers/turso.d.ts +6 -0
- package/dist/cjs/fetchers/turso.d.ts.map +1 -0
- package/dist/cjs/fetchers/turso.js +25 -0
- package/dist/cjs/fetchers/turso.js.map +1 -0
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +325 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/pagination-plugin.d.ts +5 -0
- package/dist/cjs/pagination-plugin.d.ts.map +1 -0
- package/dist/cjs/pagination-plugin.js +1484 -0
- package/dist/cjs/pagination-plugin.js.map +1 -0
- package/dist/cjs/pagination-with-count.d.ts +6 -0
- package/dist/cjs/pagination-with-count.d.ts.map +1 -0
- package/dist/cjs/pagination-with-count.js +63 -0
- package/dist/cjs/pagination-with-count.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/cjs/utils.d.ts +31 -0
- package/dist/cjs/utils.d.ts.map +1 -0
- package/dist/cjs/utils.js +763 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/cjs/validation.d.ts +5 -0
- package/dist/cjs/validation.d.ts.map +1 -0
- package/dist/cjs/validation.js +29 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/array-mapper-pagination.d.ts +32 -0
- package/dist/esm/array-mapper-pagination.d.ts.map +1 -0
- package/dist/esm/array-mapper-pagination.js +72 -0
- package/dist/esm/array-mapper-pagination.js.map +1 -0
- package/dist/esm/count-fetchers.d.ts +12 -0
- package/dist/esm/count-fetchers.d.ts.map +1 -0
- package/dist/esm/count-fetchers.js +35 -0
- package/dist/esm/count-fetchers.js.map +1 -0
- package/dist/esm/data-source-fetchers.d.ts +14 -0
- package/dist/esm/data-source-fetchers.d.ts.map +1 -0
- package/dist/esm/data-source-fetchers.js +179 -0
- package/dist/esm/data-source-fetchers.js.map +1 -0
- package/dist/esm/fetchers/airtable.d.ts +6 -0
- package/dist/esm/fetchers/airtable.d.ts.map +1 -0
- package/dist/esm/fetchers/airtable.js +22 -0
- package/dist/esm/fetchers/airtable.js.map +1 -0
- package/dist/esm/fetchers/clickhouse.d.ts +6 -0
- package/dist/esm/fetchers/clickhouse.d.ts.map +1 -0
- package/dist/esm/fetchers/clickhouse.js +24 -0
- package/dist/esm/fetchers/clickhouse.js.map +1 -0
- package/dist/esm/fetchers/csv-file.d.ts +7 -0
- package/dist/esm/fetchers/csv-file.d.ts.map +1 -0
- package/dist/esm/fetchers/csv-file.js +30 -0
- package/dist/esm/fetchers/csv-file.js.map +1 -0
- package/dist/esm/fetchers/firestore.d.ts +6 -0
- package/dist/esm/fetchers/firestore.d.ts.map +1 -0
- package/dist/esm/fetchers/firestore.js +30 -0
- package/dist/esm/fetchers/firestore.js.map +1 -0
- package/dist/esm/fetchers/google-sheets.d.ts +6 -0
- package/dist/esm/fetchers/google-sheets.d.ts.map +1 -0
- package/dist/esm/fetchers/google-sheets.js +25 -0
- package/dist/esm/fetchers/google-sheets.js.map +1 -0
- package/dist/esm/fetchers/index.d.ts +17 -0
- package/dist/esm/fetchers/index.d.ts.map +1 -0
- package/dist/esm/fetchers/index.js +17 -0
- package/dist/esm/fetchers/index.js.map +1 -0
- package/dist/esm/fetchers/javascript.d.ts +7 -0
- package/dist/esm/fetchers/javascript.d.ts.map +1 -0
- package/dist/esm/fetchers/javascript.js +34 -0
- package/dist/esm/fetchers/javascript.js.map +1 -0
- package/dist/esm/fetchers/mariadb.d.ts +3 -0
- package/dist/esm/fetchers/mariadb.d.ts.map +1 -0
- package/dist/esm/fetchers/mariadb.js +18 -0
- package/dist/esm/fetchers/mariadb.js.map +1 -0
- package/dist/esm/fetchers/mongodb.d.ts +7 -0
- package/dist/esm/fetchers/mongodb.d.ts.map +1 -0
- package/dist/esm/fetchers/mongodb.js +46 -0
- package/dist/esm/fetchers/mongodb.js.map +1 -0
- package/dist/esm/fetchers/mysql.d.ts +3 -0
- package/dist/esm/fetchers/mysql.d.ts.map +1 -0
- package/dist/esm/fetchers/mysql.js +25 -0
- package/dist/esm/fetchers/mysql.js.map +1 -0
- package/dist/esm/fetchers/postgresql.d.ts +3 -0
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -0
- package/dist/esm/fetchers/postgresql.js +20 -0
- package/dist/esm/fetchers/postgresql.js.map +1 -0
- package/dist/esm/fetchers/redis.d.ts +6 -0
- package/dist/esm/fetchers/redis.d.ts.map +1 -0
- package/dist/esm/fetchers/redis.js +41 -0
- package/dist/esm/fetchers/redis.js.map +1 -0
- package/dist/esm/fetchers/redshift.d.ts +2 -0
- package/dist/esm/fetchers/redshift.d.ts.map +1 -0
- package/dist/esm/fetchers/redshift.js +20 -0
- package/dist/esm/fetchers/redshift.js.map +1 -0
- package/dist/esm/fetchers/rest-api.d.ts +6 -0
- package/dist/esm/fetchers/rest-api.d.ts.map +1 -0
- package/dist/esm/fetchers/rest-api.js +53 -0
- package/dist/esm/fetchers/rest-api.js.map +1 -0
- package/dist/esm/fetchers/static-collection.d.ts +7 -0
- package/dist/esm/fetchers/static-collection.d.ts.map +1 -0
- package/dist/esm/fetchers/static-collection.js +18 -0
- package/dist/esm/fetchers/static-collection.js.map +1 -0
- package/dist/esm/fetchers/supabase.d.ts +7 -0
- package/dist/esm/fetchers/supabase.d.ts.map +1 -0
- package/dist/esm/fetchers/supabase.js +36 -0
- package/dist/esm/fetchers/supabase.js.map +1 -0
- package/dist/esm/fetchers/turso.d.ts +6 -0
- package/dist/esm/fetchers/turso.d.ts.map +1 -0
- package/dist/esm/fetchers/turso.js +20 -0
- package/dist/esm/fetchers/turso.js.map +1 -0
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +306 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/pagination-plugin.d.ts +5 -0
- package/dist/esm/pagination-plugin.d.ts.map +1 -0
- package/dist/esm/pagination-plugin.js +1457 -0
- package/dist/esm/pagination-plugin.js.map +1 -0
- package/dist/esm/pagination-with-count.d.ts +6 -0
- package/dist/esm/pagination-with-count.d.ts.map +1 -0
- package/dist/esm/pagination-with-count.js +34 -0
- package/dist/esm/pagination-with-count.js.map +1 -0
- package/dist/esm/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/utils.d.ts +31 -0
- package/dist/esm/utils.d.ts.map +1 -0
- package/dist/esm/utils.js +722 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/esm/validation.d.ts +5 -0
- package/dist/esm/validation.d.ts.map +1 -0
- package/dist/esm/validation.js +25 -0
- package/dist/esm/validation.js.map +1 -0
- package/package.json +33 -0
- package/src/array-mapper-pagination.ts +113 -0
- package/src/count-fetchers.ts +99 -0
- package/src/data-source-fetchers.ts +313 -0
- package/src/fetchers/airtable.ts +153 -0
- package/src/fetchers/clickhouse.ts +127 -0
- package/src/fetchers/csv-file.ts +163 -0
- package/src/fetchers/firestore.ts +138 -0
- package/src/fetchers/google-sheets.ts +189 -0
- package/src/fetchers/index.ts +32 -0
- package/src/fetchers/javascript.ts +150 -0
- package/src/fetchers/mariadb.ts +230 -0
- package/src/fetchers/mongodb.ts +239 -0
- package/src/fetchers/mysql.ts +237 -0
- package/src/fetchers/postgresql.ts +247 -0
- package/src/fetchers/redis.ts +152 -0
- package/src/fetchers/redshift.ts +138 -0
- package/src/fetchers/rest-api.ts +148 -0
- package/src/fetchers/static-collection.ts +149 -0
- package/src/fetchers/supabase.ts +246 -0
- package/src/fetchers/turso.ts +131 -0
- package/src/index.ts +352 -0
- package/src/pagination-plugin.ts +2335 -0
- package/src/pagination-with-count.ts +89 -0
- package/src/utils.ts +1013 -0
- package/src/validation.ts +32 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
2
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
3
|
+
if (ar || !(i in from)) {
|
|
4
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
5
|
+
ar[i] = from[i];
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
9
|
+
};
|
|
10
|
+
import { FileType, ChunkType, } from '@teleporthq/teleport-types';
|
|
11
|
+
import * as types from '@babel/types';
|
|
12
|
+
import { ASTUtils } from '@teleporthq/teleport-plugin-common';
|
|
13
|
+
import { StringUtils } from '@teleporthq/teleport-shared';
|
|
14
|
+
import { generateDataSourceFetcherWithCore } from './data-source-fetchers';
|
|
15
|
+
var VALID_DATA_SOURCE_TYPES = [
|
|
16
|
+
'rest-api',
|
|
17
|
+
'postgresql',
|
|
18
|
+
'mysql',
|
|
19
|
+
'mariadb',
|
|
20
|
+
'amazon-redshift',
|
|
21
|
+
'mongodb',
|
|
22
|
+
'cockroachdb',
|
|
23
|
+
'tidb',
|
|
24
|
+
'redis',
|
|
25
|
+
'firestore',
|
|
26
|
+
'clickhouse',
|
|
27
|
+
'airtable',
|
|
28
|
+
'supabase',
|
|
29
|
+
'turso',
|
|
30
|
+
'javascript',
|
|
31
|
+
'google-sheets',
|
|
32
|
+
'csv-file',
|
|
33
|
+
'static-collection',
|
|
34
|
+
];
|
|
35
|
+
export var sanitizeFileName = function (input) {
|
|
36
|
+
if (!input || typeof input !== 'string') {
|
|
37
|
+
return 'unknown';
|
|
38
|
+
}
|
|
39
|
+
return (input
|
|
40
|
+
// Remove path traversal attempts
|
|
41
|
+
.replace(/\.\./g, '')
|
|
42
|
+
.replace(/[\/\\]/g, '-')
|
|
43
|
+
// Remove invalid filename characters
|
|
44
|
+
.replace(/[<>:"|?*\x00-\x1F]/g, '')
|
|
45
|
+
// Replace spaces with dashes
|
|
46
|
+
.replace(/\s+/g, '-')
|
|
47
|
+
// Remove leading/trailing dashes and dots
|
|
48
|
+
.replace(/^[-_.]+|[-_.]+$/g, '')
|
|
49
|
+
// Limit length to prevent filesystem issues
|
|
50
|
+
.substring(0, 200) || 'unknown');
|
|
51
|
+
};
|
|
52
|
+
export var isNonEmptyString = function (value) {
|
|
53
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
54
|
+
};
|
|
55
|
+
export var hoistLoadingFromRepeater = function (dataSourceNode) {
|
|
56
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
57
|
+
if (!dataSourceNode || !dataSourceNode.content) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
var children = dataSourceNode.children || [];
|
|
61
|
+
for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
|
|
62
|
+
var child = children_1[_i];
|
|
63
|
+
if (child.type === 'cms-list-repeater' && ((_b = (_a = child.content) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b.loading)) {
|
|
64
|
+
if (!dataSourceNode.content.nodes) {
|
|
65
|
+
dataSourceNode.content.nodes = {};
|
|
66
|
+
}
|
|
67
|
+
if (!dataSourceNode.content.nodes.loading &&
|
|
68
|
+
((_d = (_c = child.content.nodes.loading.content) === null || _c === void 0 ? void 0 : _c.children) === null || _d === void 0 ? void 0 : _d.length) > 0) {
|
|
69
|
+
dataSourceNode.content.nodes.loading = child.content.nodes.loading;
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if ((_g = (_f = (_e = dataSourceNode.content.nodes) === null || _e === void 0 ? void 0 : _e.success) === null || _f === void 0 ? void 0 : _f.content) === null || _g === void 0 ? void 0 : _g.children) {
|
|
75
|
+
for (var _m = 0, _o = dataSourceNode.content.nodes.success.content.children; _m < _o.length; _m++) {
|
|
76
|
+
var child = _o[_m];
|
|
77
|
+
if (child.type === 'cms-list-repeater' && ((_j = (_h = child.content) === null || _h === void 0 ? void 0 : _h.nodes) === null || _j === void 0 ? void 0 : _j.loading)) {
|
|
78
|
+
if (!dataSourceNode.content.nodes.loading &&
|
|
79
|
+
((_l = (_k = child.content.nodes.loading.content) === null || _k === void 0 ? void 0 : _k.children) === null || _l === void 0 ? void 0 : _l.length) > 0) {
|
|
80
|
+
dataSourceNode.content.nodes.loading = child.content.nodes.loading;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
// tslint:disable-next-line:no-any
|
|
88
|
+
export var validateResourceDefinition = function (resourceDefinition) {
|
|
89
|
+
if (!resourceDefinition || typeof resourceDefinition !== 'object') {
|
|
90
|
+
return { isValid: false, error: 'Resource definition is missing or invalid' };
|
|
91
|
+
}
|
|
92
|
+
var dataSourceId = resourceDefinition.dataSourceId, tableName = resourceDefinition.tableName, dataSourceType = resourceDefinition.dataSourceType;
|
|
93
|
+
if (!isNonEmptyString(dataSourceId)) {
|
|
94
|
+
return { isValid: false, error: 'Data source ID is missing or invalid' };
|
|
95
|
+
}
|
|
96
|
+
if (!isNonEmptyString(dataSourceType)) {
|
|
97
|
+
return { isValid: false, error: 'Data source type is missing or invalid' };
|
|
98
|
+
}
|
|
99
|
+
if (!VALID_DATA_SOURCE_TYPES.includes(dataSourceType)) {
|
|
100
|
+
return { isValid: false, error: "Invalid data source type: ".concat(dataSourceType) };
|
|
101
|
+
}
|
|
102
|
+
// tableName is optional for some data sources (like REST API, JavaScript, etc.)
|
|
103
|
+
if (tableName !== undefined && !isNonEmptyString(tableName)) {
|
|
104
|
+
return { isValid: false, error: 'Table name must be a non-empty string when provided' };
|
|
105
|
+
}
|
|
106
|
+
return { isValid: true };
|
|
107
|
+
};
|
|
108
|
+
// tslint:disable-next-line:no-any
|
|
109
|
+
export var validateNodeContent = function (content) {
|
|
110
|
+
if (!content || typeof content !== 'object') {
|
|
111
|
+
return { isValid: false, error: 'Node content is missing or invalid' };
|
|
112
|
+
}
|
|
113
|
+
if (!content.resourceDefinition) {
|
|
114
|
+
return { isValid: false, error: 'Resource definition is missing from node content' };
|
|
115
|
+
}
|
|
116
|
+
// key is optional - we can generate one from the resource definition if missing
|
|
117
|
+
return { isValid: true };
|
|
118
|
+
};
|
|
119
|
+
export var validateDataSourceConfig = function (dataSource) {
|
|
120
|
+
if (!dataSource || typeof dataSource !== 'object') {
|
|
121
|
+
return { isValid: false, error: 'Data source is missing or invalid' };
|
|
122
|
+
}
|
|
123
|
+
if (!isNonEmptyString(dataSource.id)) {
|
|
124
|
+
return { isValid: false, error: 'Data source ID is missing' };
|
|
125
|
+
}
|
|
126
|
+
if (!isNonEmptyString(dataSource.type)) {
|
|
127
|
+
return { isValid: false, error: 'Data source type is missing' };
|
|
128
|
+
}
|
|
129
|
+
if (!dataSource.config || typeof dataSource.config !== 'object') {
|
|
130
|
+
return { isValid: false, error: 'Data source config is missing or invalid' };
|
|
131
|
+
}
|
|
132
|
+
return { isValid: true };
|
|
133
|
+
};
|
|
134
|
+
export var generateSafeFileName = function (dataSourceType, tableName, dataSourceId) {
|
|
135
|
+
var sanitizedType = sanitizeFileName(dataSourceType);
|
|
136
|
+
var sanitizedTable = sanitizeFileName(tableName || 'data');
|
|
137
|
+
var sanitizedId = sanitizeFileName(dataSourceId);
|
|
138
|
+
// Create a unique identifier using parts of the dataSourceId
|
|
139
|
+
var shortId = sanitizedId.substring(0, 8);
|
|
140
|
+
var baseName = "".concat(sanitizedType, "-").concat(sanitizedTable, "-").concat(shortId);
|
|
141
|
+
return StringUtils.camelCaseToDashCase(baseName);
|
|
142
|
+
};
|
|
143
|
+
export var extractDataSourceIntoNextAPIFolder = function (node, dataSources, componentChunk, extractedResources) {
|
|
144
|
+
var _a, _b, _c;
|
|
145
|
+
try {
|
|
146
|
+
// Validate node content structure
|
|
147
|
+
var contentValidation = validateNodeContent(node.content);
|
|
148
|
+
if (!contentValidation.isValid) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
var resourceDefinition = node.content.resourceDefinition;
|
|
152
|
+
// Validate resource definition
|
|
153
|
+
var resourceValidation = validateResourceDefinition(resourceDefinition);
|
|
154
|
+
if (!resourceValidation.isValid) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
var dataSourceId = resourceDefinition.dataSourceId, tableName = resourceDefinition.tableName, dataSourceType = resourceDefinition.dataSourceType;
|
|
158
|
+
// Check if dataSources object exists
|
|
159
|
+
if (!dataSources || typeof dataSources !== 'object') {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Check if data source exists
|
|
163
|
+
var dataSource = dataSources[dataSourceId];
|
|
164
|
+
if (!dataSource) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
// Validate data source configuration
|
|
168
|
+
var configValidation = validateDataSourceConfig(dataSource);
|
|
169
|
+
if (!configValidation.isValid) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
// Check if component chunk has meta and nodesLookup
|
|
173
|
+
if (!componentChunk.meta || !componentChunk.meta.nodesLookup) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// Generate safe file name
|
|
177
|
+
var fileName = generateSafeFileName(dataSourceType, tableName || 'data', dataSourceId);
|
|
178
|
+
// Check if file name is valid
|
|
179
|
+
if (!fileName || fileName === 'unknown') {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Find JSX node by searching through nodesLookup
|
|
183
|
+
// The JSX generator creates keys like: ds-{dataSourceId}-{timestamp}
|
|
184
|
+
// We need to find the node that matches our resourceDefinition
|
|
185
|
+
// IMPORTANT: Match by both dataSourceId AND renderPropIdentifier to handle multiple DataProviders with same data source
|
|
186
|
+
var jsxNode = null;
|
|
187
|
+
var targetRenderProp = (_a = node.content) === null || _a === void 0 ? void 0 : _a.renderPropIdentifier;
|
|
188
|
+
// tslint:disable-next-line:no-any
|
|
189
|
+
for (var _i = 0, _d = Object.values(componentChunk.meta.nodesLookup); _i < _d.length; _i++) {
|
|
190
|
+
var jsxElement = _d[_i];
|
|
191
|
+
// tslint:disable-next-line:no-any
|
|
192
|
+
if (jsxElement.type === 'JSXElement') {
|
|
193
|
+
var attrs = jsxElement.openingElement.attributes;
|
|
194
|
+
// Look for resourceDefinition attribute
|
|
195
|
+
// tslint:disable-next-line:no-any
|
|
196
|
+
var resourceDefAttr = attrs.find(function (attr) {
|
|
197
|
+
return attr.type === 'JSXAttribute' &&
|
|
198
|
+
attr.name.name === 'resourceDefinition';
|
|
199
|
+
});
|
|
200
|
+
// Look for name attribute to match with renderPropIdentifier
|
|
201
|
+
// tslint:disable-next-line:no-any
|
|
202
|
+
var nameAttr = attrs.find(function (attr) {
|
|
203
|
+
return attr.type === 'JSXAttribute' &&
|
|
204
|
+
attr.name.name === 'name';
|
|
205
|
+
});
|
|
206
|
+
if (resourceDefAttr &&
|
|
207
|
+
resourceDefAttr.value &&
|
|
208
|
+
resourceDefAttr.value.type === 'JSXExpressionContainer') {
|
|
209
|
+
var expr = resourceDefAttr.value.expression;
|
|
210
|
+
if (expr.type === 'ObjectExpression') {
|
|
211
|
+
// Check if this matches our resourceDefinition
|
|
212
|
+
var props = expr.properties;
|
|
213
|
+
// tslint:disable-next-line:no-any
|
|
214
|
+
var idProp = props.find(function (p) { var _a; return ((_a = p.key) === null || _a === void 0 ? void 0 : _a.value) === 'dataSourceId'; });
|
|
215
|
+
// tslint:disable-next-line:no-any
|
|
216
|
+
var idValue = (_b = idProp === null || idProp === void 0 ? void 0 : idProp.value) === null || _b === void 0 ? void 0 : _b.value;
|
|
217
|
+
// Match by dataSourceId
|
|
218
|
+
var dataSourceMatches = idValue === dataSourceId;
|
|
219
|
+
// Also check name prop matches renderPropIdentifier
|
|
220
|
+
var renderPropMatches = !targetRenderProp; // If no targetRenderProp, don't check it
|
|
221
|
+
if (targetRenderProp && nameAttr && nameAttr.value) {
|
|
222
|
+
// The name attribute value is usually a StringLiteral or JSXExpressionContainer
|
|
223
|
+
if (nameAttr.value.type === 'StringLiteral') {
|
|
224
|
+
if (nameAttr.value.value === targetRenderProp) {
|
|
225
|
+
renderPropMatches = true;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else if (nameAttr.value.type === 'JSXExpressionContainer') {
|
|
229
|
+
var nameExpr = nameAttr.value.expression;
|
|
230
|
+
if (nameExpr.type === 'StringLiteral' && nameExpr.value === targetRenderProp) {
|
|
231
|
+
renderPropMatches = true;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Before matching, check if this node already has fetchData - if so, skip it
|
|
236
|
+
// This is crucial for handling multiple DataProviders with same dataSourceId and name
|
|
237
|
+
var alreadyHasFetchData = attrs.some(function (attr) { var _a; return ((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) === 'fetchData'; });
|
|
238
|
+
if (dataSourceMatches && renderPropMatches && !alreadyHasFetchData) {
|
|
239
|
+
jsxNode = jsxElement;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
else if (dataSourceMatches && renderPropMatches && alreadyHasFetchData) {
|
|
243
|
+
// Continue searching for the next matching node without fetchData
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (!jsxNode || jsxNode.type !== 'JSXElement') {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
// Ensure opening element and attributes exist
|
|
253
|
+
if (!jsxNode.openingElement || !Array.isArray(jsxNode.openingElement.attributes)) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
// Check if this node has already been processed (has fetchData attribute)
|
|
257
|
+
var existingFetchData = jsxNode.openingElement.attributes.find(function (attr) { var _a; return ((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) === 'fetchData'; });
|
|
258
|
+
if (existingFetchData) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// Check if there are resource params
|
|
262
|
+
var resourceParams = ((_c = node.content.resource) === null || _c === void 0 ? void 0 : _c.params) || {};
|
|
263
|
+
var hasParams = Object.keys(resourceParams).length > 0;
|
|
264
|
+
// Build resource path - use template literal if params exist
|
|
265
|
+
var resourcePath = void 0;
|
|
266
|
+
if (hasParams) {
|
|
267
|
+
resourcePath = types.templateLiteral([
|
|
268
|
+
types.templateElement({ raw: "/api/".concat(fileName, "?"), cooked: "/api/".concat(fileName, "?") }),
|
|
269
|
+
types.templateElement({ raw: '', cooked: '' }),
|
|
270
|
+
], [types.newExpression(types.identifier('URLSearchParams'), [types.identifier('params')])]);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
resourcePath = types.stringLiteral("/api/".concat(fileName));
|
|
274
|
+
}
|
|
275
|
+
var fetchAST = types.callExpression(types.memberExpression(types.callExpression(types.identifier('fetch'), [
|
|
276
|
+
resourcePath,
|
|
277
|
+
types.objectExpression([
|
|
278
|
+
types.objectProperty(types.identifier('headers'), types.objectExpression([
|
|
279
|
+
types.objectProperty(types.stringLiteral('Content-Type'), types.stringLiteral('application/json')),
|
|
280
|
+
])),
|
|
281
|
+
]),
|
|
282
|
+
]), types.identifier('then')), [
|
|
283
|
+
types.arrowFunctionExpression([types.identifier('res')], types.callExpression(types.memberExpression(types.identifier('res'), types.identifier('json')), [])),
|
|
284
|
+
]);
|
|
285
|
+
var dataExpression = ASTUtils.generateMemberExpressionASTFromPath([
|
|
286
|
+
'response',
|
|
287
|
+
'data',
|
|
288
|
+
]);
|
|
289
|
+
// If there are params, the arrow function should accept params
|
|
290
|
+
var resourceAST = types.arrowFunctionExpression(hasParams ? [types.identifier('params')] : [], types.callExpression(types.memberExpression(fetchAST, types.identifier('then'), false), [
|
|
291
|
+
types.arrowFunctionExpression([types.identifier('response')], dataExpression),
|
|
292
|
+
]));
|
|
293
|
+
jsxNode.openingElement.attributes.unshift(types.jSXAttribute(types.jsxIdentifier('fetchData'), types.jsxExpressionContainer(resourceAST)));
|
|
294
|
+
var hasPersistDataAttr = jsxNode.openingElement.attributes.some(function (attr) {
|
|
295
|
+
var _a;
|
|
296
|
+
return attr.type === 'JSXAttribute' &&
|
|
297
|
+
((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) === 'persistDataDuringLoading';
|
|
298
|
+
});
|
|
299
|
+
if (!hasPersistDataAttr) {
|
|
300
|
+
jsxNode.openingElement.attributes.push(types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true))));
|
|
301
|
+
}
|
|
302
|
+
// Ensure extracted resources object exists
|
|
303
|
+
if (!extractedResources || typeof extractedResources !== 'object') {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
// Check if a utils file already exists for this data source (from getStaticProps)
|
|
307
|
+
// If so, create an API route that re-exports handler from it to avoid code duplication
|
|
308
|
+
if (extractedResources["utils/".concat(fileName)]) {
|
|
309
|
+
var apiRouteCode = "import dataSourceModule from '../../utils/data-sources/".concat(fileName, "'\n\nexport default dataSourceModule.handler\n");
|
|
310
|
+
extractedResources["api/".concat(fileName)] = {
|
|
311
|
+
fileName: fileName,
|
|
312
|
+
fileType: FileType.JS,
|
|
313
|
+
path: ['pages', 'api'],
|
|
314
|
+
content: apiRouteCode,
|
|
315
|
+
};
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
// Generate fetcher code with BOTH fetchData and handler
|
|
319
|
+
var fetcherCode = void 0;
|
|
320
|
+
try {
|
|
321
|
+
fetcherCode = generateDataSourceFetcherWithCore(dataSource, tableName || '');
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
extractedResources["api/".concat(fileName)] = {
|
|
327
|
+
fileName: fileName,
|
|
328
|
+
fileType: FileType.JS,
|
|
329
|
+
path: ['pages', 'api'],
|
|
330
|
+
content: fetcherCode,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
// Catch any unexpected errors to prevent plugin from crashing
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
export var isEmbeddedDataSource = function (dataSourceType) {
|
|
338
|
+
return ['javascript', 'csv-file', 'static-collection'].includes(dataSourceType);
|
|
339
|
+
};
|
|
340
|
+
export var replaceSecretReference = function (value, options) {
|
|
341
|
+
if (options === void 0) { options = {}; }
|
|
342
|
+
var _a = options.templateLiteral, templateLiteral = _a === void 0 ? false : _a;
|
|
343
|
+
// Handle null and undefined
|
|
344
|
+
if (value === null) {
|
|
345
|
+
return 'null';
|
|
346
|
+
}
|
|
347
|
+
if (value === undefined) {
|
|
348
|
+
return 'undefined';
|
|
349
|
+
}
|
|
350
|
+
// Handle non-string values
|
|
351
|
+
if (typeof value !== 'string') {
|
|
352
|
+
try {
|
|
353
|
+
return JSON.stringify(value);
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
// Handle circular references or non-serializable values
|
|
357
|
+
return 'null';
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Check if it's a secret reference
|
|
361
|
+
if (value.startsWith('teleporthq.secrets.')) {
|
|
362
|
+
var envVar = value.replace('teleporthq.secrets.', '');
|
|
363
|
+
// Validate environment variable name
|
|
364
|
+
// Must be alphanumeric, underscores, and start with letter or underscore
|
|
365
|
+
if (/^[A-Z_][A-Z0-9_]*$/i.test(envVar)) {
|
|
366
|
+
return templateLiteral ? "${process.env.".concat(envVar, "}") : "process.env.".concat(envVar);
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
// Invalid env var name, use as regular string
|
|
370
|
+
return JSON.stringify(value);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// Regular string value
|
|
374
|
+
try {
|
|
375
|
+
return JSON.stringify(value);
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
// Fallback for any serialization issues
|
|
379
|
+
return '""';
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
export var sanitizeNumericParam = function (value, defaultValue) {
|
|
383
|
+
if (defaultValue === void 0) { defaultValue = 0; }
|
|
384
|
+
if (typeof value === 'number' && !isNaN(value) && isFinite(value)) {
|
|
385
|
+
return Math.max(0, Math.floor(value));
|
|
386
|
+
}
|
|
387
|
+
if (typeof value === 'string') {
|
|
388
|
+
var parsed = parseInt(value, 10);
|
|
389
|
+
if (!isNaN(parsed) && isFinite(parsed)) {
|
|
390
|
+
return Math.max(0, parsed);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return defaultValue;
|
|
394
|
+
};
|
|
395
|
+
export var sanitizePort = function (port, defaultPort) {
|
|
396
|
+
var sanitized = sanitizeNumericParam(port, defaultPort);
|
|
397
|
+
// Ensure port is in valid range (1-65535)
|
|
398
|
+
if (sanitized < 1 || sanitized > 65535) {
|
|
399
|
+
return defaultPort;
|
|
400
|
+
}
|
|
401
|
+
return sanitized;
|
|
402
|
+
};
|
|
403
|
+
export var isValidUrl = function (url) {
|
|
404
|
+
if (typeof url !== 'string' || !url) {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
var parsed = new URL(url);
|
|
409
|
+
// Check for valid protocols
|
|
410
|
+
return ['http:', 'https:', 'mongodb:', 'redis:', 'postgresql:', 'mysql:'].includes(parsed.protocol);
|
|
411
|
+
}
|
|
412
|
+
catch (_a) {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
export var sanitizeIdentifier = function (identifier) {
|
|
417
|
+
if (typeof identifier !== 'string' || !identifier) {
|
|
418
|
+
return '';
|
|
419
|
+
}
|
|
420
|
+
// Remove dangerous characters, only allow safe ones
|
|
421
|
+
return identifier.replace(/[^a-zA-Z0-9_-]/g, '').substring(0, 64);
|
|
422
|
+
};
|
|
423
|
+
// tslint:disable-next-line:no-any
|
|
424
|
+
export var extractDataSourceIntoGetStaticProps = function (node, dataSources, componentChunk, getStaticPropsChunk, chunks, extractedResources, dependencies) {
|
|
425
|
+
var _a, _b;
|
|
426
|
+
try {
|
|
427
|
+
// Validate node content
|
|
428
|
+
var contentValidation = validateNodeContent(node.content);
|
|
429
|
+
if (!contentValidation.isValid) {
|
|
430
|
+
return { success: false };
|
|
431
|
+
}
|
|
432
|
+
var resourceDefinition = node.content.resourceDefinition;
|
|
433
|
+
var resourceValidation = validateResourceDefinition(resourceDefinition);
|
|
434
|
+
if (!resourceValidation.isValid) {
|
|
435
|
+
return { success: false };
|
|
436
|
+
}
|
|
437
|
+
var dataSourceId_1 = resourceDefinition.dataSourceId, tableName_1 = resourceDefinition.tableName, dataSourceType = resourceDefinition.dataSourceType;
|
|
438
|
+
if (!dataSources || typeof dataSources !== 'object') {
|
|
439
|
+
return { success: false };
|
|
440
|
+
}
|
|
441
|
+
var dataSource = dataSources[dataSourceId_1];
|
|
442
|
+
if (!dataSource) {
|
|
443
|
+
return { success: false };
|
|
444
|
+
}
|
|
445
|
+
var configValidation = validateDataSourceConfig(dataSource);
|
|
446
|
+
if (!configValidation.isValid) {
|
|
447
|
+
return { success: false };
|
|
448
|
+
}
|
|
449
|
+
if (!componentChunk.meta || !componentChunk.meta.nodesLookup) {
|
|
450
|
+
return { success: false };
|
|
451
|
+
}
|
|
452
|
+
// Generate prop key first
|
|
453
|
+
var sanitizedDsName = StringUtils.dashCaseToCamelCase(sanitizeFileName(dataSource.name || dataSourceId_1));
|
|
454
|
+
var sanitizedTableName = StringUtils.dashCaseToCamelCase(sanitizeFileName(tableName_1 || 'data'));
|
|
455
|
+
var propKey_1 = "".concat(sanitizedDsName, "_").concat(sanitizedTableName, "_data");
|
|
456
|
+
// Find ALL JSX nodes matching this dataSourceId AND tableName and add initialData to ALL of them
|
|
457
|
+
var matchingJsxNodes_2 = [];
|
|
458
|
+
// Helper function to recursively traverse the AST and find all matching JSXElements
|
|
459
|
+
var traverseAST_1 = function (astNode) {
|
|
460
|
+
var _a, _b;
|
|
461
|
+
if (!astNode || typeof astNode !== 'object') {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (astNode.type === 'JSXElement') {
|
|
465
|
+
var jsxElement = astNode;
|
|
466
|
+
var attrs = jsxElement.openingElement.attributes;
|
|
467
|
+
var resourceDefAttr = attrs.find(function (attr) {
|
|
468
|
+
return attr.type === 'JSXAttribute' &&
|
|
469
|
+
attr.name.name === 'resourceDefinition';
|
|
470
|
+
});
|
|
471
|
+
if (resourceDefAttr &&
|
|
472
|
+
resourceDefAttr.value &&
|
|
473
|
+
resourceDefAttr.value.type === 'JSXExpressionContainer') {
|
|
474
|
+
var expr = resourceDefAttr.value.expression;
|
|
475
|
+
if (expr.type === 'ObjectExpression') {
|
|
476
|
+
var props = expr.properties;
|
|
477
|
+
// tslint:disable-next-line:no-any
|
|
478
|
+
var idProp = props.find(function (p) { var _a; return ((_a = p.key) === null || _a === void 0 ? void 0 : _a.value) === 'dataSourceId'; });
|
|
479
|
+
// tslint:disable-next-line:no-any
|
|
480
|
+
var idValue = (_a = idProp === null || idProp === void 0 ? void 0 : idProp.value) === null || _a === void 0 ? void 0 : _a.value;
|
|
481
|
+
// Also check tableName to ensure we're matching the right data source
|
|
482
|
+
// tslint:disable-next-line:no-any
|
|
483
|
+
var tableNameProp = props.find(function (p) { var _a; return ((_a = p.key) === null || _a === void 0 ? void 0 : _a.value) === 'tableName'; });
|
|
484
|
+
// tslint:disable-next-line:no-any
|
|
485
|
+
var tableNameValue = (_b = tableNameProp === null || tableNameProp === void 0 ? void 0 : tableNameProp.value) === null || _b === void 0 ? void 0 : _b.value;
|
|
486
|
+
if (idValue === dataSourceId_1 && tableNameValue === tableName_1) {
|
|
487
|
+
matchingJsxNodes_2.push(jsxElement);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// Recursively traverse all properties
|
|
493
|
+
for (var key in astNode) {
|
|
494
|
+
if (astNode.hasOwnProperty(key)) {
|
|
495
|
+
var value = astNode[key];
|
|
496
|
+
if (Array.isArray(value)) {
|
|
497
|
+
value.forEach(function (item) { return traverseAST_1(item); });
|
|
498
|
+
}
|
|
499
|
+
else if (typeof value === 'object') {
|
|
500
|
+
traverseAST_1(value);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
// Traverse the entire component AST content
|
|
506
|
+
traverseAST_1(componentChunk.content);
|
|
507
|
+
if (matchingJsxNodes_2.length === 0) {
|
|
508
|
+
return { success: false };
|
|
509
|
+
}
|
|
510
|
+
// Update ALL matching JSX nodes with initialData
|
|
511
|
+
for (var _i = 0, matchingJsxNodes_1 = matchingJsxNodes_2; _i < matchingJsxNodes_1.length; _i++) {
|
|
512
|
+
var jsxNode = matchingJsxNodes_1[_i];
|
|
513
|
+
// For SSR/SSG with initialData, rename 'children' to 'renderSuccess'
|
|
514
|
+
var childrenAttrIndex = jsxNode.openingElement.attributes.findIndex(function (attr) { var _a; return ((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) === 'children'; });
|
|
515
|
+
if (childrenAttrIndex !== -1) {
|
|
516
|
+
var childrenAttr = jsxNode.openingElement.attributes[childrenAttrIndex];
|
|
517
|
+
var renderSuccessAttr = types.jsxAttribute(types.jsxIdentifier('renderSuccess'), childrenAttr.value);
|
|
518
|
+
jsxNode.openingElement.attributes[childrenAttrIndex] = renderSuccessAttr;
|
|
519
|
+
}
|
|
520
|
+
// Remove existing initialData and persistDataDuringLoading attributes to avoid duplicates
|
|
521
|
+
jsxNode.openingElement.attributes = jsxNode.openingElement.attributes.filter(function (attr) {
|
|
522
|
+
var _a, _b;
|
|
523
|
+
return ((_a = attr.name) === null || _a === void 0 ? void 0 : _a.name) !== 'initialData' &&
|
|
524
|
+
((_b = attr.name) === null || _b === void 0 ? void 0 : _b.name) !== 'persistDataDuringLoading';
|
|
525
|
+
});
|
|
526
|
+
// Add initialData attribute
|
|
527
|
+
var initialDataAttr = types.jsxAttribute(types.jsxIdentifier('initialData'), types.jsxExpressionContainer(types.memberExpression(types.identifier('props'), types.identifier(propKey_1))));
|
|
528
|
+
jsxNode.openingElement.attributes.push(initialDataAttr);
|
|
529
|
+
// Add persistDataDuringLoading={true}
|
|
530
|
+
var persistDataAttr = types.jsxAttribute(types.jsxIdentifier('persistDataDuringLoading'), types.jsxExpressionContainer(types.booleanLiteral(true)));
|
|
531
|
+
jsxNode.openingElement.attributes.push(persistDataAttr);
|
|
532
|
+
}
|
|
533
|
+
// Generate safe file name for the fetcher
|
|
534
|
+
var fileName = generateSafeFileName(dataSourceType, tableName_1 || 'data', dataSourceId_1);
|
|
535
|
+
if (!fileName || fileName === 'unknown') {
|
|
536
|
+
return { success: false };
|
|
537
|
+
}
|
|
538
|
+
// Generate fetcher code with core function
|
|
539
|
+
var fetcherCode = void 0;
|
|
540
|
+
try {
|
|
541
|
+
fetcherCode = generateDataSourceFetcherWithCore(dataSource, tableName_1 || '');
|
|
542
|
+
}
|
|
543
|
+
catch (error) {
|
|
544
|
+
// tslint:disable-next-line:no-console
|
|
545
|
+
console.error("Failed to generate fetcher for ".concat(dataSourceType, " (").concat(dataSourceId_1, "):"), error);
|
|
546
|
+
return { success: false };
|
|
547
|
+
}
|
|
548
|
+
// Ensure extracted resources object exists
|
|
549
|
+
if (!extractedResources || typeof extractedResources !== 'object') {
|
|
550
|
+
return { success: false };
|
|
551
|
+
}
|
|
552
|
+
// Add the fetcher to utils folder (for server-side use)
|
|
553
|
+
// Use a unique key to avoid conflicts with API routes
|
|
554
|
+
extractedResources["utils/".concat(fileName)] = {
|
|
555
|
+
fileName: fileName,
|
|
556
|
+
fileType: FileType.JS,
|
|
557
|
+
path: ['utils', 'data-sources'],
|
|
558
|
+
content: fetcherCode,
|
|
559
|
+
};
|
|
560
|
+
// Add dependency for the fetcher
|
|
561
|
+
var fetcherImportName = StringUtils.dashCaseToCamelCase(fileName);
|
|
562
|
+
dependencies[fetcherImportName] = {
|
|
563
|
+
type: 'local',
|
|
564
|
+
path: "../utils/data-sources/".concat(fileName),
|
|
565
|
+
};
|
|
566
|
+
// Build params object from resource params
|
|
567
|
+
// tslint:disable-next-line:no-any
|
|
568
|
+
var resourceParams = ((_a = node.content.resource) === null || _a === void 0 ? void 0 : _a.params) || {};
|
|
569
|
+
var paramsProperties_1 = [];
|
|
570
|
+
// tslint:disable-next-line:no-any
|
|
571
|
+
Object.entries(resourceParams).forEach(function (_a) {
|
|
572
|
+
var key = _a[0], value = _a[1];
|
|
573
|
+
if (value.type === 'static') {
|
|
574
|
+
var astValue = void 0;
|
|
575
|
+
if (value.content === null || value.content === undefined) {
|
|
576
|
+
astValue = types.nullLiteral();
|
|
577
|
+
}
|
|
578
|
+
else if (Array.isArray(value.content)) {
|
|
579
|
+
// Handle array values (like queryColumns)
|
|
580
|
+
astValue = types.arrayExpression(value.content.map(function (item) {
|
|
581
|
+
if (typeof item === 'string') {
|
|
582
|
+
return types.stringLiteral(item);
|
|
583
|
+
}
|
|
584
|
+
if (typeof item === 'number') {
|
|
585
|
+
return types.numericLiteral(item);
|
|
586
|
+
}
|
|
587
|
+
if (typeof item === 'boolean') {
|
|
588
|
+
return types.booleanLiteral(item);
|
|
589
|
+
}
|
|
590
|
+
return types.nullLiteral();
|
|
591
|
+
}));
|
|
592
|
+
}
|
|
593
|
+
else if (typeof value.content === 'string') {
|
|
594
|
+
astValue = types.stringLiteral(value.content);
|
|
595
|
+
}
|
|
596
|
+
else if (typeof value.content === 'number') {
|
|
597
|
+
astValue = types.numericLiteral(value.content);
|
|
598
|
+
}
|
|
599
|
+
else if (typeof value.content === 'boolean') {
|
|
600
|
+
astValue = types.booleanLiteral(value.content);
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
astValue = types.nullLiteral();
|
|
604
|
+
}
|
|
605
|
+
paramsProperties_1.push(types.objectProperty(types.stringLiteral(key), astValue));
|
|
606
|
+
}
|
|
607
|
+
// Note: We don't handle 'expr' or 'dynamic' params in getStaticProps
|
|
608
|
+
// as those should be detected by hasResourceDynamicParams check earlier
|
|
609
|
+
});
|
|
610
|
+
var fetchCallExpression = types.callExpression(types.memberExpression(types.identifier(fetcherImportName), types.identifier('fetchData')), [types.objectExpression(paramsProperties_1)]);
|
|
611
|
+
var safeFetchExpression = createSafeFetchExpression(fetchCallExpression, propKey_1);
|
|
612
|
+
// Get response value path (if specified)
|
|
613
|
+
var responseMemberAST = node.content.valuePath
|
|
614
|
+
? ASTUtils.generateMemberExpressionASTFromPath(__spreadArray([
|
|
615
|
+
propKey_1
|
|
616
|
+
], ASTUtils.parseValuePath(node.content.valuePath), true))
|
|
617
|
+
: types.identifier(propKey_1);
|
|
618
|
+
// Create or update getStaticProps chunk
|
|
619
|
+
var tryBlock = null;
|
|
620
|
+
if (!getStaticPropsChunk) {
|
|
621
|
+
tryBlock = types.tryStatement(types.blockStatement([
|
|
622
|
+
types.returnStatement(types.objectExpression([
|
|
623
|
+
types.objectProperty(types.identifier('props'), types.objectExpression([
|
|
624
|
+
types.objectProperty(types.identifier(propKey_1), responseMemberAST, false, false),
|
|
625
|
+
])),
|
|
626
|
+
types.objectProperty(types.identifier('revalidate'), types.numericLiteral(1)),
|
|
627
|
+
])),
|
|
628
|
+
]), types.catchClause(types.identifier('error'), types.blockStatement([
|
|
629
|
+
types.expressionStatement(types.callExpression(types.memberExpression(types.identifier('console'), types.identifier('error')), [types.stringLiteral('Error in getStaticProps:'), types.identifier('error')])),
|
|
630
|
+
types.returnStatement(types.objectExpression([
|
|
631
|
+
types.objectProperty(types.identifier('props'), types.objectExpression([])),
|
|
632
|
+
])),
|
|
633
|
+
])));
|
|
634
|
+
getStaticPropsChunk = {
|
|
635
|
+
name: 'getStaticProps',
|
|
636
|
+
type: ChunkType.AST,
|
|
637
|
+
fileType: FileType.JS,
|
|
638
|
+
content: types.exportNamedDeclaration(types.functionDeclaration(types.identifier('getStaticProps'), [types.identifier('context')], types.blockStatement([tryBlock]), false, true)),
|
|
639
|
+
linkAfter: ['jsx-component'],
|
|
640
|
+
};
|
|
641
|
+
chunks.push(getStaticPropsChunk);
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
// Update existing getStaticProps
|
|
645
|
+
var functionDeclaration = getStaticPropsChunk.content
|
|
646
|
+
.declaration;
|
|
647
|
+
var functionBody = functionDeclaration.body.body;
|
|
648
|
+
tryBlock = functionBody.find(function (subNode) { return subNode.type === 'TryStatement'; });
|
|
649
|
+
if (!tryBlock) {
|
|
650
|
+
return { success: false };
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
if (!tryBlock) {
|
|
654
|
+
return { success: false };
|
|
655
|
+
}
|
|
656
|
+
// Ensure props include current data source
|
|
657
|
+
var returnStatement = tryBlock.block.body.find(function (subNode) { return subNode.type === 'ReturnStatement'; });
|
|
658
|
+
if (!returnStatement) {
|
|
659
|
+
return { success: false };
|
|
660
|
+
}
|
|
661
|
+
var propsObject = returnStatement.argument.properties.find(function (property) { return property.key.name === 'props'; });
|
|
662
|
+
var propsValue = propsObject.value;
|
|
663
|
+
// Check if propKey already exists in the parallel fetch metadata
|
|
664
|
+
var parallelFetchMeta = (_b = getStaticPropsChunk.meta) === null || _b === void 0 ? void 0 : _b.parallelFetch;
|
|
665
|
+
var existingInFetchMeta = parallelFetchMeta === null || parallelFetchMeta === void 0 ? void 0 : parallelFetchMeta.names.includes(propKey_1);
|
|
666
|
+
// Always ensure both the fetch and the prop are in sync
|
|
667
|
+
if (!existingInFetchMeta) {
|
|
668
|
+
// Add to parallel fetch metadata
|
|
669
|
+
registerParallelFetch(getStaticPropsChunk, tryBlock, propKey_1, safeFetchExpression);
|
|
670
|
+
// Check if prop exists in return object
|
|
671
|
+
var existingProp = propsValue.properties.find(function (prop) {
|
|
672
|
+
return prop.type === 'ObjectProperty' &&
|
|
673
|
+
prop.key.type === 'Identifier' &&
|
|
674
|
+
prop.key.name === propKey_1;
|
|
675
|
+
});
|
|
676
|
+
// Add prop if it doesn't exist
|
|
677
|
+
if (!existingProp) {
|
|
678
|
+
propsValue.properties.unshift(types.objectProperty(types.identifier(propKey_1), responseMemberAST, false, false));
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return { success: true, chunk: getStaticPropsChunk };
|
|
682
|
+
}
|
|
683
|
+
catch (error) {
|
|
684
|
+
return { success: false };
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
var createSafeFetchExpression = function (fetchCallExpression, label) {
|
|
688
|
+
var errorIdentifier = types.identifier('error');
|
|
689
|
+
var catchHandler = types.arrowFunctionExpression([errorIdentifier], types.blockStatement([
|
|
690
|
+
types.expressionStatement(types.callExpression(types.memberExpression(types.identifier('console'), types.identifier('error')), [types.stringLiteral("Error fetching ".concat(label, ":")), errorIdentifier])),
|
|
691
|
+
types.returnStatement(types.arrayExpression([])),
|
|
692
|
+
]));
|
|
693
|
+
return types.callExpression(types.memberExpression(fetchCallExpression, types.identifier('catch')), [catchHandler]);
|
|
694
|
+
};
|
|
695
|
+
var registerParallelFetch = function (getStaticPropsChunk, tryBlock, propKey, expression) {
|
|
696
|
+
var _a;
|
|
697
|
+
if (!getStaticPropsChunk.meta) {
|
|
698
|
+
getStaticPropsChunk.meta = {};
|
|
699
|
+
}
|
|
700
|
+
var meta = (_a = getStaticPropsChunk.meta.parallelFetchData) !== null && _a !== void 0 ? _a : (getStaticPropsChunk.meta.parallelFetchData = {
|
|
701
|
+
names: [],
|
|
702
|
+
expressions: [],
|
|
703
|
+
});
|
|
704
|
+
meta.names.push(propKey);
|
|
705
|
+
meta.expressions.push(expression);
|
|
706
|
+
updateParallelFetchStatement(tryBlock, meta);
|
|
707
|
+
};
|
|
708
|
+
var updateParallelFetchStatement = function (tryBlock, meta) {
|
|
709
|
+
if (meta.declaration) {
|
|
710
|
+
var existingIndex = tryBlock.block.body.indexOf(meta.declaration);
|
|
711
|
+
if (existingIndex !== -1) {
|
|
712
|
+
tryBlock.block.body.splice(existingIndex, 1);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
var promiseAllCall = types.awaitExpression(types.callExpression(types.memberExpression(types.identifier('Promise'), types.identifier('all')), [types.arrayExpression(meta.expressions.map(function (expression) { return expression; }))]));
|
|
716
|
+
var arrayPattern = types.arrayPattern(meta.names.map(function (name) { return types.identifier(name); }));
|
|
717
|
+
meta.declaration = types.variableDeclaration('const', [
|
|
718
|
+
types.variableDeclarator(arrayPattern, promiseAllCall),
|
|
719
|
+
]);
|
|
720
|
+
tryBlock.block.body.unshift(meta.declaration);
|
|
721
|
+
};
|
|
722
|
+
//# sourceMappingURL=utils.js.map
|