@teleporthq/teleport-plugin-next-data-source 0.42.9 → 0.42.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/__tests__/csv-header-detection.test.ts +212 -0
  2. package/__tests__/validation.test.ts +33 -2
  3. package/dist/cjs/data-source-fetchers.d.ts +2 -2
  4. package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
  5. package/dist/cjs/data-source-fetchers.js +30 -7
  6. package/dist/cjs/data-source-fetchers.js.map +1 -1
  7. package/dist/cjs/fetchers/airtable.d.ts.map +1 -1
  8. package/dist/cjs/fetchers/airtable.js +1 -1
  9. package/dist/cjs/fetchers/airtable.js.map +1 -1
  10. package/dist/cjs/fetchers/clickhouse.d.ts.map +1 -1
  11. package/dist/cjs/fetchers/clickhouse.js +1 -1
  12. package/dist/cjs/fetchers/clickhouse.js.map +1 -1
  13. package/dist/cjs/fetchers/csv-file.d.ts.map +1 -1
  14. package/dist/cjs/fetchers/csv-file.js +22 -3
  15. package/dist/cjs/fetchers/csv-file.js.map +1 -1
  16. package/dist/cjs/fetchers/firestore.d.ts.map +1 -1
  17. package/dist/cjs/fetchers/firestore.js +1 -1
  18. package/dist/cjs/fetchers/firestore.js.map +1 -1
  19. package/dist/cjs/fetchers/google-sheets.d.ts.map +1 -1
  20. package/dist/cjs/fetchers/google-sheets.js +6 -1
  21. package/dist/cjs/fetchers/google-sheets.js.map +1 -1
  22. package/dist/cjs/fetchers/javascript.d.ts.map +1 -1
  23. package/dist/cjs/fetchers/javascript.js +1 -1
  24. package/dist/cjs/fetchers/javascript.js.map +1 -1
  25. package/dist/cjs/fetchers/mariadb.d.ts.map +1 -1
  26. package/dist/cjs/fetchers/mariadb.js +3 -3
  27. package/dist/cjs/fetchers/mariadb.js.map +1 -1
  28. package/dist/cjs/fetchers/mongodb.d.ts +1 -1
  29. package/dist/cjs/fetchers/mongodb.d.ts.map +1 -1
  30. package/dist/cjs/fetchers/mongodb.js +11 -3
  31. package/dist/cjs/fetchers/mongodb.js.map +1 -1
  32. package/dist/cjs/fetchers/mysql.d.ts.map +1 -1
  33. package/dist/cjs/fetchers/mysql.js +2 -2
  34. package/dist/cjs/fetchers/mysql.js.map +1 -1
  35. package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
  36. package/dist/cjs/fetchers/postgresql.js +3 -3
  37. package/dist/cjs/fetchers/postgresql.js.map +1 -1
  38. package/dist/cjs/fetchers/redis.d.ts.map +1 -1
  39. package/dist/cjs/fetchers/redis.js +1 -1
  40. package/dist/cjs/fetchers/redis.js.map +1 -1
  41. package/dist/cjs/fetchers/redshift.d.ts.map +1 -1
  42. package/dist/cjs/fetchers/redshift.js +2 -2
  43. package/dist/cjs/fetchers/redshift.js.map +1 -1
  44. package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
  45. package/dist/cjs/fetchers/rest-api.js +2 -2
  46. package/dist/cjs/fetchers/rest-api.js.map +1 -1
  47. package/dist/cjs/fetchers/static-collection.d.ts.map +1 -1
  48. package/dist/cjs/fetchers/static-collection.js +1 -1
  49. package/dist/cjs/fetchers/static-collection.js.map +1 -1
  50. package/dist/cjs/fetchers/supabase.d.ts.map +1 -1
  51. package/dist/cjs/fetchers/supabase.js +2 -2
  52. package/dist/cjs/fetchers/supabase.js.map +1 -1
  53. package/dist/cjs/fetchers/turso.d.ts.map +1 -1
  54. package/dist/cjs/fetchers/turso.js +1 -1
  55. package/dist/cjs/fetchers/turso.js.map +1 -1
  56. package/dist/cjs/fetchers/utils/header-detection.d.ts +2 -0
  57. package/dist/cjs/fetchers/utils/header-detection.d.ts.map +1 -0
  58. package/dist/cjs/fetchers/utils/header-detection.js +8 -0
  59. package/dist/cjs/fetchers/utils/header-detection.js.map +1 -0
  60. package/dist/cjs/index.d.ts.map +1 -1
  61. package/dist/cjs/index.js +168 -4
  62. package/dist/cjs/index.js.map +1 -1
  63. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  64. package/dist/cjs/pagination-plugin.js +320 -65
  65. package/dist/cjs/pagination-plugin.js.map +1 -1
  66. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  67. package/dist/cjs/utils.d.ts +2 -0
  68. package/dist/cjs/utils.d.ts.map +1 -1
  69. package/dist/cjs/utils.js +214 -46
  70. package/dist/cjs/utils.js.map +1 -1
  71. package/dist/esm/data-source-fetchers.d.ts +2 -2
  72. package/dist/esm/data-source-fetchers.d.ts.map +1 -1
  73. package/dist/esm/data-source-fetchers.js +29 -6
  74. package/dist/esm/data-source-fetchers.js.map +1 -1
  75. package/dist/esm/fetchers/airtable.d.ts.map +1 -1
  76. package/dist/esm/fetchers/airtable.js +2 -2
  77. package/dist/esm/fetchers/airtable.js.map +1 -1
  78. package/dist/esm/fetchers/clickhouse.d.ts.map +1 -1
  79. package/dist/esm/fetchers/clickhouse.js +2 -2
  80. package/dist/esm/fetchers/clickhouse.js.map +1 -1
  81. package/dist/esm/fetchers/csv-file.d.ts.map +1 -1
  82. package/dist/esm/fetchers/csv-file.js +23 -4
  83. package/dist/esm/fetchers/csv-file.js.map +1 -1
  84. package/dist/esm/fetchers/firestore.d.ts.map +1 -1
  85. package/dist/esm/fetchers/firestore.js +2 -2
  86. package/dist/esm/fetchers/firestore.js.map +1 -1
  87. package/dist/esm/fetchers/google-sheets.d.ts.map +1 -1
  88. package/dist/esm/fetchers/google-sheets.js +6 -1
  89. package/dist/esm/fetchers/google-sheets.js.map +1 -1
  90. package/dist/esm/fetchers/javascript.d.ts.map +1 -1
  91. package/dist/esm/fetchers/javascript.js +2 -2
  92. package/dist/esm/fetchers/javascript.js.map +1 -1
  93. package/dist/esm/fetchers/mariadb.d.ts.map +1 -1
  94. package/dist/esm/fetchers/mariadb.js +4 -4
  95. package/dist/esm/fetchers/mariadb.js.map +1 -1
  96. package/dist/esm/fetchers/mongodb.d.ts +1 -1
  97. package/dist/esm/fetchers/mongodb.d.ts.map +1 -1
  98. package/dist/esm/fetchers/mongodb.js +12 -4
  99. package/dist/esm/fetchers/mongodb.js.map +1 -1
  100. package/dist/esm/fetchers/mysql.d.ts.map +1 -1
  101. package/dist/esm/fetchers/mysql.js +3 -3
  102. package/dist/esm/fetchers/mysql.js.map +1 -1
  103. package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
  104. package/dist/esm/fetchers/postgresql.js +4 -4
  105. package/dist/esm/fetchers/postgresql.js.map +1 -1
  106. package/dist/esm/fetchers/redis.d.ts.map +1 -1
  107. package/dist/esm/fetchers/redis.js +2 -2
  108. package/dist/esm/fetchers/redis.js.map +1 -1
  109. package/dist/esm/fetchers/redshift.d.ts.map +1 -1
  110. package/dist/esm/fetchers/redshift.js +3 -3
  111. package/dist/esm/fetchers/redshift.js.map +1 -1
  112. package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
  113. package/dist/esm/fetchers/rest-api.js +3 -3
  114. package/dist/esm/fetchers/rest-api.js.map +1 -1
  115. package/dist/esm/fetchers/static-collection.d.ts.map +1 -1
  116. package/dist/esm/fetchers/static-collection.js +2 -2
  117. package/dist/esm/fetchers/static-collection.js.map +1 -1
  118. package/dist/esm/fetchers/supabase.d.ts.map +1 -1
  119. package/dist/esm/fetchers/supabase.js +3 -3
  120. package/dist/esm/fetchers/supabase.js.map +1 -1
  121. package/dist/esm/fetchers/turso.d.ts.map +1 -1
  122. package/dist/esm/fetchers/turso.js +2 -2
  123. package/dist/esm/fetchers/turso.js.map +1 -1
  124. package/dist/esm/fetchers/utils/header-detection.d.ts +2 -0
  125. package/dist/esm/fetchers/utils/header-detection.d.ts.map +1 -0
  126. package/dist/esm/fetchers/utils/header-detection.js +4 -0
  127. package/dist/esm/fetchers/utils/header-detection.js.map +1 -0
  128. package/dist/esm/index.d.ts.map +1 -1
  129. package/dist/esm/index.js +169 -5
  130. package/dist/esm/index.js.map +1 -1
  131. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  132. package/dist/esm/pagination-plugin.js +320 -65
  133. package/dist/esm/pagination-plugin.js.map +1 -1
  134. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  135. package/dist/esm/utils.d.ts +2 -0
  136. package/dist/esm/utils.d.ts.map +1 -1
  137. package/dist/esm/utils.js +211 -45
  138. package/dist/esm/utils.js.map +1 -1
  139. package/package.json +3 -3
  140. package/src/data-source-fetchers.ts +29 -13
  141. package/src/fetchers/airtable.ts +78 -30
  142. package/src/fetchers/clickhouse.ts +85 -18
  143. package/src/fetchers/csv-file.ts +254 -29
  144. package/src/fetchers/firestore.ts +62 -12
  145. package/src/fetchers/google-sheets.ts +147 -30
  146. package/src/fetchers/javascript.ts +102 -23
  147. package/src/fetchers/mariadb.ts +82 -25
  148. package/src/fetchers/mongodb.ts +153 -36
  149. package/src/fetchers/mysql.ts +83 -25
  150. package/src/fetchers/postgresql.ts +86 -26
  151. package/src/fetchers/redis.ts +40 -4
  152. package/src/fetchers/redshift.ts +84 -17
  153. package/src/fetchers/rest-api.ts +101 -24
  154. package/src/fetchers/static-collection.ts +96 -18
  155. package/src/fetchers/supabase.ts +175 -53
  156. package/src/fetchers/turso.ts +84 -17
  157. package/src/fetchers/utils/header-detection.ts +200 -0
  158. package/src/index.ts +248 -2
  159. package/src/pagination-plugin.ts +708 -191
  160. package/src/utils.ts +344 -38
