@kubb/plugin-vue-query 5.0.0-beta.56 → 5.0.0-beta.64

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 (40) hide show
  1. package/dist/{components-B79Gljyl.js → components-CAlEf7Oh.js} +114 -191
  2. package/dist/components-CAlEf7Oh.js.map +1 -0
  3. package/dist/{components-D3xIZ9FA.cjs → components-CfU59l8V.cjs} +113 -190
  4. package/dist/components-CfU59l8V.cjs.map +1 -0
  5. package/dist/components.cjs +1 -1
  6. package/dist/components.d.ts +1 -1
  7. package/dist/components.js +1 -1
  8. package/dist/{generators-BTtcGtUY.cjs → generators-DpMLVmyi.cjs} +2 -2
  9. package/dist/{generators-BTtcGtUY.cjs.map → generators-DpMLVmyi.cjs.map} +1 -1
  10. package/dist/{generators-D95ddIFV.js → generators-fWBjs0CN.js} +2 -2
  11. package/dist/{generators-D95ddIFV.js.map → generators-fWBjs0CN.js.map} +1 -1
  12. package/dist/generators.cjs +1 -1
  13. package/dist/generators.d.ts +1 -1
  14. package/dist/generators.js +1 -1
  15. package/dist/index.cjs +8 -8
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.js +8 -8
  19. package/dist/index.js.map +1 -1
  20. package/dist/{types-CwabLiFK.d.ts → types-C6a_58nb.d.ts} +3 -3
  21. package/package.json +8 -9
  22. package/dist/components-B79Gljyl.js.map +0 -1
  23. package/dist/components-D3xIZ9FA.cjs.map +0 -1
  24. package/src/components/InfiniteQuery.tsx +0 -127
  25. package/src/components/InfiniteQueryOptions.tsx +0 -191
  26. package/src/components/Mutation.tsx +0 -150
  27. package/src/components/MutationKey.tsx +0 -1
  28. package/src/components/Query.tsx +0 -126
  29. package/src/components/QueryKey.tsx +0 -52
  30. package/src/components/QueryOptions.tsx +0 -116
  31. package/src/components/index.ts +0 -7
  32. package/src/generators/index.ts +0 -3
  33. package/src/generators/infiniteQueryGenerator.tsx +0 -196
  34. package/src/generators/mutationGenerator.tsx +0 -157
  35. package/src/generators/queryGenerator.tsx +0 -180
  36. package/src/index.ts +0 -2
  37. package/src/plugin.ts +0 -183
  38. package/src/resolvers/resolverVueQuery.ts +0 -76
  39. package/src/types.ts +0 -268
  40. package/src/utils.ts +0 -57
@@ -1,9 +1,9 @@
1
1
  import { t as __name } from "./chunk-C0LytTxp.js";
2
2
  import { ast } from "@kubb/core";
3
- import { functionPrinter } from "@kubb/plugin-ts";
3
+ import { buildGroupParam, caseParams, createOperationParams, getNestedAccessor, resolveGroupType, resolveParamType } from "@kubb/ast/utils";
4
+ import { functionPrinter, renderType } from "@kubb/plugin-ts";
4
5
  import { File, Function, Type } from "@kubb/renderer-jsx";
5
6
  import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
6
- import { getNestedAccessor } from "@kubb/ast/utils";
7
7
  //#region ../../internals/utils/src/casing.ts
