@kubb/core 1.2.0 → 1.2.2

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/dist/index.js CHANGED
@@ -3,12 +3,14 @@ import crypto from 'node:crypto';
3
3
  import fs from 'fs-extra';
4
4
  import pathParser2 from 'node:path';
5
5
  import { camelCase, camelCaseTransformMerge } from 'change-case';
6
+ import { performance } from 'node:perf_hooks';
6
7
  import { rimraf } from 'rimraf';
7
8
  import dirTree from 'directory-tree';
8
9
  import mod from 'node:module';
9
10
  import { pathToFileURL } from 'node:url';
10
- import pc from 'picocolors';
11
+ import pc3 from 'picocolors';
11
12
  export { default as pc } from 'picocolors';
13
+ import seedrandom from 'seedrandom';
12
14
  import { createImportDeclaration, print, createExportDeclaration } from '@kubb/ts-codegen';
13
15
 
14
16
  createRequire(import.meta.url);
@@ -42,7 +44,7 @@ async function write(data, path) {
42
44
  }
43
45
 
44
46
  // src/utils/cache.ts
45
- function createPluginCache(Store) {
47
+ function createPluginCache(Store = /* @__PURE__ */ Object.create(null)) {
46
48
  return {
47
49
  set(id, value) {
48
50
  Store[id] = [0, value];
@@ -165,18 +167,18 @@ async function timeout(ms) {
165
167
  }, ms);
166
168
  });
167
169
  }