package/src/index.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { ComponentPlugin, ComponentPluginFactory, FileType } from '@teleporthq/teleport-types'
1
+ import {
2
+ ComponentPlugin,
3
+ ComponentPluginFactory,
4
+ FileType,
5
+ ChunkType,
6
+ } from '@teleporthq/teleport-types'
2
7
  import { UIDLUtils, StringUtils } from '@teleporthq/teleport-shared'
3
8
  import {
4
9
  extractDataSourceIntoNextAPIFolder,
@@ -486,6 +491,9 @@ export const createNextPagesDataSourcePlugin: ComponentPluginFactory<{}> = () =>
486
491
  let firstDataSourceInfo: DataSourceInfo | null = null
487
492
  // Track fetcher import name for wrapped providers
488
493
  let fetcherImportName: string | null = null
494
+ // Track the position counter for each (dataSourceId, tableName) combination
495
+ // This is used to match the correct DataProvider in the JSX based on UIDL order
496
+ const dataProviderPositionCounters = new Map<string, number>()
489
497
 
490
498
  UIDLUtils.traverseNodes(uidl.node, (node) => {
491
499
  // Data source nodes can be either:
@@ -527,7 +535,59 @@ export const createNextPagesDataSourcePlugin: ComponentPluginFactory<{}> = () =>
527
535
  return
528
536
  }
529
537
 
530
- const dataSourceKey = `${resourceDef.dataSourceId}:${resourceDef.tableName || 'data'}`
538
+ // Track the position of this data-source-list for matching the correct DataProvider
539
+ // The key is (dataSourceId, tableName) since all matching DataProviders share these
540
+ const positionKey = `${resourceDef.dataSourceId}:${resourceDef.tableName || 'data'}`
541
+ const currentPosition = dataProviderPositionCounters.get(positionKey) || 0
542
+ dataProviderPositionCounters.set(positionKey, currentPosition + 1)
543
+
544
+ // Check if this data-source-list contains a cms-list-repeater with pagination or search
545
+ // If so, skip it - the pagination plugin will handle the data fetching
546
+ // tslint:disable-next-line:no-any
547
+ const hasPaginatedOrSearchRepeater = (nodeToCheck: any): boolean => {
548
+ if (!nodeToCheck || typeof nodeToCheck !== 'object') {
549
+ return false
550
+ }
551
+
552
+ if (nodeToCheck.type === 'cms-list-repeater') {
553
+ const content = nodeToCheck.content
554
+ if (content?.paginated || content?.searchEnabled) {
555
+ return true
556
+ }
557
+ }
558
+
559
+ // Check children array
560
+ if (nodeToCheck.content?.children && Array.isArray(nodeToCheck.content.children)) {
561
+ for (const child of nodeToCheck.content.children) {
562
+ if (hasPaginatedOrSearchRepeater(child)) {
563
+ return true
564
+ }
565
+ }
566
+ }
567
+
568
+ // Check nodes object (data-source-list has nodes.success, nodes.error, etc.)
569
+ if (nodeToCheck.content?.nodes && typeof nodeToCheck.content.nodes === 'object') {
570
+ for (const nodeKey of Object.keys(nodeToCheck.content.nodes)) {
571
+ if (hasPaginatedOrSearchRepeater(nodeToCheck.content.nodes[nodeKey])) {
572
+ return true
573
+ }
574
+ }
575
+ }
576
+
577
+ return false
578
+ }
579
+
580
+ if (hasPaginatedOrSearchRepeater(dataSourceNode)) {
581
+ // Skip this node but position counter is already incremented above
582
+ return
583
+ }
584
+
585
+ // Include resource ID to differentiate between same dataSource/table with different params (sorts, filters, etc.)
586
+ // tslint:disable-next-line:no-any
587
+ const resourceId = (dataSourceNode.content.resource as any)?.id || ''
588
+ const dataSourceKey = `${resourceDef.dataSourceId}:${
589
+ resourceDef.tableName || 'data'
590
+ }:${resourceId}`
531
591
 
532
592
  // Check if resource has dynamic parameters
533
593
  // tslint:disable-next-line:no-any
@@ -762,6 +822,94 @@ export const createNextPagesDataSourcePlugin: ComponentPluginFactory<{}> = () =>
762
822
  }
763
823
  }