8
8
  /**
9
9
  * Shared implementation for camelCase and PascalCase conversion.
@@ -278,7 +278,7 @@ function buildOperationComments(node, options = {}) {
278
278
  return filteredComments.flatMap((text) => text.split(/\r?\n/).map((line) => line.trim())).filter((comment) => Boolean(comment));
279
279
  }
280
280
  function getOperationParameters(node, options = {}) {
281
- const params = ast.caseParams(node.parameters, options.paramsCasing);
281
+ const params = caseParams(node.parameters, options.paramsCasing);
282
282
  return {
283
283
  path: params.filter((param) => param.in === "path"),
284
284
  query: params.filter((param) => param.in === "query"),
@@ -360,7 +360,7 @@ const mutationKeyTransformer = ({ node }) => {
360
360
  return [`{ url: '${Url.toPath(node.path)}' }`];
361
361
  };
362
362
  function MutationKey({ name, paramsCasing, node, transformer }) {
363
- const paramsNode = ast.createFunctionParameters({ params: [] });
363
+ const paramsNode = ast.factory.createFunctionParameters({ params: [] });
364
364
  const paramsSignature = declarationPrinter$7.print(paramsNode) ?? "";
365
365
  const keys = (transformer ?? mutationKeyTransformer)({
366
366
  node,
@@ -382,6 +382,14 @@ function MutationKey({ name, paramsCasing, node, transformer }) {
382
382
  //#endregion
383
383
  //#region ../../internals/tanstack-query/src/utils.ts
384
384
  /**
385
+ * Returns the `TypeLiteral` members of a destructured group parameter, or `null`
386
+ * for a plain named parameter.
387
+ */
388
+ function groupMembers(param) {
389
+ if (typeof param.name === "string") return null;
390
+ return param.type && typeof param.type !== "string" && param.type.kind === "TypeLiteral" ? param.type.members : [];
391
+ }
392
+ /**
385
393
  * Builds the shared `(…params, config = {})` parameter list for a TanStack
386
394
  * query-options function. The trailing `config` parameter is typed as a partial
387
395
  * `RequestConfig` with an optional `client`. Framework plugins wrap the result
@@ -390,17 +398,14 @@ function MutationKey({ name, paramsCasing, node, transformer }) {
390
398
  function buildQueryOptionsParams(node, options) {
391
399
  const { paramsType, paramsCasing, pathParamsType, resolver } = options;
392
400
  const requestName = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : void 0;
393
- return ast.createOperationParams(node, {
401
+ return createOperationParams(node, {
394
402
  paramsType,
395
403
  pathParamsType: paramsType === "object" ? "object" : pathParamsType === "object" ? "object" : "inline",
396
404
  paramsCasing,
397
405
  resolver,
398
- extraParams: [ast.createFunctionParameter({
406
+ extraParams: [ast.factory.createFunctionParameter({
399
407
  name: "config",
400
- type: ast.createParamsType({
401
- variant: "reference",
402
- name: requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : "Partial<RequestConfig> & { client?: Client }"
403
- }),
408
+ type: requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : "Partial<RequestConfig> & { client?: Client }",
404
409
  default: "{}"
405
410
  })]
406
411
  });
@@ -451,107 +456,52 @@ function resolveZodSchemaNames(node, zodResolver, parser) {
451
456
  ].filter((n) => Boolean(n));
452
457
  }
453
458
  /**
454
- * Resolve the type for a single path parameter.
455
- *
456
- * - When the resolver's group name differs from the individual param name
457
- * (e.g. kubbV4) → `GroupName['paramName']` (member access).
458
- * - When they match (v5 default) → `TypeName` (direct reference).
459
- */
460
- function resolvePathParamType(node, param, resolver) {
461
- const individualName = resolver.resolveParamName(node, param);
462
- const groupName = resolver.resolvePathParamsName(node, param);
463
- if (groupName !== individualName) return ast.createParamsType({
464
- variant: "member",
465
- base: groupName,
466
- key: param.name
467
- });
468
- return ast.createParamsType({
469
- variant: "reference",
470
- name: individualName
471
- });
472
- }
473
- /**
474
- * Derive a query-params group type from the resolver.
475
- * Returns `null` when no query params exist or when the group name
476
- * equals the individual param name (no real group).
477
- */
478
- function resolveQueryGroupType(node, params, resolver) {
479
- if (!params.length) return null;
480
- const firstParam = params[0];
481
- const groupName = resolver.resolveQueryParamsName(node, firstParam);
482
- if (groupName === resolver.resolveParamName(node, firstParam)) return null;
483
- return {
484
- type: ast.createParamsType({
485
- variant: "reference",
486
- name: groupName
487
- }),
488
- optional: params.every((p) => !p.required)
489
- };
490
- }
491
- /**
492
- * Build a single `FunctionParameterNode` for a query or header group.
493
- */
494
- function buildGroupParam(name, node, params, groupType, resolver) {
495
- if (groupType) return [ast.createFunctionParameter({
496
- name,
497
- type: groupType.type,
498
- optional: groupType.optional
499
- })];
500
- if (params.length) {
501
- const structProps = params.map((p) => ({
502
- name: p.name,
503
- type: ast.createParamsType({
504
- variant: "reference",
505
- name: resolver.resolveParamName(node, p)
506
- }),
507
- optional: !p.required
508
- }));
509
- return [ast.createFunctionParameter({
510
- name,
511
- type: ast.createParamsType({
512
- variant: "struct",
513
- properties: structProps
514
- }),
515
- optional: params.every((p) => !p.required)
516
- })];
517
- }
518
- return [];
519
- }
520
- /**
521
459
  * Build QueryKey params: pathParams + data + queryParams (NO headers, NO config).
522
460
  */
