apibara 2.1.0-beta.3 → 2.1.0-beta.30
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/chunks/add.mjs +16 -8
- package/dist/chunks/build.mjs +4 -2
- package/dist/chunks/dev.mjs +44 -14
- package/dist/chunks/init.mjs +11 -7
- package/dist/chunks/prepare.mjs +4 -2
- package/dist/chunks/start.mjs +14 -4
- package/dist/chunks/write-project-info.mjs +50 -0
- package/dist/cli/index.mjs +2 -1
- package/dist/core/index.mjs +98 -68
- package/dist/create/index.d.mts +2 -1
- package/dist/create/index.d.ts +2 -1
- package/dist/create/index.mjs +142 -112
- package/dist/hooks/index.mjs +1 -1
- package/dist/rolldown/index.d.mts +7 -0
- package/dist/rolldown/index.d.ts +7 -0
- package/dist/rolldown/index.mjs +159 -0
- package/dist/runtime/dev.mjs +14 -4
- package/dist/runtime/internal/app.d.ts +6 -1
- package/dist/runtime/internal/app.mjs +50 -19
- package/dist/runtime/internal/helper.d.ts +12 -0
- package/dist/runtime/internal/helper.mjs +33 -0
- package/dist/runtime/project-info.d.ts +3 -0
- package/dist/runtime/project-info.mjs +53 -0
- package/dist/runtime/start.mjs +18 -4
- package/dist/shared/apibara.63c9a277.mjs +29 -0
- package/dist/shared/apibara.730bb1e4.mjs +17 -0
- package/dist/types/index.d.mts +23 -19
- package/dist/types/index.d.ts +23 -19
- package/package.json +13 -16
- package/src/cli/commands/add.ts +16 -7
- package/src/cli/commands/build.ts +5 -2
- package/src/cli/commands/dev.ts +56 -13
- package/src/cli/commands/init.ts +12 -7
- package/src/cli/commands/prepare.ts +4 -2
- package/src/cli/commands/start.ts +16 -3
- package/src/cli/commands/write-project-info.ts +56 -0
- package/src/cli/common.ts +33 -1
- package/src/cli/index.ts +2 -0
- package/src/core/apibara.ts +5 -0
- package/src/core/build/build.ts +13 -5
- package/src/core/build/dev.ts +44 -23
- package/src/core/build/error.ts +9 -14
- package/src/core/build/prepare.ts +5 -3
- package/src/core/build/prod.ts +25 -16
- package/src/core/build/types.ts +11 -1
- package/src/core/config/defaults.ts +3 -0
- package/src/core/config/loader.ts +13 -7
- package/src/core/config/resolvers/preset.resolver.ts +3 -0
- package/src/core/config/update.ts +1 -1
- package/src/create/add.ts +10 -9
- package/src/create/constants.ts +10 -11
- package/src/create/init.ts +8 -5
- package/src/create/templates.ts +130 -102
- package/src/hooks/useRuntimeConfig.ts +1 -1
- package/src/rolldown/config.ts +111 -0
- package/src/rolldown/index.ts +2 -0
- package/src/rolldown/plugins/config.ts +17 -0
- package/src/{rollup → rolldown}/plugins/indexers.ts +3 -3
- package/src/rolldown/plugins/instrumentation.ts +68 -0
- package/src/runtime/dev.ts +16 -4
- package/src/runtime/internal/app.ts +66 -25
- package/src/runtime/internal/helper.ts +55 -0
- package/src/runtime/project-info.ts +72 -0
- package/src/runtime/start.ts +21 -4
- package/src/types/config.ts +23 -12
- package/src/types/hooks.ts +8 -5
- package/src/types/index.ts +1 -1
- package/src/types/rolldown.ts +5 -0
- package/src/types/virtual/config.d.ts +4 -1
- package/src/types/virtual/indexers.d.ts +4 -1
- package/src/types/virtual/instrumentation.d.ts +4 -0
- package/dist/rollup/index.d.mts +0 -6
- package/dist/rollup/index.d.ts +0 -6
- package/dist/rollup/index.mjs +0 -150
- package/dist/shared/apibara.1b515d04.mjs +0 -8
- package/src/core/config/resolvers/runtime-config.resolver.ts +0 -6
- package/src/rollup/config.ts +0 -87
- package/src/rollup/index.ts +0 -2
- package/src/rollup/plugins/config.ts +0 -12
- package/src/rollup/plugins/esm-shim.ts +0 -69
- package/src/types/rollup.ts +0 -8
package/dist/create/index.mjs
CHANGED
|
@@ -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
|
|
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
|
{
|
|
@@ -57,26 +44,25 @@ const storages = [
|
|
|
57
44
|
];
|
|
58
45
|
const packageVersions = {
|
|
59
46
|
// Required Dependencies
|
|
60
|
-
apibara: "
|
|
61
|
-
"@apibara/indexer": "
|
|
62
|
-
"@apibara/protocol": "
|
|
47
|
+
apibara: "next",
|
|
48
|
+
"@apibara/indexer": "next",
|
|
49
|
+
"@apibara/protocol": "next",
|
|
63
50
|
// Chain Dependencies
|
|
64
|
-
"@apibara/evm": "
|
|
65
|
-
"@apibara/beaconchain": "
|
|
66
|
-
"@apibara/starknet": "
|
|
51
|
+
"@apibara/evm": "next",
|
|
52
|
+
"@apibara/beaconchain": "next",
|
|
53
|
+
"@apibara/starknet": "next",
|
|
67
54
|
// Storage Dependencies
|
|
68
|
-
"@apibara/plugin-drizzle": "
|
|
69
|
-
"@apibara/plugin-mongo": "
|
|
70
|
-
"@apibara/plugin-sqlite": "
|
|
55
|
+
"@apibara/plugin-drizzle": "next",
|
|
56
|
+
"@apibara/plugin-mongo": "next",
|
|
57
|
+
"@apibara/plugin-sqlite": "next",
|
|
71
58
|
// Postgres Dependencies
|
|
72
59
|
"@electric-sql/pglite": "^0.2.17",
|
|
73
|
-
"drizzle-orm": "^0.
|
|
60
|
+
"drizzle-orm": "^0.40.1",
|
|
74
61
|
pg: "^8.13.1",
|
|
75
62
|
"@types/pg": "^8.11.10",
|
|
76
63
|
"drizzle-kit": "^0.29.0",
|
|
77
64
|
// Typescript Dependencies
|
|
78
65
|
typescript: "^5.6.2",
|
|
79
|
-
"@rollup/plugin-typescript": "^11.1.6",
|
|
80
66
|
"@types/node": "^20.5.2"
|
|
81
67
|
};
|
|
82
68
|
const dnaUrls = {
|
|
@@ -386,7 +372,7 @@ function generatePackageJson(isTypeScript) {
|
|
|
386
372
|
private: true,
|
|
387
373
|
type: "module",
|
|
388
374
|
scripts: {
|
|
389
|
-
prepare: "apibara prepare",
|
|
375
|
+
...isTypeScript && { prepare: "apibara prepare" },
|
|
390
376
|
dev: "apibara dev",
|
|
391
377
|
start: "apibara start",
|
|
392
378
|
build: "apibara build",
|
|
@@ -399,7 +385,6 @@ function generatePackageJson(isTypeScript) {
|
|
|
399
385
|
},
|
|
400
386
|
devDependencies: {
|
|
401
387
|
...isTypeScript && {
|
|
402
|
-
"@rollup/plugin-typescript": packageVersions["@rollup/plugin-typescript"],
|
|
403
388
|
"@types/node": packageVersions["@types/node"],
|
|
404
389
|
typescript: packageVersions.typescript
|
|
405
390
|
}
|
|
@@ -427,13 +412,10 @@ function generateTsConfig() {
|
|
|
427
412
|
};
|
|
428
413
|
}
|
|
429
414
|
function generateApibaraConfig(isTypeScript) {
|
|
430
|
-
return
|
|
415
|
+
return `import { defineConfig } from "apibara/config";
|
|
431
416
|
|
|
432
417
|
export default defineConfig({
|
|
433
|
-
runtimeConfig: {}
|
|
434
|
-
rollupConfig: {
|
|
435
|
-
plugins: [typescript()${isTypeScript ? " as Plugin" : ""}],
|
|
436
|
-
},` : ""}
|
|
418
|
+
runtimeConfig: {},
|
|
437
419
|
});
|
|
438
420
|
`;
|
|
439
421
|
}
|
|
@@ -446,15 +428,18 @@ function generateIndexer({
|
|
|
446
428
|
return `import { defineIndexer } from "@apibara/indexer";
|
|
447
429
|
import { useLogger } from "@apibara/indexer/plugins";
|
|
448
430
|
${storage === "postgres" ? `import { drizzleStorage } from "@apibara/plugin-drizzle";` : ""}
|
|
431
|
+
${storage === "postgres" ? `import { drizzle } from "@apibara/plugin-drizzle";` : ""}
|
|
449
432
|
${chain === "ethereum" ? `import { EvmStream } from "@apibara/evm";` : chain === "beaconchain" ? `import { BeaconChainStream } from "@apibara/beaconchain";` : chain === "starknet" ? `import { StarknetStream } from "@apibara/starknet";` : ""}
|
|
450
433
|
${language === "typescript" ? `import type { ApibaraRuntimeConfig } from "apibara/types";` : ""}
|
|
451
|
-
${storage === "postgres" ? `import
|
|
434
|
+
${storage === "postgres" ? `import * as schema from "../lib/schema";` : ""}
|
|
452
435
|
|
|
453
436
|
|
|
454
437
|
export default function (runtimeConfig${language === "typescript" ? ": ApibaraRuntimeConfig" : ""}) {
|
|
455
438
|
const indexerId = "${indexerId}";
|
|
456
|
-
const { startingBlock, streamUrl
|
|
457
|
-
${storage === "postgres" ?
|
|
439
|
+
const { startingBlock, streamUrl } = runtimeConfig[indexerId];
|
|
440
|
+
${storage === "postgres" ? `const db = drizzle({
|
|
441
|
+
schema,
|
|
442
|
+
});` : ""}
|
|
458
443
|
|
|
459
444
|
return defineIndexer(${chain === "ethereum" ? "EvmStream" : chain === "beaconchain" ? "BeaconChainStream" : chain === "starknet" ? "StarknetStream" : ""})({
|
|
460
445
|
streamUrl,
|
|
@@ -463,7 +448,7 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
463
448
|
filter: {
|
|
464
449
|
header: "always",
|
|
465
450
|
},
|
|
466
|
-
plugins: [${storage === "postgres" ? "drizzleStorage({ db,
|
|
451
|
+
plugins: [${storage === "postgres" ? "drizzleStorage({ db, migrate: { migrationsFolder: './drizzle' } })" : ""}],
|
|
467
452
|
async transform({ endCursor, finality }) {
|
|
468
453
|
const logger = useLogger();
|
|
469
454
|
|
|
@@ -475,14 +460,12 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
475
460
|
);
|
|
476
461
|
|
|
477
462
|
${storage === "postgres" ? `// Example snippet to insert data into db using drizzle with postgres
|
|
478
|
-
//
|
|
479
|
-
|
|
480
|
-
//
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
// });
|
|
485
|
-
// }` : ""}
|
|
463
|
+
// const { db: database } = useDrizzleStorage();
|
|
464
|
+
|
|
465
|
+
// await database.insert(schema.cursorTable).values({
|
|
466
|
+
// endCursor: Number(endCursor?.orderKey),
|
|
467
|
+
// uniqueKey: \`\${endCursor?.uniqueKey}\`,
|
|
468
|
+
// });` : ""}
|
|
486
469
|
},
|
|
487
470
|
});
|
|
488
471
|
}
|
|
@@ -549,8 +532,8 @@ async function updateApibaraConfigFile({
|
|
|
549
532
|
);
|
|
550
533
|
const runtimeConfigString = `{
|
|
551
534
|
startingBlock: 0,
|
|
552
|
-
streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
|
|
553
|
-
|
|
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,7 +564,7 @@ async function updateApibaraConfigFile({
|
|
|
581
564
|
await formatFile(pathToConfig);
|
|
582
565
|
}
|
|
583
566
|
async function createDrizzleStorageFiles(options) {
|
|
584
|
-
const { cwd, language, storage } = options;
|
|
567
|
+
const { cwd, language, storage, indexerId } = options;
|
|
585
568
|
if (storage !== "postgres")
|
|
586
569
|
return;
|
|
587
570
|
const fileExtension = language === "typescript" ? "ts" : "js";
|
|
@@ -595,11 +578,11 @@ async function createDrizzleStorageFiles(options) {
|
|
|
595
578
|
const drizzleConfigContent = `${language === "typescript" ? 'import type { Config } from "drizzle-kit";' : ""}
|
|
596
579
|
|
|
597
580
|
export default {
|
|
598
|
-
schema: "./lib/schema
|
|
581
|
+
schema: "./lib/schema.${fileExtension}",
|
|
599
582
|
out: "./drizzle",
|
|
600
583
|
dialect: "postgresql",
|
|
601
584
|
dbCredentials: {
|
|
602
|
-
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "",
|
|
585
|
+
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}",
|
|
603
586
|
},
|
|
604
587
|
}${language === "typescript" ? " satisfies Config" : ""};`;
|
|
605
588
|
fs.writeFileSync(drizzleConfigPath, drizzleConfigContent);
|
|
@@ -614,14 +597,14 @@ export default {
|
|
|
614
597
|
fileName: `lib/${schemaFileName}`
|
|
615
598
|
});
|
|
616
599
|
if (!schemaExists || schemaOverwrite) {
|
|
617
|
-
const schemaContent = `// --- Add your pg table schemas here ----
|
|
600
|
+
const schemaContent = `// --- Add your pg table schemas here ----
|
|
618
601
|
|
|
619
602
|
// import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
620
603
|
|
|
621
|
-
// export const
|
|
604
|
+
// export const cursorTable = pgTable("cursor_table", {
|
|
622
605
|
// id: uuid("id").primaryKey().defaultRandom(),
|
|
623
|
-
//
|
|
624
|
-
//
|
|
606
|
+
// endCursor: bigint("end_cursor", { mode: "number" }),
|
|
607
|
+
// uniqueKey: text("unique_key"),
|
|
625
608
|
// });
|
|
626
609
|
|
|
627
610
|
export {};
|
|
@@ -631,48 +614,6 @@ export {};
|
|
|
631
614
|
await formatFile(schemaPath);
|
|
632
615
|
consola.success(`Created ${cyan("lib/schema.ts")}`);
|
|
633
616
|
}
|
|
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}`)}`);
|
|
675
|
-
}
|
|
676
617
|
console.log("\n");
|
|
677
618
|
if (!schemaExists || schemaOverwrite) {
|
|
678
619
|
consola.info(
|
|
@@ -688,15 +629,15 @@ ${yellow(`
|
|
|
688
629
|
|
|
689
630
|
import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
690
631
|
|
|
691
|
-
export const
|
|
632
|
+
export const cursorTable = pgTable("cursor_table", {
|
|
692
633
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
693
|
-
|
|
694
|
-
|
|
634
|
+
endCursor: bigint("end_cursor", { mode: "number" }),
|
|
635
|
+
uniqueKey: text("unique_key"),
|
|
695
636
|
});`)}`);
|
|
696
637
|
console.log("\n");
|
|
697
638
|
}
|
|
698
639
|
consola.info(
|
|
699
|
-
`Run ${green(`${options.packageManager} run drizzle:generate`)} & ${green(`${options.packageManager} run drizzle:migrate`)} to generate and apply migrations.`
|
|
640
|
+
`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
641
|
);
|
|
701
642
|
}
|
|
702
643
|
async function createStorageRelatedFiles(options) {
|
|
@@ -705,6 +646,90 @@ async function createStorageRelatedFiles(options) {
|
|
|
705
646
|
await createDrizzleStorageFiles(options);
|
|
706
647
|
}
|
|
707
648
|
}
|
|
649
|
+
const gitIgnoreItems = [
|
|
650
|
+
{
|
|
651
|
+
isRecommended: false,
|
|
652
|
+
value: "node_modules"
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
isRecommended: false,
|
|
656
|
+
value: "dist"
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
isRecommended: true,
|
|
660
|
+
description: "build and dev files of apibara",
|
|
661
|
+
value: ".apibara"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
isRecommended: false,
|
|
665
|
+
value: ".env"
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
isRecommended: false,
|
|
669
|
+
description: "for mac users",
|
|
670
|
+
value: ".DS_Store"
|
|
671
|
+
}
|
|
672
|
+
];
|
|
673
|
+
async function createGitIgnoreFile(cwd) {
|
|
674
|
+
const gitIgnorePath = path.join(cwd, ".gitignore");
|
|
675
|
+
if (fs.existsSync(gitIgnorePath)) {
|
|
676
|
+
const result = await prompts([
|
|
677
|
+
{
|
|
678
|
+
type: "select",
|
|
679
|
+
name: "overwrite",
|
|
680
|
+
message: `${cyan(".gitignore")} already exists. Please choose how to proceed:`,
|
|
681
|
+
initial: 0,
|
|
682
|
+
choices: [
|
|
683
|
+
{
|
|
684
|
+
title: "Choose items to append in your .gitignore",
|
|
685
|
+
value: "append"
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
title: "Keep original",
|
|
689
|
+
value: "ignore"
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
title: "Overwrite",
|
|
693
|
+
value: "overwrite"
|
|
694
|
+
}
|
|
695
|
+
]
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
type: (overwrite2) => overwrite2 === "append" ? "multiselect" : null,
|
|
699
|
+
name: "ignoreItems",
|
|
700
|
+
message: "Choose items to append in your .gitignore",
|
|
701
|
+
choices: gitIgnoreItems.map((item) => ({
|
|
702
|
+
title: `${yellow(item.value)}${item.description ? ` - ${item.description}` : ""}${item.isRecommended ? ` ${green("(recommended)")}` : ""}`,
|
|
703
|
+
value: item.value
|
|
704
|
+
}))
|
|
705
|
+
}
|
|
706
|
+
]);
|
|
707
|
+
const { overwrite, ignoreItems } = result;
|
|
708
|
+
if (overwrite === "append" && ignoreItems.length > 0) {
|
|
709
|
+
const gitIgnoreContent = fs.readFileSync(gitIgnorePath, "utf8");
|
|
710
|
+
fs.writeFileSync(
|
|
711
|
+
gitIgnorePath,
|
|
712
|
+
`${gitIgnoreContent}
|
|
713
|
+
${result.ignoreItems.join("\n")}`
|
|
714
|
+
);
|
|
715
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
if (overwrite === "overwrite") {
|
|
719
|
+
fs.writeFileSync(
|
|
720
|
+
gitIgnorePath,
|
|
721
|
+
gitIgnoreItems.map((item) => item.value).join("\n")
|
|
722
|
+
);
|
|
723
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
fs.writeFileSync(
|
|
728
|
+
gitIgnorePath,
|
|
729
|
+
gitIgnoreItems.map((item) => item.value).join("\n")
|
|
730
|
+
);
|
|
731
|
+
consola.success(`Created ${cyan(".gitignore")}`);
|
|
732
|
+
}
|
|
708
733
|
|
|
709
734
|
async function initializeProject({
|
|
710
735
|
argTargetDir,
|
|
@@ -789,35 +814,36 @@ async function initializeProject({
|
|
|
789
814
|
JSON.stringify(packageJson, null, 2) + "\n"
|
|
790
815
|
);
|
|
791
816
|
await formatFile(packageJsonPath);
|
|
792
|
-
consola$1.success("Created
|
|
817
|
+
consola$1.success("Created", cyan("package.json"));
|
|
793
818
|
if (isTs) {
|
|
794
819
|
const tsConfigPath = path.join(root, "tsconfig.json");
|
|
795
820
|
const tsConfig = generateTsConfig();
|
|
796
821
|
fs.writeFileSync(tsConfigPath, JSON.stringify(tsConfig, null, 2) + "\n");
|
|
797
822
|
await formatFile(tsConfigPath);
|
|
798
|
-
consola$1.success("Created
|
|
823
|
+
consola$1.success("Created", cyan("tsconfig.json"));
|
|
799
824
|
}
|
|
800
825
|
const apibaraConfigPath = path.join(root, `apibara.config.${configExt}`);
|
|
801
|
-
const apibaraConfig = generateApibaraConfig(
|
|
826
|
+
const apibaraConfig = generateApibaraConfig();
|
|
802
827
|
fs.writeFileSync(apibaraConfigPath, apibaraConfig);
|
|
803
828
|
await formatFile(apibaraConfigPath);
|
|
804
|
-
consola$1.success("Created
|
|
829
|
+
consola$1.success("Created", cyan(`apibara.config.${configExt}`));
|
|
805
830
|
const indexersDir = path.join(root, "indexers");
|
|
806
831
|
if (!fs.existsSync(indexersDir)) {
|
|
807
832
|
fs.mkdirSync(indexersDir, { recursive: true });
|
|
808
833
|
consola$1.success(`Created ${cyan("indexers")} directory`);
|
|
809
834
|
}
|
|
835
|
+
await createGitIgnoreFile(root);
|
|
810
836
|
console.log("\n");
|
|
811
837
|
consola$1.ready(green("Project initialized successfully"));
|
|
812
838
|
console.log();
|
|
813
839
|
if (!argNoCreateIndexer) {
|
|
814
840
|
consola$1.info("Let's create an indexer\n");
|
|
815
|
-
await addIndexer({});
|
|
841
|
+
await addIndexer({ argRootDir: argTargetDir });
|
|
816
842
|
} else {
|
|
817
843
|
const pkgManager = getPackageManager();
|
|
818
844
|
consola$1.info(
|
|
819
845
|
"Run ",
|
|
820
|
-
green(`${pkgManager.name}
|
|
846
|
+
green(`${pkgManager.name} install`),
|
|
821
847
|
" to install all dependencies"
|
|
822
848
|
);
|
|
823
849
|
}
|
|
@@ -828,9 +854,11 @@ async function addIndexer({
|
|
|
828
854
|
argChain,
|
|
829
855
|
argNetwork,
|
|
830
856
|
argStorage,
|
|
831
|
-
argDnaUrl
|
|
857
|
+
argDnaUrl,
|
|
858
|
+
argRootDir
|
|
832
859
|
}) {
|
|
833
|
-
const
|
|
860
|
+
const cwd = path.join(process.cwd(), argRootDir ?? ".");
|
|
861
|
+
const configExists = hasApibaraConfig(cwd);
|
|
834
862
|
if (!configExists) {
|
|
835
863
|
consola$1.error("No apibara.config found in the current directory.");
|
|
836
864
|
const prompt_initialize = await prompts({
|
|
@@ -854,7 +882,7 @@ async function addIndexer({
|
|
|
854
882
|
);
|
|
855
883
|
}
|
|
856
884
|
}
|
|
857
|
-
const language = getApibaraConfigLanguage(
|
|
885
|
+
const language = getApibaraConfigLanguage(cwd);
|
|
858
886
|
validateIndexerId(argIndexerId, true);
|
|
859
887
|
validateChain(argChain, true);
|
|
860
888
|
validateNetwork(argChain, argNetwork, true);
|
|
@@ -869,7 +897,7 @@ async function addIndexer({
|
|
|
869
897
|
initial: argIndexerId ?? "my-indexer",
|
|
870
898
|
validate: (id) => validateIndexerId(id) ? checkFileExists(
|
|
871
899
|
path.join(
|
|
872
|
-
|
|
900
|
+
cwd,
|
|
873
901
|
"indexers",
|
|
874
902
|
`${id}.indexer.${language === "typescript" ? "ts" : "js"}`
|
|
875
903
|
)
|
|
@@ -951,7 +979,7 @@ async function addIndexer({
|
|
|
951
979
|
const indexerFileId = argIndexerId ?? prompt_indexerId;
|
|
952
980
|
const pkgManager = getPackageManager();
|
|
953
981
|
const options = {
|
|
954
|
-
cwd
|
|
982
|
+
cwd,
|
|
955
983
|
indexerFileId,
|
|
956
984
|
indexerId: convertKebabToCamelCase(indexerFileId),
|
|
957
985
|
chain: argChain ?? prompt_chain?.name,
|
|
@@ -973,8 +1001,10 @@ async function addIndexer({
|
|
|
973
1001
|
);
|
|
974
1002
|
await createStorageRelatedFiles(options);
|
|
975
1003
|
console.log();
|
|
1004
|
+
const baseCommand = `${options.packageManager} install`;
|
|
1005
|
+
const tsCommand = `${baseCommand} && ${options.packageManager} run prepare`;
|
|
976
1006
|
consola$1.info(
|
|
977
|
-
`Before running the indexer, run ${cyan(
|
|
1007
|
+
`Before running the indexer, run ${cyan(language === "typescript" ? tsCommand : baseCommand)}`
|
|
978
1008
|
);
|
|
979
1009
|
}
|
|
980
1010
|
|
package/dist/hooks/index.mjs
CHANGED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { builtinModules } from 'node:module';
|
|
3
|
+
import replace from '@rollup/plugin-replace';
|
|
4
|
+
import defu from 'defu';
|
|
5
|
+
import { join as join$1 } from 'pathe';
|
|
6
|
+
import virtual from '@rollup/plugin-virtual';
|
|
7
|
+
import { hash } from 'ohash';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
function appConfig(apibara) {
|
|
11
|
+
return virtual({
|
|
12
|
+
"#apibara-internal-virtual/config": `
|
|
13
|
+
const serializedConfig = \`process.env.APIBARA_CONFIG\`;
|
|
14
|
+
|
|
15
|
+
if (serializedConfig === undefined || serializedConfig === "") {
|
|
16
|
+
throw new Error("APIBARA_CONFIG is not defined");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const config = JSON.parse(serializedConfig);
|
|
20
|
+
`
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function indexers(apibara) {
|
|
25
|
+
const indexers2 = [...new Set(apibara.indexers)];
|
|
26
|
+
return virtual({
|
|
27
|
+
"#apibara-internal-virtual/indexers": `
|
|
28
|
+
${indexers2.map((i) => `import * as _${hash(i)} from '${i.indexer}';`).join("\n")}
|
|
29
|
+
|
|
30
|
+
export const indexers = [
|
|
31
|
+
${indexers2.map((i) => `{ name: "${i.name}", indexer: _${hash(i)} }`).join(",\n")}
|
|
32
|
+
];
|
|
33
|
+
`
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function instrumentation(apibara) {
|
|
38
|
+
const instrumentationPath = join(
|
|
39
|
+
apibara.options._c12.cwd,
|
|
40
|
+
`instrumentation.${apibara.options._c12.configFile?.endsWith(".ts") ? "ts" : "js"}`
|
|
41
|
+
);
|
|
42
|
+
if (!existsSync(instrumentationPath)) {
|
|
43
|
+
return virtual({
|
|
44
|
+
"#apibara-internal-virtual/instrumentation": `
|
|
45
|
+
let register = undefined;
|
|
46
|
+
let logger = undefined;
|
|
47
|
+
|
|
48
|
+
export { register, logger };
|
|
49
|
+
`
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return virtual({
|
|
53
|
+
"#apibara-internal-virtual/instrumentation": `
|
|
54
|
+
let register = undefined;
|
|
55
|
+
let logger = undefined;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const instrumentation = require('${instrumentationPath}');
|
|
59
|
+
|
|
60
|
+
if (instrumentation?.register && typeof instrumentation.register === "function") {
|
|
61
|
+
register = instrumentation.register;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (instrumentation?.logger && typeof instrumentation.logger === "function") {
|
|
65
|
+
logger = instrumentation.logger;
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
// Silently handle any require errors
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { register, logger };
|
|
72
|
+
`
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const runtimeDependencies = [
|
|
77
|
+
"better-sqlite3",
|
|
78
|
+
"@electric-sql/pglite",
|
|
79
|
+
"pg",
|
|
80
|
+
// https://socket.io/docs/v4/server-installation/#additional-packages
|
|
81
|
+
"utf-8-validate",
|
|
82
|
+
"bufferutil",
|
|
83
|
+
// was giving unresolved import warnings from `node-fetch` library.
|
|
84
|
+
"encoding"
|
|
85
|
+
];
|
|
86
|
+
function getRolldownConfig(apibara) {
|
|
87
|
+
const extensions = [
|
|
88
|
+
".ts",
|
|
89
|
+
".mjs",
|
|
90
|
+
".js",
|
|
91
|
+
".json",
|
|
92
|
+
".node",
|
|
93
|
+
".tsx",
|
|
94
|
+
".jsx"
|
|
95
|
+
];
|
|
96
|
+
const tsConfigExists = existsSync(
|
|
97
|
+
join$1(apibara.options.rootDir, "tsconfig.json")
|
|
98
|
+
);
|
|
99
|
+
const rolldownConfig = defu(
|
|
100
|
+
// biome-ignore lint/suspicious/noExplicitAny: apibara.options.rolldownConfig is typed
|
|
101
|
+
apibara.options.rolldownConfig,
|
|
102
|
+
{
|
|
103
|
+
platform: "node",
|
|
104
|
+
input: apibara.options.entry,
|
|
105
|
+
output: {
|
|
106
|
+
dir: join$1(apibara.options.outputDir || "./.apibara/build"),
|
|
107
|
+
format: "esm",
|
|
108
|
+
entryFileNames: "[name].mjs",
|
|
109
|
+
chunkFileNames: "chunks/[name]-[hash].mjs",
|
|
110
|
+
sourcemap: true
|
|
111
|
+
},
|
|
112
|
+
plugins: [],
|
|
113
|
+
onwarn(warning, rolldownWarn) {
|
|
114
|
+
if (!["CIRCULAR_DEPENDENCY", "EVAL", "THIS_IS_UNDEFINED"].includes(
|
|
115
|
+
warning.code || ""
|
|
116
|
+
) && !warning.message.includes("Unsupported source map comment") && !warning.message.includes("@__PURE__") && !warning.message.includes("/*#__PURE__*/")) {
|
|
117
|
+
rolldownWarn(warning);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
resolve: {
|
|
121
|
+
extensions,
|
|
122
|
+
preferBuiltins: !!apibara.options.node,
|
|
123
|
+
mainFields: ["main"],
|
|
124
|
+
exportConditions: apibara.options.exportConditions,
|
|
125
|
+
tsconfigFilename: tsConfigExists ? "tsconfig.json" : void 0
|
|
126
|
+
},
|
|
127
|
+
treeshake: true,
|
|
128
|
+
external: [...builtinModules, ...runtimeDependencies]
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
rolldownConfig.plugins?.push(
|
|
132
|
+
replace({
|
|
133
|
+
preventAssignment: true,
|
|
134
|
+
values: {
|
|
135
|
+
"process.env.APIBARA_CONFIG": getSerializedRuntimeConfig(apibara)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
);
|
|
139
|
+
rolldownConfig.plugins?.push(instrumentation(apibara));
|
|
140
|
+
rolldownConfig.plugins?.push(indexers(apibara));
|
|
141
|
+
rolldownConfig.plugins?.push(appConfig());
|
|
142
|
+
return rolldownConfig;
|
|
143
|
+
}
|
|
144
|
+
function getSerializedRuntimeConfig(apibara) {
|
|
145
|
+
try {
|
|
146
|
+
return JSON.stringify({
|
|
147
|
+
runtimeConfig: apibara.options.runtimeConfig,
|
|
148
|
+
preset: apibara.options.preset,
|
|
149
|
+
presets: apibara.options.presets
|
|
150
|
+
});
|
|
151
|
+
} catch (error) {
|
|
152
|
+
throw new Error(
|
|
153
|
+
"Failed to serialize runtime config. Please ensure all values in your runtime configuration are JSON serializable.",
|
|
154
|
+
{ cause: error }
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export { getRolldownConfig };
|
package/dist/runtime/dev.mjs
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { runWithReconnect } from "@apibara/indexer";
|
|
2
|
-
import { createClient } from "@apibara/protocol";
|
|
3
2
|
import { defineCommand, runMain } from "citty";
|
|
4
|
-
import {
|
|
3
|
+
import { blueBright } from "picocolors";
|
|
4
|
+
import {
|
|
5
|
+
availableIndexers,
|
|
6
|
+
createAuthenticatedClient,
|
|
7
|
+
createIndexer
|
|
8
|
+
} from "./internal/app.mjs";
|
|
5
9
|
const startCommand = defineCommand({
|
|
6
10
|
meta: {
|
|
7
11
|
name: "start",
|
|
@@ -32,11 +36,17 @@ const startCommand = defineCommand({
|
|
|
32
36
|
}
|
|
33
37
|
await Promise.all(
|
|
34
38
|
selectedIndexers.map(async (indexer) => {
|
|
35
|
-
const indexerInstance = createIndexer(indexer, preset);
|
|
36
|
-
|
|
39
|
+
const { indexer: indexerInstance, logger } = createIndexer(indexer, preset) ?? {};
|
|
40
|
+
if (!indexerInstance) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const client = createAuthenticatedClient(
|
|
37
44
|
indexerInstance.streamConfig,
|
|
38
45
|
indexerInstance.options.streamUrl
|
|
39
46
|
);
|
|
47
|
+
if (logger) {
|
|
48
|
+
logger.info(`Indexer ${blueBright(indexer)} started`);
|
|
49
|
+
}
|
|
40
50
|
await runWithReconnect(client, indexerInstance);
|
|
41
51
|
})
|
|
42
52
|
);
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import { type CreateClientOptions, type StreamConfig } from "@apibara/protocol";
|
|
1
2
|
export declare const availableIndexers: any;
|
|
2
|
-
export declare function createIndexer(indexerName: string, preset?: string):
|
|
3
|
+
export declare function createIndexer(indexerName: string, preset?: string): {
|
|
4
|
+
indexer: import("@apibara/indexer").Indexer<unknown, unknown>;
|
|
5
|
+
logger: any;
|
|
6
|
+
} | undefined;
|
|
7
|
+
export declare function createAuthenticatedClient(config: StreamConfig<unknown, unknown>, streamUrl: string, options?: CreateClientOptions): import("@apibara/protocol").GrpcClient<unknown, unknown>;
|