764
824
 
825
+ // Stringify complex params in DataProvider components before pagination plugin runs
826
+ stringifyComplexParamsInDataProviders(componentChunk)
827
+
828
+ // If getStaticProps doesn't exist yet but we have paginated/search data sources,
829
+ // create a basic getStaticProps structure for the pagination plugin to populate
830
+ if (!getStaticPropsChunk && opts.paginationConfig) {
831
+ const hasPaginatedOrSearchDataSources =
832
+ opts.paginationConfig.perPageMap.size > 0 || opts.paginationConfig.searchConfigMap.size > 0
833
+
834
+ if (hasPaginatedOrSearchDataSources) {
835
+ // Create a basic getStaticProps structure with Promise.all
836
+ const getStaticPropsAST = types.exportNamedDeclaration(
837
+ (() => {
838
+ const node = types.functionDeclaration(
839
+ types.identifier('getStaticProps'),
840
+ [types.identifier('context')],
841
+ types.blockStatement([
842
+ types.tryStatement(
843
+ types.blockStatement([
844
+ // Create Promise.all structure that updateGetStaticProps expects
845
+ types.variableDeclaration('const', [
846
+ types.variableDeclarator(
847
+ types.arrayPattern([]),
848
+ types.awaitExpression(
849
+ types.callExpression(
850
+ types.memberExpression(
851
+ types.identifier('Promise'),
852
+ types.identifier('all')
853
+ ),
854
+ [types.arrayExpression([])]
855
+ )
856
+ )
857
+ ),
858
+ ]),
859
+ types.returnStatement(
860
+ types.objectExpression([
861
+ types.objectProperty(types.identifier('props'), types.objectExpression([])),
862
+ ])
863
+ ),
864
+ ]),
865
+ types.catchClause(
866
+ types.identifier('error'),
867
+ types.blockStatement([
868
+ types.expressionStatement(
869
+ types.callExpression(
870
+ types.memberExpression(
871
+ types.identifier('console'),
872
+ types.identifier('error')
873
+ ),
874
+ [
875
+ types.stringLiteral('Error in getStaticProps:'),
876
+ types.identifier('error'),
877
+ ]
878
+ )
879
+ ),
880
+ types.returnStatement(
881
+ types.objectExpression([
882
+ types.objectProperty(
883
+ types.identifier('props'),
884
+ types.objectExpression([])
885
+ ),
886
+ ])
887
+ ),
888
+ ])
889
+ )
890
+ ),
891
+ ]),
892
+ false,
893
+ true
894
+ )
895
+
896
+ node.async = true
897
+ return node
898
+ })()
899
+ )
900
+
901
+ getStaticPropsChunk = {
902
+ name: 'getStaticProps',
903
+ type: ChunkType.AST,
904
+ fileType: FileType.JS,
905
+ content: getStaticPropsAST,
906
+ linkAfter: ['jsx-component'],
907
+ }
908
+
909
+ chunks.push(getStaticPropsChunk)
910
+ }
911
+ }
912
+
765
913
  const paginationPlugin = createNextArrayMapperPaginationPlugin()
