apibara 2.1.0-beta.4 → 2.1.0-beta.40

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 (119) hide show
  1. package/dist/chunks/add.mjs +16 -8
  2. package/dist/chunks/add.mjs.map +1 -0
  3. package/dist/chunks/build.mjs +4 -2
  4. package/dist/chunks/build.mjs.map +1 -0
  5. package/dist/chunks/dev.mjs +55 -21
  6. package/dist/chunks/dev.mjs.map +1 -0
  7. package/dist/chunks/init.mjs +11 -7
  8. package/dist/chunks/init.mjs.map +1 -0
  9. package/dist/chunks/prepare.mjs +4 -2
  10. package/dist/chunks/prepare.mjs.map +1 -0
  11. package/dist/chunks/start.mjs +16 -4
  12. package/dist/chunks/start.mjs.map +1 -0
  13. package/dist/chunks/write-project-info.mjs +51 -0
  14. package/dist/chunks/write-project-info.mjs.map +1 -0
  15. package/dist/cli/index.mjs +3 -1
  16. package/dist/cli/index.mjs.map +1 -0
  17. package/dist/common/index.d.mts +33 -0
  18. package/dist/common/index.d.ts +33 -0
  19. package/dist/common/index.mjs +91 -0
  20. package/dist/common/index.mjs.map +1 -0
  21. package/dist/config/index.mjs +1 -0
  22. package/dist/config/index.mjs.map +1 -0
  23. package/dist/core/index.mjs +134 -69
  24. package/dist/core/index.mjs.map +1 -0
  25. package/dist/create/index.d.mts +2 -1
  26. package/dist/create/index.d.ts +2 -1
  27. package/dist/create/index.mjs +168 -139
  28. package/dist/create/index.mjs.map +1 -0
  29. package/dist/hooks/index.mjs +6 -1
  30. package/dist/hooks/index.mjs.map +1 -0
  31. package/dist/indexer/index.d.ts +1 -0
  32. package/dist/indexer/index.mjs +1 -0
  33. package/dist/indexer/plugins.d.ts +1 -0
  34. package/dist/indexer/plugins.mjs +1 -0
  35. package/dist/indexer/testing.d.ts +1 -0
  36. package/dist/indexer/testing.mjs +1 -0
  37. package/dist/indexer/vcr.d.ts +1 -0
  38. package/dist/indexer/vcr.mjs +1 -0
  39. package/dist/rolldown/index.d.mts +7 -0
  40. package/dist/rolldown/index.d.ts +7 -0
  41. package/dist/rolldown/index.mjs +140 -0
  42. package/dist/rolldown/index.mjs.map +1 -0
  43. package/dist/runtime/dev.mjs +19 -9
  44. package/dist/runtime/internal/app.d.ts +14 -1
  45. package/dist/runtime/internal/app.mjs +26 -21
  46. package/dist/runtime/project-info.d.ts +3 -0
  47. package/dist/runtime/project-info.mjs +67 -0
  48. package/dist/runtime/start.mjs +59 -7
  49. package/dist/shared/apibara.730bb1e4.mjs +18 -0
  50. package/dist/shared/apibara.730bb1e4.mjs.map +1 -0
  51. package/dist/types/index.d.mts +24 -20
  52. package/dist/types/index.d.ts +24 -20
  53. package/dist/types/index.mjs +1 -0
  54. package/dist/types/index.mjs.map +1 -0
  55. package/package.json +33 -16
  56. package/src/cli/commands/add.ts +16 -7
  57. package/src/cli/commands/build.ts +5 -2
  58. package/src/cli/commands/dev.ts +64 -20
  59. package/src/cli/commands/init.ts +12 -7
  60. package/src/cli/commands/prepare.ts +4 -3
  61. package/src/cli/commands/start.ts +18 -3
  62. package/src/cli/commands/write-project-info.ts +56 -0
  63. package/src/cli/index.ts +2 -0
  64. package/src/common/cli.ts +40 -0
  65. package/src/common/constants.ts +6 -0
  66. package/src/common/helper.ts +86 -0
  67. package/src/common/index.ts +3 -0
  68. package/src/core/apibara.ts +7 -2
  69. package/src/core/build/build.ts +13 -5
  70. package/src/core/build/dev.ts +46 -23
  71. package/src/core/build/error.ts +9 -14
  72. package/src/core/build/prepare.ts +5 -3
  73. package/src/core/build/prod.ts +25 -16
  74. package/src/core/build/types.ts +11 -1
  75. package/src/core/config/defaults.ts +3 -0
  76. package/src/core/config/loader.ts +15 -7
  77. package/src/core/config/resolvers/runtime.resolver.ts +44 -0
  78. package/src/core/config/update.ts +6 -2
  79. package/src/core/scan.ts +1 -1
  80. package/src/create/add.ts +14 -20
  81. package/src/create/constants.ts +5 -7
  82. package/src/create/init.ts +8 -5
  83. package/src/create/templates.ts +144 -116
  84. package/src/create/types.ts +3 -0
  85. package/src/create/utils.ts +20 -7
  86. package/src/hooks/useRuntimeConfig.ts +4 -1
  87. package/src/indexer/index.ts +1 -0
  88. package/src/indexer/plugins.ts +1 -0
  89. package/src/indexer/testing.ts +1 -0
  90. package/src/indexer/vcr.ts +1 -0
  91. package/src/rolldown/config.ts +85 -0
  92. package/src/rolldown/index.ts +2 -0
  93. package/src/{rollup → rolldown}/plugins/indexers.ts +3 -3
  94. package/src/rolldown/plugins/instrumentation.ts +68 -0
  95. package/src/rolldown/plugins/static-config.ts +21 -0
  96. package/src/runtime/dev.ts +21 -8
  97. package/src/runtime/internal/app.ts +42 -29
  98. package/src/runtime/project-info.ts +90 -0
  99. package/src/runtime/start.ts +68 -6
  100. package/src/types/config.ts +27 -13
  101. package/src/types/hooks.ts +8 -5
  102. package/src/types/index.ts +1 -1
  103. package/src/types/rolldown.ts +5 -0
  104. package/src/types/virtual/indexers.d.ts +4 -1
  105. package/src/types/virtual/instrumentation.d.ts +4 -0
  106. package/src/types/virtual/static-config.d.ts +4 -0
  107. package/dist/rollup/index.d.mts +0 -6
  108. package/dist/rollup/index.d.ts +0 -6
  109. package/dist/rollup/index.mjs +0 -150
  110. package/dist/shared/apibara.1b515d04.mjs +0 -8
  111. package/src/cli/common.ts +0 -8
  112. package/src/core/config/resolvers/preset.resolver.ts +0 -9
  113. package/src/core/config/resolvers/runtime-config.resolver.ts +0 -6
  114. package/src/rollup/config.ts +0 -87
  115. package/src/rollup/index.ts +0 -2
  116. package/src/rollup/plugins/config.ts +0 -12
  117. package/src/rollup/plugins/esm-shim.ts +0 -69
  118. package/src/types/rollup.ts +0 -8
  119. package/src/types/virtual/config.d.ts +0 -3