523
461
  function buildQueryKeyParams(node, options) {
524
462
  const { pathParamsType, paramsCasing, resolver } = options;
525
- const casedParams = ast.caseParams(node.parameters, paramsCasing);
463
+ const casedParams = caseParams(node.parameters, paramsCasing);
526
464
  const pathParams = casedParams.filter((p) => p.in === "path");
527
465
  const queryParams = casedParams.filter((p) => p.in === "query");
528
- const queryGroupType = resolveQueryGroupType(node, queryParams, resolver);
529
- const bodyType = node.requestBody?.content?.[0]?.schema ? ast.createParamsType({
530
- variant: "reference",
531
- name: resolver.resolveDataName(node)
532
- }) : null;
466
+ const queryGroupType = resolveGroupType({
467
+ node,
468
+ params: queryParams,
469
+ group: "query",
470
+ resolver
471
+ });
472
+ const bodyType = node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null;
533
473
  const bodyRequired = node.requestBody?.required ?? false;
534
474
  const params = [];
535
475
  if (pathParams.length) {
536
- const pathChildren = pathParams.map((p) => ast.createFunctionParameter({
476
+ const pathChildren = pathParams.map((p) => ({
537
477
  name: p.name,
538
- type: resolvePathParamType(node, p, resolver),
478
+ type: resolveParamType({
479
+ node,
480
+ param: p,
481
+ resolver
482
+ }),
539
483
  optional: !p.required
540
484
  }));
541
- params.push({
542
- kind: "ParameterGroup",
485
+ if (pathParamsType === "object") params.push(ast.factory.createFunctionParameter({
543
486
  properties: pathChildren,
544
- inline: pathParamsType === "inline",
545
487
  default: pathChildren.every((c) => c.optional) ? "{}" : void 0
546
- });
488
+ }));
489
+ else params.push(...pathChildren.map((child) => ast.factory.createFunctionParameter(child)));
547
490
  }
548
- if (bodyType) params.push(ast.createFunctionParameter({
491
+ if (bodyType) params.push(ast.factory.createFunctionParameter({
549
492
  name: "data",
550
493
  type: bodyType,
551
494
  optional: !bodyRequired
552
495
  }));
553
- params.push(...buildGroupParam("params", node, queryParams, queryGroupType, resolver));
554
- return ast.createFunctionParameters({ params });
496
+ params.push(...buildGroupParam({
497
+ name: "params",
498
+ node,
499
+ params: queryParams,
500
+ groupType: queryGroupType,
501
+ resolver,
502
+ wrapType: (type) => type
503
+ }));
504
+ return ast.factory.createFunctionParameters({ params });
555
505
  }
556
506
  /**
557
507
  * Collect the names of the required params (no default) that drive the `enabled`
@@ -560,12 +510,11 @@ function buildQueryKeyParams(node, options) {
560
510
  */
561
511
  function getEnabledParamNames(paramsNode) {
562
512
  const required = [];
563
- for (const param of paramsNode.params) if ("kind" in param && param.kind === "ParameterGroup") {
564
- const group = param;
565
- for (const child of group.properties) if (!child.optional && child.default === void 0) required.push(child.name);
566
- } else {
567
- const fp = param;
568
- if (!fp.optional && fp.default === void 0) required.push(fp.name);
513
+ for (const param of paramsNode.params) {
514
+ const members = groupMembers(param);
515
+ if (members) {
516
+ for (const member of members) if (!member.optional) required.push(member.name);
517
+ } else if (typeof param.name === "string" && !param.optional && param.default === void 0) required.push(param.name);
569
518
  }
570
519
  return required;
571
520
  }
@@ -581,27 +530,25 @@ function markParamsOptional(paramsNode, names) {
581
530
  if (names.length === 0) return paramsNode;
582
531
  const nameSet = new Set(names);
583
532
  const params = paramsNode.params.map((param) => {
584
- if ("kind" in param && param.kind === "ParameterGroup") {
585
- const group = param;
533
+ const members = groupMembers(param);
534
+ if (members) {
535
+ const next = members.map((member) => nameSet.has(member.name) ? {
536
+ ...member,
537
+ optional: true
538
+ } : member);
586
539
  return {
587
- ...group,
588
- properties: group.properties.map((child) => nameSet.has(child.name) ? ast.createFunctionParameter({
589
- name: child.name,
590
- type: child.type,
591
- rest: child.rest,
592
- optional: true
593
- }) : child)
540
+ ...param,
541
+ type: ast.factory.createTypeLiteral({ members: next })
594
542
  };
595
543
  }
596
- const fp = param;
597
- return nameSet.has(fp.name) ? ast.createFunctionParameter({
598
- name: fp.name,
599
- type: fp.type,
600
- rest: fp.rest,
544
+ return typeof param.name === "string" && nameSet.has(param.name) ? ast.factory.createFunctionParameter({
545
+ name: param.name,
546
+ type: param.type,
547
+ rest: param.rest,
601
548
  optional: true
602
- }) : fp;
549
+ }) : param;
603
550
  });
604
- return ast.createFunctionParameters({ params });
551
+ return ast.factory.createFunctionParameters({ params });
605
552
  }
606
553
  functionPrinter({ mode: "declaration" });
607
554
  const queryKeyTransformer = ({ node, casing }) => {
@@ -620,43 +567,31 @@ const queryKeyTransformer = ({ node, casing }) => {
620
567
  };
621
568
  //#endregion
622
569
  //#region src/utils.ts
623
- function printType(typeNode) {
624
- if (!typeNode) return "unknown";
625
- if (typeNode.variant === "reference") return typeNode.name;
626
- if (typeNode.variant === "member") return `${typeNode.base}['${typeNode.key}']`;
627
- if (typeNode.variant === "struct") return `{ ${typeNode.properties.map((p) => {
628
- const typeStr = printType(p.type);
629
- const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(p.name) ? p.name : JSON.stringify(p.name);
630
- return p.optional ? `${key}?: ${typeStr}` : `${key}: ${typeStr}`;
631
- }).join("; ")} }`;
632
- return "unknown";
633
- }
570
+ /**
571
+ * Wraps each parameter type in `MaybeRefOrGetter<…>` so a vue-query signature
572
+ * accepts refs or getters. Group members are wrapped individually; `skip` opts a
573
+ * plain parameter out by name.
574
+ */
634
575
  function wrapWithMaybeRefOrGetter(paramsNode, skip) {
635
576
  const wrappedParams = paramsNode.params.map((param) => {
636
- if ("kind" in param && param.kind === "ParameterGroup") {
637
- const group = param;
638
- return {
639
- ...group,
640
- properties: group.properties.map((p) => ({
641
- ...p,
642
- type: p.type ? ast.createParamsType({
643
- variant: "reference",
644
- name: `MaybeRefOrGetter<${printType(p.type)}>`
645
- }) : p.type
646
- }))
577
+ if (typeof param.name !== "string") {
578
+ const type = param.type;
579
+ if (type && typeof type !== "string" && type.kind === "TypeLiteral") return {
580
+ ...param,
581
+ type: ast.factory.createTypeLiteral({ members: type.members.map((member) => ({
582
+ ...member,
583
+ type: `MaybeRefOrGetter<${renderType(member.type)}>`
584
+ })) })
647
585
  };
586
+ return param;
648
587
  }
649
- const fp = param;
650
- if (skip?.(fp.name)) return fp;
588
+ if (skip?.(param.name)) return param;
651
589
  return {
652
- ...fp,
653
- type: fp.type ? ast.createParamsType({
654
- variant: "reference",
655
- name: `MaybeRefOrGetter<${printType(fp.type)}>`
656
- }) : fp.type
590
+ ...param,
591
+ type: param.type ? `MaybeRefOrGetter<${renderType(param.type)}>` : param.type
657
592
  };
658
593
  });
659
- return ast.createFunctionParameters({ params: wrappedParams });
594
+ return ast.factory.createFunctionParameters({ params: wrappedParams });
660
595
  }
661
596
  //#endregion
662
597
  //#region src/components/QueryKey.tsx
@@ -781,24 +716,21 @@ function buildInfiniteQueryParamsNode(node, options) {
781
716
  const errorNames = resolveErrorNames(node, resolver);
782
717
  const TData = dataReturnType === "data" ? responseName : buildStatusUnionType(node, resolver);
783
718
  const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
784
- const optionsParam = ast.createFunctionParameter({
719
+ const optionsParam = ast.factory.createFunctionParameter({
785
720
  name: "options",
786
- type: ast.createParamsType({
787
- variant: "reference",
788
- name: `{
721
+ type: `{
789
722
  query?: Partial<UseInfiniteQueryOptions<${[
790
- TData,
791
- TError,
792
- "TQueryData",
793
- "TQueryKey",
794
- "TQueryData"
795
- ].join(", ")}>> & { client?: QueryClient },
723
+ TData,
724
+ TError,
725
+ "TQueryData",
726
+ "TQueryKey",
727
+ "TQueryData"
728
+ ].join(", ")}>> & { client?: QueryClient },
796
729
  client?: ${requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : "Partial<RequestConfig> & { client?: Client }"}
797
- }`
798
- }),
730
+ }`,
799
731
  default: "{}"
800
732
  });
801
- return wrapWithMaybeRefOrGetter(ast.createOperationParams(node, {
733
+ return wrapWithMaybeRefOrGetter(createOperationParams(node, {
802
734
  paramsType,
803
735
  pathParamsType: paramsType === "object" ? "object" : pathParamsType === "object" ? "object" : "inline",
804
736
  paramsCasing,
@@ -984,9 +916,9 @@ function addToValueCalls(callStr, enabledNames = []) {
984
916
  //#region src/components/Mutation.tsx
985
917
  const declarationPrinter$1 = functionPrinter({ mode: "declaration" });
986
918
  const callPrinter$1 = functionPrinter({ mode: "call" });
987
- const keysPrinter = functionPrinter({ mode: "keys" });
919
+ const keysPrinter = functionPrinter({ mode: "call" });
988
920
  function createMutationArgParams(node, options) {
989
- return ast.createOperationParams(node, {
921
+ return createOperationParams(node, {
990
922
  paramsType: "inline",
991
923
  pathParamsType: "inline",
992
924
  paramsCasing: options.paramsCasing,
@@ -1005,20 +937,17 @@ function buildMutationParamsNode(node, options) {
1005
937
  resolver
1006
938
  }));
1007
939
  const TRequestWrapped = wrappedParamsNode.params.length > 0 ? declarationPrinter$1.print(wrappedParamsNode) ?? "" : "";
1008
- return ast.createFunctionParameters({ params: [ast.createFunctionParameter({
940
+ return ast.factory.createFunctionParameters({ params: [ast.factory.createFunctionParameter({
1009
941
  name: "options",
1010
- type: ast.createParamsType({
1011
- variant: "reference",
1012
- name: `{
942
+ type: `{
1013
943
  mutation?: MutationObserverOptions<${[
1014
- TData,
1015
- TError,
1016
- TRequestWrapped ? `{${TRequestWrapped}}` : "undefined",
1017
- "TContext"
1018
- ].join(", ")}> & { client?: QueryClient },
944
+ TData,
945
+ TError,
946
+ TRequestWrapped ? `{${TRequestWrapped}}` : "undefined",
947
+ "TContext"
948
+ ].join(", ")}> & { client?: QueryClient },
1019
949
  client?: ${buildRequestConfigType(node, resolver)},
1020
- }`
1021
- }),
950
+ }`,
1022
951
  default: "{}"
1023
952
  })] });
1024
953
  }
@@ -1041,19 +970,16 @@ function Mutation({ name, clientName, paramsCasing, paramsType, pathParamsType,
1041
970
  TRequest ? `{${TRequest}}` : "undefined",
1042
971
  "TContext"
1043
972
  ].join(", ");
1044
- const mutationKeyParamsNode = ast.createFunctionParameters({ params: [] });
973
+ const mutationKeyParamsNode = ast.factory.createFunctionParameters({ params: [] });
1045
974
  const mutationKeyParamsCall = callPrinter$1.print(mutationKeyParamsNode) ?? "";
1046
- const clientCallParamsNode = ast.createOperationParams(node, {
975
+ const clientCallParamsNode = createOperationParams(node, {
1047
976
  paramsType,
1048
977
  pathParamsType: paramsType === "object" ? "object" : pathParamsType === "object" ? "object" : "inline",
1049
978
  paramsCasing,
1050
979
  resolver: tsResolver,
1051
- extraParams: [ast.createFunctionParameter({
980
+ extraParams: [ast.factory.createFunctionParameter({
1052
981
  name: "config",
1053
- type: ast.createParamsType({
1054
- variant: "reference",
1055
- name: buildRequestConfigType(node, tsResolver)
1056
- }),
982
+ type: buildRequestConfigType(node, tsResolver),
1057
983
  default: "{}"
1058
984
  })]
1059
985
  });
@@ -1102,24 +1028,21 @@ function buildQueryParamsNode(node, options) {
1102
1028
  const errorNames = resolveErrorNames(node, resolver);
1103
1029
  const TData = dataReturnType === "data" ? responseName : buildStatusUnionType(node, resolver);
1104
1030
  const TError = `ResponseErrorConfig<${errorNames.length > 0 ? errorNames.join(" | ") : "Error"}>`;
1105
- const optionsParam = ast.createFunctionParameter({
1031
+ const optionsParam = ast.factory.createFunctionParameter({
1106
1032
  name: "options",
1107
- type: ast.createParamsType({
1108
- variant: "reference",
1109
- name: `{
1033
+ type: `{
1110
1034
  query?: Partial<UseQueryOptions<${[
1111
- TData,
1112
- TError,
1113
- "TData",
1114
- "TQueryData",
1115
- "TQueryKey"
1116
- ].join(", ")}>> & { client?: QueryClient },
1035
+ TData,
1036
+ TError,
1037
+ "TData",
1038
+ "TQueryData",
1039
+ "TQueryKey"
1040
+ ].join(", ")}>> & { client?: QueryClient },
1117
1041
  client?: ${requestName ? `Partial<RequestConfig<${requestName}>> & { client?: Client }` : "Partial<RequestConfig> & { client?: Client }"}
1118
- }`
1119
- }),
1042
+ }`,
1120
1043
  default: "{}"
1121
1044
  });
1122
- return wrapWithMaybeRefOrGetter(ast.createOperationParams(node, {
1045
+ return wrapWithMaybeRefOrGetter(createOperationParams(node, {
1123
1046
  paramsType,
1124
1047
  pathParamsType: paramsType === "object" ? "object" : pathParamsType === "object" ? "object" : "inline",
1125
1048
  paramsCasing,
@@ -1192,4 +1115,4 @@ function Query({ name, queryKeyTypeName, queryOptionsName, queryKeyName, paramsT
1192
1115
  //#endregion
1193
1116
  export { QueryOptions as a, resolveZodSchemaNames as c, getOperationParameters as d, operationFileEntry as f, InfiniteQuery as i, MutationKey as l, camelCase as m, Mutation as n, QueryKey as o, resolveOperationTypeNames as p, InfiniteQueryOptions as r, queryKeyTransformer as s, Query as t, mutationKeyTransformer as u };
1194
1117
 
1195
- //# sourceMappingURL=components-B79Gljyl.js.map
1118
+ //# sourceMappingURL=components-CAlEf7Oh.js.map