766
914
  return paginationPlugin(structure)
767
915
  }
@@ -769,6 +917,101 @@ export const createNextPagesDataSourcePlugin: ComponentPluginFactory<{}> = () =>
769
917
  return nextPagesDataSourcePlugin
770
918
  }
771
919
 
920
+ // Helper function to stringify complex params (sorts, filters) in DataProvider components
921
+ function stringifyComplexParamsInDataProviders(componentChunk: any): void {
922
+ if (!componentChunk || !componentChunk.content) {
923
+ return
924
+ }
925
+
926
+ // tslint:disable-next-line:no-any
927
+ const traverseAST = (astNode: any): void => {
928
+ if (!astNode || typeof astNode !== 'object') {
929
+ return
930
+ }
931
+
932
+ // Check if this is a DataProvider JSXElement
933
+ if (astNode.type === 'JSXElement' && astNode.openingElement?.name?.name === 'DataProvider') {
934
+ const attrs = astNode.openingElement.attributes
935
+
936
+ // Find the params attribute
937
+ const paramsAttr = attrs.find(
938
+ // tslint:disable-next-line:no-any
939
+ (attr: any) =>
940
+ attr.type === 'JSXAttribute' &&
941
+ attr.name?.name === 'params' &&
942
+ attr.value?.type === 'JSXExpressionContainer'
943
+ )
944
+
945
+ if (paramsAttr) {
946
+ let paramsObj = null
947
+
948
+ // Handle direct ObjectExpression
949
+ if (paramsAttr.value?.expression?.type === 'ObjectExpression') {
950
+ paramsObj = paramsAttr.value.expression
951
+ }
952
+ // Handle useMemo wrapped params: useMemo(() => ({...}), [...])
953
+ else if (
954
+ paramsAttr.value?.expression?.type === 'CallExpression' &&
955
+ paramsAttr.value.expression.callee?.name === 'useMemo' &&
956
+ paramsAttr.value.expression.arguments?.length > 0
957
+ ) {
958
+ const firstArg = paramsAttr.value.expression.arguments[0]
959
+ // Check if it's an arrow function returning an object
960
+ if (
961
+ firstArg.type === 'ArrowFunctionExpression' &&
962
+ firstArg.body?.type === 'ObjectExpression'
963
+ ) {
964
+ paramsObj = firstArg.body
965
+ }
966
+ }
967
+
968
+ if (paramsObj && paramsObj.properties) {
969
+ const properties = paramsObj.properties
970
+
971
+ // Find sorts, filters and queryColumns properties and stringify them
972
+ for (let i = 0; i < properties.length; i++) {
973
+ const prop = properties[i]
974
+ // Get the key name from either Identifier or StringLiteral
975
+ const keyName =
976
+ prop.key?.type === 'Identifier'
977
+ ? prop.key.name
978
+ : prop.key?.type === 'StringLiteral'
979
+ ? prop.key.value
980
+ : undefined
981
+
982
+ if (
983
+ prop.type === 'ObjectProperty' &&
984
+ (keyName === 'sorts' || keyName === 'filters' || keyName === 'queryColumns') &&
985
+ prop.value?.type === 'ArrayExpression'
986
+ ) {
987
+ // Replace the array with JSON.stringify(array)
988
+ properties[i] = types.objectProperty(
989
+ prop.key,
990
+ types.callExpression(
991
+ types.memberExpression(types.identifier('JSON'), types.identifier('stringify')),
992
+ [prop.value]
993
+ )
994
+ )
995
+ }
996
+ }
997
+ }
998
+ }
999
+ }
1000
+
1001
+ // Recursively traverse all properties
1002
+ for (const key of Object.keys(astNode)) {
1003
+ const value = astNode[key]
1004
+ if (Array.isArray(value)) {
1005
+ value.forEach((item) => traverseAST(item))
1006
+ } else if (typeof value === 'object' && value !== null) {
1007
+ traverseAST(value)
1008
+ }
1009
+ }
1010
+ }
1011
+
1012
+ traverseAST(componentChunk.content)
1013
+ }
1014
+
772
1015
  export const createNextComponentDataSourcePlugin: ComponentPluginFactory<{}> = () => {
773
1016
  const nextComponentDataSourcePlugin: ComponentPlugin = async (structure) => {
774
1017
  const { uidl, chunks, options, dependencies } = structure
@@ -995,6 +1238,9 @@ export default dataSourceModule.handler
995
1238
  }
996
1239
  }
997
1240
 
1241
+ // Stringify complex params in DataProvider components before pagination plugin runs
1242
+ stringifyComplexParamsInDataProviders(componentChunk)
1243
+
998
1244
  const paginationPlugin = createNextArrayMapperPaginationPlugin()
999
1245
  return paginationPlugin(structure)
1000
1246
  }