@@ -1,24 +1,11 @@
1
1
  import path, { basename } from 'node:path';
2
2
  import consola$1, { consola } from 'consola';
3
3
  import prompts from 'prompts';
4
- import colors from 'picocolors';
4
+ import { a as blue, y as yellow, c as green, r as red, d as cyan, m as magenta, e as reset } from '../shared/apibara.730bb1e4.mjs';
5
5
  import fs from 'node:fs';
6
6
  import { Project, SyntaxKind } from 'ts-morph';
7
7
  import * as prettier from 'prettier';
8
-
9
- const {
10
- blue,
11
- blueBright,
12
- cyan,
13
- gray,
14
- green,
15
- greenBright,
16
- magenta,
17
- red,
18
- redBright,
19
- reset,
20
- yellow
21
- } = colors;
8
+ import 'picocolors';
22
9
 
23
10
  const chains = [
24
11
  {
@@ -58,7 +45,6 @@ const storages = [
58
45
  const packageVersions = {
59
46
  // Required Dependencies
60
47
  apibara: "next",
61
- "@apibara/indexer": "next",
62
48
  "@apibara/protocol": "next",
63
49
  // Chain Dependencies
64
50
  "@apibara/evm": "next",
@@ -70,21 +56,20 @@ const packageVersions = {
70
56
  "@apibara/plugin-sqlite": "next",
71
57
  // Postgres Dependencies
72
58
  "@electric-sql/pglite": "^0.2.17",
73
- "drizzle-orm": "^0.37.0",
59
+ "drizzle-orm": "^0.40.1",
74
60
  pg: "^8.13.1",
75
61
  "@types/pg": "^8.11.10",
76
62
  "drizzle-kit": "^0.29.0",
77
63
  // Typescript Dependencies
78
64
  typescript: "^5.6.2",
79
- "@rollup/plugin-typescript": "^11.1.6",
80
65
  "@types/node": "^20.5.2"
81
66
  };
82
67
  const dnaUrls = {
83
- ethereum: "https://ethereum.preview.apibara.org",
84
- ethereumSepolia: "https://ethereum-sepolia.preview.apibara.org",
68
+ ethereum: "https://mainnet.ethereum.a5a.ch",
69
+ ethereumSepolia: "https://sepolia.ethereum.a5a.ch",
85
70
  beaconchain: "https://beaconchain.preview.apibara.org",
86
- starknet: "https://starknet.preview.apibara.org",
87
- starknetSepolia: "https://starknet-sepolia.preview.apibara.org"
71
+ starknet: "https://mainnet.starknet.a5a.ch",
72
+ starknetSepolia: "https://sepolia.starknet.a5a.ch"
88
73
  };
89
74
 
90
75
  function isEmpty(path2) {
@@ -106,7 +91,7 @@ function validateLanguage(language, throwError = false) {
106
91
  if (!language) {
107
92
  return false;
108
93
  }
109
- if (language === "typescript" || language === "ts" || language === "javascript" || language === "js") {
94
+ if (language === "typescript" || language === "ts" || language === "javascript" || language === "js" || language === "mjs") {
110
95
  return true;
111
96
  }
112
97
  if (throwError) {
@@ -120,7 +105,7 @@ function getLanguageFromAlias(alias) {
120
105
  if (alias === "ts" || alias === "typescript") {
121
106
  return "typescript";
122
107
  }
123
- if (alias === "js" || alias === "javascript") {
108
+ if (alias === "js" || alias === "javascript" || alias === "mjs") {
124
109
  return "javascript";
125
110
  }
126
111
  throw new Error(
@@ -240,16 +225,21 @@ function validateDnaUrl(dnaUrl, throwError = false) {
240
225
  function hasApibaraConfig(cwd) {
241
226
  const configPathJS = path.join(cwd, "apibara.config.js");
242
227
  const configPathTS = path.join(cwd, "apibara.config.ts");
243
- return fs.existsSync(configPathJS) || fs.existsSync(configPathTS);
228
+ const configPathMJS = path.join(cwd, "apibara.config.mjs");
229
+ return fs.existsSync(configPathJS) || fs.existsSync(configPathTS) || fs.existsSync(configPathMJS);
244
230
  }
245
231
  function getApibaraConfigLanguage(cwd) {
246
232
  const configPathJS = path.join(cwd, "apibara.config.js");
247
233
  const configPathTS = path.join(cwd, "apibara.config.ts");
234
+ const configPathMJS = path.join(cwd, "apibara.config.mjs");
235
+ if (fs.existsSync(configPathMJS)) {
236
+ return { language: "javascript", extension: "mjs" };
237
+ }
248
238
  if (fs.existsSync(configPathJS)) {
249
- return "javascript";
239
+ return { language: "javascript", extension: "js" };
250
240
  }
251
241
  if (fs.existsSync(configPathTS)) {
252
- return "typescript";
242
+ return { language: "typescript", extension: "ts" };
253
243
  }
254
244
  throw new Error(red("\u2716") + " No apibara.config found");
255
245
  }
@@ -386,20 +376,18 @@ function generatePackageJson(isTypeScript) {
386
376
  private: true,
387
377
  type: "module",
388
378
  scripts: {
389
- prepare: "apibara prepare",
379
+ ...isTypeScript && { prepare: "apibara prepare" },
390
380
  dev: "apibara dev",
391
381
  start: "apibara start",
392
382
  build: "apibara build",
393
383
  ...isTypeScript && { typecheck: "tsc --noEmit" }
394
384
  },
395
385
  dependencies: {
396
- "@apibara/indexer": packageVersions["@apibara/indexer"],
397
386
  "@apibara/protocol": packageVersions["@apibara/protocol"],
398
387
  apibara: packageVersions.apibara
399
388
  },
400
389
  devDependencies: {
401
390
  ...isTypeScript && {
402
- "@rollup/plugin-typescript": packageVersions["@rollup/plugin-typescript"],
403
391
  "@types/node": packageVersions["@types/node"],
404
392
  typescript: packageVersions.typescript
405
393
  }
@@ -427,13 +415,10 @@ function generateTsConfig() {
427
415
  };
428
416
  }
429
417
  function generateApibaraConfig(isTypeScript) {
430
- return `${isTypeScript ? 'import typescript from "@rollup/plugin-typescript";\nimport type { Plugin } from "apibara/rollup";\n' : ""}import { defineConfig } from "apibara/config";
418
+ return `import { defineConfig } from "apibara/config";
431
419
 
432
420
  export default defineConfig({
433
- runtimeConfig: {},${isTypeScript ? `
434
- rollupConfig: {
435
- plugins: [typescript()${isTypeScript ? " as Plugin" : ""}],
436
- },` : ""}
421
+ runtimeConfig: {},
437
422
  });
438
423
  `;
439
424
  }
@@ -443,27 +428,29 @@ function generateIndexer({
443
428
  chain,
444
429
  language
445
430
  }) {
446
- return `import { defineIndexer } from "@apibara/indexer";
447
- import { useLogger } from "@apibara/indexer/plugins";
431
+ return `import { defineIndexer } from "apibara/indexer";
432
+ import { useLogger } from "apibara/plugins";
448
433
  ${storage === "postgres" ? `import { drizzleStorage } from "@apibara/plugin-drizzle";` : ""}
434
+ ${storage === "postgres" ? `import { drizzle } from "@apibara/plugin-drizzle";` : ""}
449
435
  ${chain === "ethereum" ? `import { EvmStream } from "@apibara/evm";` : chain === "beaconchain" ? `import { BeaconChainStream } from "@apibara/beaconchain";` : chain === "starknet" ? `import { StarknetStream } from "@apibara/starknet";` : ""}
450
436
  ${language === "typescript" ? `import type { ApibaraRuntimeConfig } from "apibara/types";` : ""}
451
- ${storage === "postgres" ? `import { getDrizzlePgDatabase } from "../lib/db";` : ""}
437
+ ${storage === "postgres" ? `import * as schema from "../lib/schema";` : ""}
452
438
 
453
439
 
454
440
  export default function (runtimeConfig${language === "typescript" ? ": ApibaraRuntimeConfig" : ""}) {
455
- const indexerId = "${indexerId}";
456
- const { startingBlock, streamUrl${storage === "postgres" ? ", postgresConnectionString" : ""} } = runtimeConfig[indexerId];
457
- ${storage === "postgres" ? "const { db } = getDrizzlePgDatabase(postgresConnectionString);" : ""}
441
+ const { startingBlock, streamUrl } = runtimeConfig["${indexerId}"];
442
+ ${storage === "postgres" ? `const db = drizzle({
443
+ schema,
444
+ });` : ""}
458
445
 
459
446
  return defineIndexer(${chain === "ethereum" ? "EvmStream" : chain === "beaconchain" ? "BeaconChainStream" : chain === "starknet" ? "StarknetStream" : ""})({
460
447
  streamUrl,
461
448
  finality: "accepted",
462
449
  startingBlock: BigInt(startingBlock),
463
450
  filter: {
464
- header: "always",
451
+ ${chain === "ethereum" ? "logs: []," : chain === "starknet" ? "events: []," : ""}
465
452
  },
466
- plugins: [${storage === "postgres" ? "drizzleStorage({ db, persistState: true })" : ""}],
453
+ plugins: [${storage === "postgres" ? "drizzleStorage({ db, migrate: { migrationsFolder: './drizzle' } })" : ""}],
467
454
  async transform({ endCursor, finality }) {
468
455
  const logger = useLogger();
469
456
 
@@ -475,14 +462,12 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
475
462
  );
476
463
 
477
464
  ${storage === "postgres" ? `// Example snippet to insert data into db using drizzle with postgres
478
- // const { db } = useDrizzleStorage();
479
- // const { logs } = block;
480
- // for (const log of logs) {
481
- // await db.insert(exampleTable).values({
482
- // number: Number(endCursor?.orderKey),
483
- // hash: log.transactionHash,
484
- // });
485
- // }` : ""}
465
+ // const { db: database } = useDrizzleStorage();
466
+
467
+ // await database.insert(schema.cursorTable).values({
468
+ // endCursor: Number(endCursor?.orderKey),
469
+ // uniqueKey: \`\${endCursor?.uniqueKey}\`,
470
+ // });` : ""}
486
471
  },
487
472
  });
488
473
  }
@@ -492,7 +477,7 @@ async function createIndexerFile(options) {
492
477
  const indexerFilePath = path.join(
493
478
  options.cwd,
494
479
  "indexers",
495
- `${options.indexerFileId}.indexer.${options.language === "typescript" ? "ts" : "js"}`
480
+ `${options.indexerFileId}.indexer.${options.extension}`
496
481
  );
497
482
  const { exists, overwrite } = await checkFileExists(indexerFilePath, {
498
483
  askPrompt: true
@@ -541,16 +526,14 @@ async function updateApibaraConfigFile({
541
526
  storage,
542
527
  language,
543
528
  network,
544
- dnaUrl
529
+ dnaUrl,
530
+ extension
545
531
  }) {
546
- const pathToConfig = path.join(
547
- cwd,
548
- `apibara.config.${language === "typescript" ? "ts" : "js"}`
549
- );
532
+ const pathToConfig = path.join(cwd, `apibara.config.${extension}`);
550
533
  const runtimeConfigString = `{
551
534
  startingBlock: 0,
552
- streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"${storage === "postgres" ? `,
553
- postgresConnectionString: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}"` : ""}}`;
535
+ streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
536
+ }`;
554
537
  const project = new Project();
555
538
  const sourceFile = project.addSourceFileAtPath(pathToConfig);
556
539
  const defineConfigCall = sourceFile.getFirstDescendantByKind(
@@ -581,10 +564,15 @@ async function updateApibaraConfigFile({
581
564
  await formatFile(pathToConfig);
582
565
  }
583
566
  async function createDrizzleStorageFiles(options) {
584
- const { cwd, language, storage } = options;
567
+ const {
568
+ cwd,
569
+ language,
570
+ storage,
571
+ indexerId,
572
+ extension: fileExtension
573
+ } = options;
585
574
  if (storage !== "postgres")
586
575
  return;
587
- const fileExtension = language === "typescript" ? "ts" : "js";
588
576
  const drizzleConfigFileName = `drizzle.config.${fileExtension}`;
589
577
  const drizzleConfigPath = path.join(cwd, drizzleConfigFileName);
590
578
  const { exists, overwrite } = await checkFileExists(drizzleConfigPath, {
@@ -595,11 +583,11 @@ async function createDrizzleStorageFiles(options) {
595
583
  const drizzleConfigContent = `${language === "typescript" ? 'import type { Config } from "drizzle-kit";' : ""}
596
584
 
597
585
  export default {
598
- schema: "./lib/schema.ts",
586
+ schema: "./lib/schema.${fileExtension}",
599
587
  out: "./drizzle",
600
588
  dialect: "postgresql",
601
589
  dbCredentials: {
602
- url: process.env["POSTGRES_CONNECTION_STRING"] ?? "",
590
+ url: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}",
603
591
  },
604
592
  }${language === "typescript" ? " satisfies Config" : ""};`;
605
593
  fs.writeFileSync(drizzleConfigPath, drizzleConfigContent);
@@ -614,14 +602,14 @@ export default {
614
602
  fileName: `lib/${schemaFileName}`
615
603
  });
616
604
  if (!schemaExists || schemaOverwrite) {
617
- const schemaContent = `// --- Add your pg table schemas here ----
605
+ const schemaContent = `// --- Add your pg table schemas here ----
618
606
 
619
607
  // import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
620
608
 
621
- // export const exampleTable = pgTable("example_table", {
609
+ // export const cursorTable = pgTable("cursor_table", {
622
610
  // id: uuid("id").primaryKey().defaultRandom(),
623
- // number: bigint("number", { mode: "number" }),
624
- // hash: text("hash"),
611
+ // endCursor: bigint("end_cursor", { mode: "number" }),
612
+ // uniqueKey: text("unique_key"),
625
613
  // });
626
614
 
627
615
  export {};
@@ -629,49 +617,7 @@ export {};
629
617
  fs.mkdirSync(path.dirname(schemaPath), { recursive: true });
630
618
  fs.writeFileSync(schemaPath, schemaContent);
631
619
  await formatFile(schemaPath);
632
- consola.success(`Created ${cyan("lib/schema.ts")}`);
633
- }
634
- const dbFileName = `db.${fileExtension}`;
635
- const dbPath = path.join(cwd, "lib", dbFileName);
636
- const { exists: dbExists, overwrite: dbOverwrite } = await checkFileExists(
637
- dbPath,
638
- {
639
- askPrompt: true,
640
- fileName: `lib/${dbFileName}`,
641
- allowIgnore: true
642
- }
643
- );
644
- if (!dbExists || dbOverwrite) {
645
- const dbContent = `import * as schema from "./schema";
646
- import { drizzle as nodePgDrizzle } from "drizzle-orm/node-postgres";
647
- import { drizzle as pgLiteDrizzle } from "drizzle-orm/pglite";
648
- import pg from "pg";
649
-
650
-
651
- export function getDrizzlePgDatabase(connectionString${language === "typescript" ? ": string" : ""}) {
652
- // Create pglite instance
653
- if (connectionString.includes("memory")) {
654
- return {
655
- db: pgLiteDrizzle({
656
- schema,
657
- connection: {
658
- dataDir: connectionString,
659
- },
660
- }),
661
- };
662
- }
663
-
664
- // Create node-postgres instance
665
- const pool = new pg.Pool({
666
- connectionString,
667
- });
668
-
669
- return { db: nodePgDrizzle(pool, { schema }) };
670
- }`;
671
- fs.mkdirSync(path.dirname(dbPath), { recursive: true });
672
- fs.writeFileSync(dbPath, dbContent);
673
- await formatFile(dbPath);
674
- consola.success(`Created ${cyan(`lib/${dbFileName}`)}`);
620
+ consola.success(`Created ${cyan(`lib/${schemaFileName}`)}`);
675
621
  }
676
622
  console.log("\n");
677
623
  if (!schemaExists || schemaOverwrite) {
@@ -683,20 +629,20 @@ export function getDrizzlePgDatabase(connectionString${language === "typescript"
683
629
 
684
630
  ${yellow(`
685
631
  \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
686
- \u2502 lib/schema.ts \u2502
632
+ \u2502 lib/schema \u2502
687
633
  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
688
634
 
689
635
  import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
690
636
 
691
- export const exampleTable = pgTable("example_table", {
637
+ export const cursorTable = pgTable("cursor_table", {
692
638
  id: uuid("id").primaryKey().defaultRandom(),
693
- number: bigint("number", { mode: "number" }),
694
- hash: text("hash"),
639
+ endCursor: bigint("end_cursor", { mode: "number" }),
640
+ uniqueKey: text("unique_key"),
695
641
  });`)}`);
696
642
  console.log("\n");
697
643
  }
698
644
  consola.info(
699
- `Run ${green(`${options.packageManager} run drizzle:generate`)} & ${green(`${options.packageManager} run drizzle:migrate`)} to generate and apply migrations.`
645
+ `Run ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:generate`)} & ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:migrate`)} to generate and apply migrations.`
700
646
  );
701
647
  }
702
648
  async function createStorageRelatedFiles(options) {
@@ -705,6 +651,90 @@ async function createStorageRelatedFiles(options) {
705
651
  await createDrizzleStorageFiles(options);
706
652
  }
707
653
  }
654
+ const gitIgnoreItems = [
655
+ {
656
+ isRecommended: false,
657
+ value: "node_modules"
658
+ },
659
+ {
660
+ isRecommended: false,
661
+ value: "dist"
662
+ },
663
+ {
664
+ isRecommended: true,
665
+ description: "build and dev files of apibara",
666
+ value: ".apibara"
667
+ },
668
+ {
669
+ isRecommended: false,
670
+ value: ".env"
671
+ },
672
+ {
673
+ isRecommended: false,
674
+ description: "for mac users",
675
+ value: ".DS_Store"
676
+ }
677
+ ];
678
+ async function createGitIgnoreFile(cwd) {
679
+ const gitIgnorePath = path.join(cwd, ".gitignore");
680
+ if (fs.existsSync(gitIgnorePath)) {
681
+ const result = await prompts([
682
+ {
683
+ type: "select",
684
+ name: "overwrite",
685
+ message: `${cyan(".gitignore")} already exists. Please choose how to proceed:`,
686
+ initial: 0,
687
+ choices: [
688
+ {
689
+ title: "Choose items to append in your .gitignore",
690
+ value: "append"
691
+ },
692
+ {
693
+ title: "Keep original",
694
+ value: "ignore"
695
+ },
696
+ {
697
+ title: "Overwrite",
698
+ value: "overwrite"
699
+ }
700
+ ]
701
+ },
702
+ {
703
+ type: (overwrite2) => overwrite2 === "append" ? "multiselect" : null,
704
+ name: "ignoreItems",
705
+ message: "Choose items to append in your .gitignore",
706
+ choices: gitIgnoreItems.map((item) => ({
707
+ title: `${yellow(item.value)}${item.description ? ` - ${item.description}` : ""}${item.isRecommended ? ` ${green("(recommended)")}` : ""}`,
708
+ value: item.value
709
+ }))
710
+ }
711
+ ]);
712
+ const { overwrite, ignoreItems } = result;
713
+ if (overwrite === "append" && ignoreItems.length > 0) {
714
+ const gitIgnoreContent = fs.readFileSync(gitIgnorePath, "utf8");
715
+ fs.writeFileSync(
716
+ gitIgnorePath,
717
+ `${gitIgnoreContent}
718
+ ${result.ignoreItems.join("\n")}`
719
+ );
720
+ consola.success(`Updated ${cyan(".gitignore")}`);
721
+ return;
722
+ }
723
+ if (overwrite === "overwrite") {
724
+ fs.writeFileSync(
725
+ gitIgnorePath,
726
+ gitIgnoreItems.map((item) => item.value).join("\n")
727
+ );
728
+ consola.success(`Updated ${cyan(".gitignore")}`);
729
+ return;
730
+ }
731
+ }
732
+ fs.writeFileSync(
733
+ gitIgnorePath,
734
+ gitIgnoreItems.map((item) => item.value).join("\n")
735
+ );
736
+ consola.success(`Created ${cyan(".gitignore")}`);
737
+ }
708
738
 
709
739
  async function initializeProject({
710
740
  argTargetDir,
@@ -789,35 +819,36 @@ async function initializeProject({
789
819
  JSON.stringify(packageJson, null, 2) + "\n"
790
820
  );
791
821
  await formatFile(packageJsonPath);
792
- consola$1.success("Created ", cyan("package.json"));
822
+ consola$1.success("Created", cyan("package.json"));
793
823
  if (isTs) {
794
824
  const tsConfigPath = path.join(root, "tsconfig.json");
795
825
  const tsConfig = generateTsConfig();
796
826
  fs.writeFileSync(tsConfigPath, JSON.stringify(tsConfig, null, 2) + "\n");
797
827
  await formatFile(tsConfigPath);
798
- consola$1.success("Created ", cyan("tsconfig.json"));
828
+ consola$1.success("Created", cyan("tsconfig.json"));
799
829
  }
800
830
  const apibaraConfigPath = path.join(root, `apibara.config.${configExt}`);
801
- const apibaraConfig = generateApibaraConfig(isTs);
831
+ const apibaraConfig = generateApibaraConfig();
802
832
  fs.writeFileSync(apibaraConfigPath, apibaraConfig);
803
833
  await formatFile(apibaraConfigPath);
804
- consola$1.success("Created ", cyan(`apibara.config.${configExt}`));
834
+ consola$1.success("Created", cyan(`apibara.config.${configExt}`));
805
835
  const indexersDir = path.join(root, "indexers");
806
836
  if (!fs.existsSync(indexersDir)) {
807
837
  fs.mkdirSync(indexersDir, { recursive: true });
808
838
  consola$1.success(`Created ${cyan("indexers")} directory`);
809
839
  }
840
+ await createGitIgnoreFile(root);
810
841
  console.log("\n");
811
842
  consola$1.ready(green("Project initialized successfully"));
812
843
  console.log();
813
844
  if (!argNoCreateIndexer) {
814
845
  consola$1.info("Let's create an indexer\n");
815
- await addIndexer({});
846
+ await addIndexer({ argRootDir: argTargetDir });
816
847
  } else {
817
848
  const pkgManager = getPackageManager();
818
849
  consola$1.info(
819
850
  "Run ",
820
- green(`${pkgManager.name} run install`),
851
+ green(`${pkgManager.name} install`),
821
852
  " to install all dependencies"
822
853
  );
823
854
  }
@@ -828,9 +859,11 @@ async function addIndexer({
828
859
  argChain,
829
860
  argNetwork,
830
861
  argStorage,
831
- argDnaUrl
862
+ argDnaUrl,
863
+ argRootDir
832
864
  }) {
833
- const configExists = hasApibaraConfig(process.cwd());
865
+ const cwd = path.join(process.cwd(), argRootDir ?? ".");
866
+ const configExists = hasApibaraConfig(cwd);
834
867
  if (!configExists) {
835
868
  consola$1.error("No apibara.config found in the current directory.");
836
869
  const prompt_initialize = await prompts({
@@ -854,7 +887,7 @@ async function addIndexer({
854
887
  );
855
888
  }
856
889
  }
857
- const language = getApibaraConfigLanguage(process.cwd());
890
+ const { language, extension } = getApibaraConfigLanguage(cwd);
858
891
  validateIndexerId(argIndexerId, true);
859
892
  validateChain(argChain, true);
860
893
  validateNetwork(argChain, argNetwork, true);
@@ -868,13 +901,9 @@ async function addIndexer({
868
901
  message: reset("Indexer ID:"),
869
902
  initial: argIndexerId ?? "my-indexer",
870
903
  validate: (id) => validateIndexerId(id) ? checkFileExists(
871
- path.join(
872
- process.cwd(),
873
- "indexers",
874
- `${id}.indexer.${language === "typescript" ? "ts" : "js"}`
875
- )
904
+ path.join(cwd, "indexers", `${id}.indexer.${extension}`)
876
905
  ).then(
877
- ({ exists }) => exists ? `Indexer ${cyan(`${id}.indexer.${language === "typescript" ? "ts" : "js"}`)} already exists` : true
906
+ ({ exists }) => exists ? `Indexer ${cyan(`${id}.indexer.${extension}`)} already exists` : true
878
907
  ) : "Invalid indexer ID, it cannot be empty and must be in kebab-case format"
879
908
  },
880
909
  {
@@ -951,7 +980,7 @@ async function addIndexer({
951
980
  const indexerFileId = argIndexerId ?? prompt_indexerId;
952
981
  const pkgManager = getPackageManager();
953
982
  const options = {
954
- cwd: process.cwd(),
983
+ cwd,
955
984
  indexerFileId,
956
985
  indexerId: convertKebabToCamelCase(indexerFileId),
957
986
  chain: argChain ?? prompt_chain?.name,
@@ -959,23 +988,23 @@ async function addIndexer({
959
988
  storage: argStorage ?? prompt_storage?.name,
960
989
  dnaUrl: argDnaUrl ?? prompt_dnaUrl,
961
990
  language,
962
- packageManager: pkgManager.name
991
+ packageManager: pkgManager.name,
992
+ extension
963
993
  };
964
994
  await updateApibaraConfigFile(options);
965
- consola$1.success(
966
- `Updated ${cyan("apibara.config." + (language === "typescript" ? "ts" : "js"))}`
967
- );
995
+ consola$1.success(`Updated ${cyan(`apibara.config.${extension}`)}`);
968
996
  await updatePackageJson(options);
969
997
  consola$1.success(`Updated ${cyan("package.json")}`);
970
998
  await createIndexerFile(options);
971
- consola$1.success(
972
- `Created ${cyan(`${indexerFileId}.indexer.${language === "typescript" ? "ts" : "js"}`)}`
973
- );
999
+ consola$1.success(`Created ${cyan(`${indexerFileId}.indexer.${extension}`)}`);
974
1000
  await createStorageRelatedFiles(options);
975
1001
  console.log();
1002
+ const baseCommand = `${options.packageManager} install`;
1003
+ const tsCommand = `${baseCommand} && ${options.packageManager} run prepare`;
976
1004
  consola$1.info(
977
- `Before running the indexer, run ${cyan(`${options.packageManager} run install`)}${language === "typescript" ? " & " + cyan(`${options.packageManager} run prepare`) : ""}`
1005
+ `Before running the indexer, run ${cyan(language === "typescript" ? tsCommand : baseCommand)}`
978
1006
  );
979
1007
  }
980
1008
 
981
1009
  export { addIndexer, initializeProject };
1010
+ //# sourceMappingURL=index.mjs.map