168
-
169
- // src/utils/Queue.ts
170
170
  var Queue = class {
171
171
  queue = [];
172
172
  workerCount = 0;
173
173
  maxParallel;
174
- constructor(maxParallel) {
174
+ debug = false;
175
+ constructor(maxParallel, debug = false) {
175
176
  this.maxParallel = maxParallel;
177
+ this.debug = debug;
176
178
  }
177
- run(task) {
179
+ run(task, options = { name: crypto.randomUUID(), description: "" }) {
178
180
  return new Promise((resolve, reject) => {
179
- const item = { reject, resolve, task };
181
+ const item = { reject, resolve, task, name: options.name, description: options.description || options.name };
180
182
  this.queue.push(item);
181
183
  this.work();
182
184
  });
@@ -188,8 +190,17 @@ var Queue = class {
188
190
  this.workerCount++;
189
191
  let entry;
190
192
  while (entry = this.queue.shift()) {
191
- const { reject, resolve, task } = entry;
192
- task().then((result) => resolve(result)).catch((err) => reject(err));
193
+ const { reject, resolve, task, name, description } = entry;
194
+ if (this.debug) {
195
+ performance.mark(name + "_start");
196
+ }
197
+ task().then((result) => {
198
+ resolve(result);
199
+ if (this.debug) {
200
+ performance.mark(name + "_stop");
201
+ performance.measure(description, name + "_start", name + "_stop");
202
+ }
203
+ }).catch((err) => reject(err));
193
204
  }
194
205
  this.workerCount--;
195
206
  }
@@ -483,26 +494,26 @@ var Warning = class extends Error {
483
494
  }
484
495
  };
485
496
  function createLogger(spinner) {
486
- const [log] = throttle((message) => {
497
+ const log = (message) => {
487
498
  if (message && spinner) {
488
499
  spinner.text = message;
489
500
  }
490
- }, 100);
491
- const [error] = throttle((message) => {
501
+ };
502
+ const error = (message) => {
492
503
  if (message) {
493
504
  throw new Error(message || "Something went wrong");
494
505
  }
495
- }, 100);
496
- const [warn] = throttle((message) => {
506
+ };
507
+ const warn = (message) => {
497
508
  if (message && spinner) {
498
- spinner.warn(pc.yellow(message));
509
+ spinner.warn(pc3.yellow(message));
499
510
  }
500
- }, 100);
501
- const [info] = throttle((message) => {
511
+ };
512
+ const info = (message) => {
502
513
  if (message && spinner) {
503
- spinner.text = message;
514
+ spinner.info(message);
504
515
  }
505
- }, 100);
516
+ };
506
517
  const logger = {
507
518
  log,
508
519
  error,
@@ -512,6 +523,38 @@ function createLogger(spinner) {
512
523
  };
513
524
  return logger;
514
525
  }
526
+ function canLogHierarchy(input, compareTo) {
527
+ if (input === "stacktrace") {
528
+ return canLogHierarchy("info", compareTo);
529
+ }
530
+ return input === compareTo;
531
+ }
532
+ var defaultColours = ["black", "blue", "darkBlue", "cyan", "gray", "green", "darkGreen", "magenta", "red", "darkRed", "yellow", "darkYellow"];
533
+ function randomColour(text, colours = defaultColours) {
534
+ if (!text) {
535
+ return "white";
536
+ }
537
+ const random = seedrandom(text);
538
+ const colour = colours.at(Math.floor(random() * colours.length)) || "white";
539
+ return colour;
540
+ }
541
+ function randomPicoColour(text, colors = defaultColours) {
542
+ const colours = pc3.createColors(true);
543
+ if (!text) {
544
+ return colours.white(text);
545
+ }
546
+ const colour = randomColour(text, colors);
547
+ const isDark = colour.includes("dark");
548
+ const key = colour.replace("dark", "").toLowerCase();
549
+ const formatter = colours[key];
550
+ if (isDark) {
551
+ return pc3.bold(formatter(text));
552
+ }
553
+ if (typeof formatter !== "function") {
554
+ throw new Error("Formatter for picoColor is not of type function/Formatter");
555
+ }
556
+ return formatter(text);
557
+ }
515
558
  function writeIndexes(root, options = {}) {
516
559
  const tree = TreeNode.build(root, { extensions: /\.ts/, ...options });
517
560
  if (!tree) {
@@ -567,7 +610,7 @@ function combineFiles(files) {
567
610
  acc[prevIndex] = {
568
611
  ...curr,
569
612
  source: prev.source && curr.source ? `${prev.source}
570
- ${curr.source}` : "'",
613
+ ${curr.source}` : "",
571
614
  imports: [...prev.imports || [], ...curr.imports || []],
572
615
  exports: [...prev.exports || [], ...curr.exports || []],
573
616
  env: { ...prev.env || {}, ...curr.env || {} }
@@ -688,82 +731,66 @@ var FileManager = class {
688
731
  this.queue = options.queue;
689
732
  }
690
733
  }
691
- getCache(id) {
692
- return this.cache.get(id);
693
- }
694
734
  get extensions() {
695
735
  return extensions;
696
736
  }
697
- getCacheByPath(path) {
698
- let cache;
699
- this.cache.forEach((item) => {
700
- if (item.file.path === path) {
701
- cache = item;
702
- }
703
- });
704
- return cache;
705
- }
706
737
  get files() {
707
738
  const files = [];
708
739
  this.cache.forEach((item) => {
709
- files.push(item.file);
710
- });
711
- return files;
712
- }
713
- get cachedFiles() {
714
- const files = [];
715
- this.cache.forEach((item) => {
716
- files.push(item);
740
+ files.push(...item.flat(1));
717
741
  });
718
742
  return files;
719
743
  }
720
744
  async add(file) {
721
- const cacheItem = { id: crypto.randomUUID(), file, status: "new" };
722
- this.cache.set(cacheItem.id, cacheItem);
745
+ const resolvedFile = { id: crypto.randomUUID(), ...file };
746
+ this.cache.set(resolvedFile.path, [resolvedFile]);
723
747
  if (this.queue) {
724
748
  await this.queue.run(async () => {
725
- await this.task?.(cacheItem.id, file);
749
+ await this.task?.(resolvedFile);
726
750
  });
727
751
  }
728
- return file;
752
+ return resolvedFile;
729
753
  }
730
754
  addOrAppend(file) {
731
- if (!file.path.endsWith(file.fileName)) ;
732
- const previousCache = this.getCacheByPath(file.path);
755
+ const previousCaches = this.cache.get(file.path);
756
+ const previousCache = previousCaches ? previousCaches.at(previousCaches.length - 1) : void 0;
733
757
  if (previousCache) {
734
- const sourceAlreadyExists = file.source && previousCache.file.source.includes(file.source);
758
+ const sourceAlreadyExists = file.source && previousCache.source.includes(file.source);
735
759
  if (sourceAlreadyExists) {
736
- return Promise.resolve(file);
760
+ return Promise.resolve(previousCache);
737
761
  }
738
- this.cache.delete(previousCache.id);
762
+ this.cache.delete(previousCache.path);
739
763
  return this.add({
740
764
  ...file,
741
- source: `${previousCache.file.source}
742
- ${file.source}`,
743
- imports: [...previousCache.file.imports || [], ...file.imports || []],
744
- exports: [...previousCache.file.exports || [], ...file.exports || []]
765
+ source: previousCache.source && file.source ? `${previousCache.source}
766
+ ${file.source}` : "",
767
+ imports: [...previousCache.imports || [], ...file.imports || []],
768
+ exports: [...previousCache.exports || [], ...file.exports || []],
769
+ env: { ...previousCache.env || {}, ...file.env || {} }
745
770
  });
746
771
  }
747
772
  return this.add(file);
748
773
  }
749
- setStatus(id, status) {
750
- const cacheItem = this.getCache(id);
751
- if (!cacheItem) {
752
- return;
753
- }
754
- cacheItem.status = status;
755
- this.cache.set(id, cacheItem);
774
+ append(path, file) {
775
+ const previousFiles = this.cache.get(path) || [];
776
+ this.cache.set(path, [...previousFiles, file]);
756
777
  }
757
- get(id) {
758
- const cacheItem = this.getCache(id);
759
- return cacheItem?.file;
778
+ getCacheByUUID(UUID) {
779
+ let cache;
780
+ this.cache.forEach((files) => {
781
+ cache = files.find((item) => item.id === UUID);
782
+ });
783
+ return cache;
760
784
  }
761
- remove(id) {
762
- const cacheItem = this.getCache(id);
785
+ get(path) {
786
+ return this.cache.get(path);
787
+ }
788
+ remove(path) {
789
+ const cacheItem = this.get(path);
763
790
  if (!cacheItem) {
764
791
  return;
765
792
  }
766
- this.setStatus(id, "removed");
793
+ this.cache.delete(path);
767
794
  }
768
795
  async write(...params) {
769
796
  if (this.queue) {
@@ -799,52 +826,53 @@ function createPlugin(factory) {
799
826
  var pluginName = "core";
800
827
  var definePlugin = createPlugin((options) => {
801
828
  const { fileManager, resolvePath, resolveName, load, logger } = options;
802
- const api = {
803
- get config() {
804
- return options.config;
805
- },
806
- fileManager,
807
- async addFile(...files) {
808
- const trace = getStackTrace();
809
- const plugins = options.config.plugins?.filter((plugin) => trace[1].getFileName()?.includes(plugin.name)).sort((a, b) => {
810
- if (a.name.length < b.name.length) {
811
- return 1;
812
- }
813
- if (a.name.length > b.name.length) {
814
- return -1;
815
- }
816
- return 0;
817
- });
818
- const pluginName2 = plugins?.[0]?.name;
819
- return Promise.all(
820
- files.map((file) => {
821
- const fileWithMeta = {
822
- ...file,
823
- meta: {
824
- ...file.meta || {},
825
- pluginName: pluginName2
826
- }
827
- };
828
- if (file.override) {
829
- return fileManager.add(fileWithMeta);
830
- }
831
- return fileManager.addOrAppend(fileWithMeta);
832
- })
833
- );
834
- },
835
- resolvePath,
836
- resolveName: (params) => {
837
- const name = resolveName(params);
838
- return transformReservedWord(name);
839
- },
840
- load,
841
- logger,
842
- cache: createPluginCache(/* @__PURE__ */ Object.create(null))
843
- };
844
829
  return {
845
830
  name: pluginName,
846
831
  options,
847
- api,
832
+ api() {
833
+ return {
834
+ get config() {
835
+ return options.config;
836
+ },
837
+ logger,
838
+ fileManager,
839
+ async addFile(...files) {
840
+ const trace = getStackTrace();
841
+ const plugins = options.config.plugins?.filter((plugin) => trace[1].getFileName()?.includes(plugin.name)).sort((a, b) => {
842
+ if (a.name.length < b.name.length) {
843
+ return 1;
844
+ }
845
+ if (a.name.length > b.name.length) {
846
+ return -1;
847
+ }
848
+ return 0;
849
+ });
850
+ const pluginName2 = plugins?.[0]?.name;
851
+ return Promise.all(
852
+ files.map((file) => {
853
+ const fileWithMeta = {
854
+ ...file,
855
+ meta: {
856
+ ...file.meta || {},
857
+ pluginName: pluginName2
858
+ }
859
+ };
860
+ if (file.override) {
861
+ return fileManager.add(fileWithMeta);
862
+ }
863
+ return fileManager.addOrAppend(fileWithMeta);
864
+ })
865
+ );
866
+ },
867
+ resolvePath,
868
+ resolveName: (params) => {
869
+ const name = resolveName(params);
870
+ return transformReservedWord(name);
871
+ },
872
+ load,
873
+ cache: createPluginCache()
874
+ };
875
+ },
848
876
  resolvePath(fileName) {
849
877
  const root = pathParser2.resolve(this.config.root, this.config.output.path);
850
878
  return pathParser2.resolve(root, fileName);
@@ -902,33 +930,46 @@ var hookNames = {
902
930
  buildEnd: 1
903
931
  };
904
932
  var hooks = Object.keys(hookNames);
933
+ var convertKubbUserPluginToKubbPlugin = (plugin, context) => {
934
+ if (plugin.api && typeof plugin.api === "function") {
935
+ const api = plugin.api.call(context);
936
+ return {
937
+ ...plugin,
938
+ api
939
+ };
940
+ }
941
+ return null;
942
+ };
905
943
  var PluginManager = class {
906
944
  plugins;
907
945
  fileManager;
908
946
  onExecute;
909
947
  core;
910
948
  queue;
911
- executer;
912
949
  executed = [];
913
950
  logger;
914
951
  constructor(config, options) {
915
952
  this.onExecute = options.onExecute?.bind(this);
916
953
  this.logger = options.logger;
917
- this.queue = new Queue(10);
954
+ this.queue = new Queue(100, options.debug);
918
955
  this.fileManager = new FileManager({ task: options.task, queue: this.queue });
919
- this.core = definePlugin({
956
+ const core = definePlugin({
920
957
  config,
921
958
  logger: this.logger,
922
959
  fileManager: this.fileManager,
923
960
  load: this.load,
924
961
  resolvePath: this.resolvePath,
925
- resolveName: this.resolveName,
926
- getExecuter: this.getExecuter.bind(this)
962
+ resolveName: this.resolveName
927
963
  });
928
- this.plugins = [this.core, ...config.plugins || []];
929
- }
930
- getExecuter() {
931
- return this.executer;
964
+ const convertedCore = convertKubbUserPluginToKubbPlugin(core, core.api.call(null));
965
+ this.core = convertedCore;
966
+ this.plugins = [this.core, ...config.plugins || []].reduce((prev, plugin) => {
967
+ const convertedApi = convertKubbUserPluginToKubbPlugin(plugin, convertedCore?.api);
968
+ if (convertedApi) {
969
+ return [...prev, convertedApi];
970
+ }
971
+ return [...prev, plugin];
972
+ }, []);
932
973
  }
933
974
  resolvePath = (params) => {
934
975
  if (params.pluginName) {
@@ -949,7 +990,7 @@ var PluginManager = class {
949
990
  pluginName: params.pluginName,
950
991
  hookName: "resolveName",
951
992
  parameters: [params.name]
952
- });
993
+ }) || params.name;
953
994
  }
954
995
  return this.hookFirstSync({
955
996
  hookName: "resolveName",
@@ -1133,7 +1174,7 @@ var PluginManager = class {
1133
1174
  }
1134
1175
  return pluginByPluginName;
1135
1176
  }
1136
- addExecuter(executer) {
1177
+ addExecutedToCallStack(executer) {
1137
1178
  this.onExecute?.call(this, executer, this);
1138
1179
  if (executer) {
1139
1180
  this.executed.push(executer);
@@ -1153,39 +1194,35 @@ var PluginManager = class {
1153
1194
  plugin
1154
1195
  }) {
1155
1196
  const hook = plugin[hookName];
1197
+ let output;
1156
1198
  if (!hook) {
1157
1199
  return null;
1158
1200
  }
1159
- return Promise.resolve().then(() => {
1160
- this.executer = {
1161
- strategy,
1162
- hookName,
1163
- plugin
1164
- };
1201
+ const task = Promise.resolve().then(() => {
1165
1202
  if (typeof hook === "function") {
1166
- const hookResult = hook.apply(this.core.api, parameters);
1167
- if (isPromise(hookResult)) {
1168
- return Promise.resolve(hookResult).then((result) => {
1169
- this.addExecuter({
1170
- strategy,
1171
- hookName,
1172
- plugin
1173
- });
1174
- return result;
1175
- });
1203
+ const possiblePromiseResult = hook.apply(this.core.api, parameters);
1204
+ if (isPromise(possiblePromiseResult)) {
1205
+ return Promise.resolve(possiblePromiseResult);
1176
1206
  }
1177
- return hookResult;
1207
+ return possiblePromiseResult;
1178
1208
  }
1179
- this.addExecuter({
1180
- strategy,
1181
- hookName,
1182
- plugin
1183
- });
1184
1209
  return hook;
1210
+ }).then((result) => {
1211
+ output = result;
1212
+ return result;
1185
1213
  }).catch((e) => {
1186
1214
  this.catcher(e, plugin, hookName);
1187
1215
  return null;
1216
+ }).finally(() => {
1217
+ this.addExecutedToCallStack({
1218
+ input: parameters,
1219
+ output,
1220
+ strategy,
1221
+ hookName,
1222
+ plugin
1223
+ });
1188
1224
  });
1225
+ return this.queue.run(() => task);
1189
1226
  }
1190
1227
  /**
1191
1228
  * Run a sync plugin hook and return the result.
@@ -1201,33 +1238,29 @@ var PluginManager = class {
1201
1238
  plugin
1202
1239
  }) {
1203
1240
  const hook = plugin[hookName];
1241
+ let output;
1204
1242
  if (!hook) {
1205
1243
  return null;
1206
1244
  }
1207
1245
  try {
1208
- this.executer = {
1209
- strategy,
1210
- hookName,
1211
- plugin
1212
- };
1213
1246
  if (typeof hook === "function") {
1214
1247
  const fn = hook.apply(this.core.api, parameters);
1215
- this.addExecuter({
1216
- strategy,
1217
- hookName,
1218
- plugin
1219
- });
1248
+ output = fn;
1220
1249
  return fn;
1221
1250
  }
1222
- this.addExecuter({
1223
- strategy,
1224
- hookName,
1225
- plugin
1226
- });
1251
+ output = hook;
1227
1252
  return hook;
1228
1253
  } catch (e) {
1229
1254
  this.catcher(e, plugin, hookName);
1230
1255
  return null;
1256
+ } finally {
1257
+ this.addExecutedToCallStack({
1258
+ input: parameters,
1259
+ output,
1260
+ strategy,
1261
+ hookName,
1262
+ plugin
1263
+ });
1231
1264
  }
1232
1265
  }
1233
1266
  catcher(e, plugin, hookName) {
@@ -1258,23 +1291,35 @@ function validatePlugins(plugins, dependedPluginNames) {
1258
1291
  return true;
1259
1292
  }
1260
1293
 
1294
+ // src/types.ts
1295
+ var LogLevel = {
1296
+ silent: "silent",
1297
+ info: "info",
1298
+ stacktrace: "stacktrace"
1299
+ };
1300
+
1261
1301
  // src/build.ts
1262
1302
  async function transformReducer(_previousCode, result, _plugin) {
1263
1303
  return result;
1264
1304
  }
1265
1305
  async function build(options) {
1266
- const { config, logger = createLogger() } = options;
1306
+ const { config, debug, logger = createLogger() } = options;
1267
1307
  try {
1268
1308
  if (!isURL(config.input.path)) {
1269
1309
  await read(config.input.path);
1270
1310
  }
1271
1311
  } catch (e) {
1272
- throw new Error("Cannot read file/URL defined in `input.path` or set with --input in the CLI of your Kubb config", { cause: e });
1312
+ throw new Error(
1313
+ "Cannot read file/URL defined in `input.path` or set with `kubb generate PATH` in the CLI of your Kubb config " + pc3.dim(config.input.path),
1314
+ {
1315
+ cause: e
1316
+ }
1317
+ );
1273
1318
  }
1274
1319
  if (config.output.clean) {
1275
1320
  await clean(config.output.path);
1276
1321
  }
1277
- const queueTask = async (id, file) => {
1322
+ const queueTask = async (file) => {
1278
1323
  const { path } = file;
1279
1324
  let code = getFileSource(file);
1280
1325
  const { result: loadedResult } = await pluginManager.hookFirst({
@@ -1305,13 +1350,27 @@ async function build(options) {
1305
1350
  if (!executer) {
1306
1351
  return;
1307
1352
  }
1308
- const { hookName, plugin } = executer;
1309
- if (config.logLevel === "info") {
1310
- const messsage = `\u{1FA82} Executing ${hookName || "unknown"}(${pc.yellow(plugin.name || "unknown")})`;
1311
- logger.log(messsage);
1353
+ const { hookName, plugin, output, input } = executer;
1354
+ const messsage = `${randomPicoColour(plugin.name)} Executing ${hookName}`;
1355
+ if (config.logLevel === LogLevel.info && logger?.spinner && input) {
1356
+ if (debug) {
1357
+ logger.info(messsage);
1358
+ } else {
1359
+ logger.spinner.suffixText = messsage;
1360
+ }
1361
+ }
1362
+ if (config.logLevel === LogLevel.stacktrace && logger?.spinner && input) {
1363
+ logger.info(messsage);
1364
+ const logs = [
1365
+ input && `${pc3.bgWhite(`Input`)} ${randomPicoColour(plugin.name)} ${hookName}`,
1366
+ JSON.stringify(input, void 0, 2),
1367
+ output && `${pc3.bgWhite("Output")} ${randomPicoColour(plugin.name)} ${hookName}`,
1368
+ output
1369
+ ].filter(Boolean);
1370
+ console.log(logs.join("\n"));
1312
1371
  }
1313
1372
  };
1314
- const pluginManager = new PluginManager(config, { logger, task: queueTask, onExecute });
1373
+ const pluginManager = new PluginManager(config, { debug, logger, task: queueTask, onExecute });
1315
1374
  const { plugins, fileManager } = pluginManager;
1316
1375
  await pluginManager.hookParallel({
1317
1376
  hookName: "validate",
@@ -1326,7 +1385,9 @@ async function build(options) {
1326
1385
  }
1327
1386
 
1328
1387
  // src/config.ts
1329
- var defineConfig = (options) => options;
1388
+ function defineConfig(options) {
1389
+ return options;
1390
+ }
1330
1391
 
1331
1392
  // src/generators/Generator.ts
1332
1393
  var Generator = class {
@@ -1352,6 +1413,6 @@ var SchemaGenerator = class extends Generator {
1352
1413
  // src/index.ts
1353
1414
  var src_default = build;
1354
1415
 
1355
- export { FileManager, Generator, ParallelPluginError, PluginError, PluginManager, Queue, SchemaGenerator, SummaryError, TreeNode, ValidationPluginError, Warning, build, clean, combineFiles, createJSDocBlockText, createLogger, createPlugin, createPluginCache, src_default as default, defineConfig, extensions, getEncodedText, getFileSource, getLocation, getPathMode, getRelativePath, getStackTrace, getUniqueName, hooks, importModule, isPromise, isPromiseFulfilledResult, isPromiseRejectedResult, isURL, pluginName as name, nameSorter, normalizeDirectory, objectToParameters, pluginName, read, renderTemplate, throttle, timeout, transformReservedWord, uniqueId, validatePlugins, write, writeIndexes };
1416
+ export { FileManager, Generator, LogLevel, ParallelPluginError, PluginError, PluginManager, Queue, SchemaGenerator, SummaryError, TreeNode, ValidationPluginError, Warning, build, canLogHierarchy, clean, combineFiles, createJSDocBlockText, createLogger, createPlugin, createPluginCache, src_default as default, defaultColours, defineConfig, extensions, getEncodedText, getFileSource, getLocation, getPathMode, getRelativePath, getStackTrace, getUniqueName, hooks, importModule, isPromise, isPromiseFulfilledResult, isPromiseRejectedResult, isURL, pluginName as name, nameSorter, normalizeDirectory, objectToParameters, pluginName, randomColour, randomPicoColour, read, renderTemplate, throttle, timeout, transformReservedWord, uniqueId, validatePlugins, write, writeIndexes };
1356
1417
  //# sourceMappingURL=out.js.map
1357
1418
  //# sourceMappingURL=index.js.map