apibara 2.1.0-beta.1 → 2.1.0-beta.10
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 +12 -7
- package/dist/chunks/dev.mjs +23 -5
- package/dist/chunks/init.mjs +3 -7
- package/dist/core/index.mjs +69 -40
- package/dist/create/index.d.mts +2 -1
- package/dist/create/index.d.ts +2 -1
- package/dist/create/index.mjs +185 -121
- package/dist/rolldown/index.d.mts +7 -0
- package/dist/rolldown/index.d.ts +7 -0
- package/dist/rolldown/index.mjs +90 -0
- package/dist/runtime/dev.mjs +3 -0
- package/dist/runtime/internal/app.d.ts +1 -1
- package/dist/runtime/internal/app.mjs +11 -3
- package/dist/runtime/start.mjs +5 -0
- package/dist/types/index.d.mts +18 -15
- package/dist/types/index.d.ts +18 -15
- package/package.json +12 -15
- package/src/cli/commands/add.ts +12 -6
- package/src/cli/commands/dev.ts +26 -5
- package/src/cli/commands/init.ts +3 -7
- 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/prod.ts +15 -10
- package/src/core/build/types.ts +8 -0
- package/src/core/config/defaults.ts +3 -0
- package/src/core/config/update.ts +1 -1
- package/src/create/add.ts +26 -12
- package/src/create/constants.ts +9 -10
- package/src/create/init.ts +28 -14
- package/src/create/templates.ts +154 -118
- package/src/create/utils.ts +10 -0
- package/src/rolldown/config.ts +83 -0
- package/src/rolldown/index.ts +2 -0
- package/src/{rollup → rolldown}/plugins/config.ts +2 -1
- package/src/{rollup → rolldown}/plugins/indexers.ts +3 -3
- package/src/runtime/dev.ts +3 -0
- package/src/runtime/internal/app.ts +13 -5
- package/src/runtime/start.ts +5 -0
- package/src/types/config.ts +12 -7
- 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/indexers.d.ts +4 -1
- package/dist/rollup/index.d.mts +0 -6
- package/dist/rollup/index.d.ts +0 -6
- package/dist/rollup/index.mjs +0 -150
- package/src/rollup/config.ts +0 -87
- package/src/rollup/index.ts +0 -2
- package/src/rollup/plugins/esm-shim.ts +0 -69
- package/src/types/rollup.ts +0 -8
package/dist/create/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import path, { basename } from 'node:path';
|
|
1
2
|
import consola$1, { consola } from 'consola';
|
|
2
3
|
import prompts from 'prompts';
|
|
3
4
|
import colors from 'picocolors';
|
|
4
5
|
import fs from 'node:fs';
|
|
5
|
-
import path, { basename } from 'node:path';
|
|
6
6
|
import { Project, SyntaxKind } from 'ts-morph';
|
|
7
|
+
import * as prettier from 'prettier';
|
|
7
8
|
|
|
8
9
|
const {
|
|
9
10
|
blue,
|
|
@@ -56,17 +57,17 @@ const storages = [
|
|
|
56
57
|
];
|
|
57
58
|
const packageVersions = {
|
|
58
59
|
// Required Dependencies
|
|
59
|
-
apibara: "
|
|
60
|
-
"@apibara/indexer": "
|
|
61
|
-
"@apibara/protocol": "
|
|
60
|
+
apibara: "next",
|
|
61
|
+
"@apibara/indexer": "next",
|
|
62
|
+
"@apibara/protocol": "next",
|
|
62
63
|
// Chain Dependencies
|
|
63
|
-
"@apibara/evm": "
|
|
64
|
-
"@apibara/beaconchain": "
|
|
65
|
-
"@apibara/starknet": "
|
|
64
|
+
"@apibara/evm": "next",
|
|
65
|
+
"@apibara/beaconchain": "next",
|
|
66
|
+
"@apibara/starknet": "next",
|
|
66
67
|
// Storage Dependencies
|
|
67
|
-
"@apibara/plugin-drizzle": "
|
|
68
|
-
"@apibara/plugin-mongo": "
|
|
69
|
-
"@apibara/plugin-sqlite": "
|
|
68
|
+
"@apibara/plugin-drizzle": "next",
|
|
69
|
+
"@apibara/plugin-mongo": "next",
|
|
70
|
+
"@apibara/plugin-sqlite": "next",
|
|
70
71
|
// Postgres Dependencies
|
|
71
72
|
"@electric-sql/pglite": "^0.2.17",
|
|
72
73
|
"drizzle-orm": "^0.37.0",
|
|
@@ -75,7 +76,6 @@ const packageVersions = {
|
|
|
75
76
|
"drizzle-kit": "^0.29.0",
|
|
76
77
|
// Typescript Dependencies
|
|
77
78
|
typescript: "^5.6.2",
|
|
78
|
-
"@rollup/plugin-typescript": "^11.1.6",
|
|
79
79
|
"@types/node": "^20.5.2"
|
|
80
80
|
};
|
|
81
81
|
const dnaUrls = {
|
|
@@ -369,6 +369,14 @@ function pkgFromUserAgent(userAgent) {
|
|
|
369
369
|
version: pkgSpecArr[1]
|
|
370
370
|
};
|
|
371
371
|
}
|
|
372
|
+
async function formatFile(path2) {
|
|
373
|
+
const file = fs.readFileSync(path2, "utf8");
|
|
374
|
+
const formatted = await prettier.format(file, {
|
|
375
|
+
filepath: path2,
|
|
376
|
+
tabWidth: 2
|
|
377
|
+
});
|
|
378
|
+
fs.writeFileSync(path2, formatted);
|
|
379
|
+
}
|
|
372
380
|
|
|
373
381
|
function generatePackageJson(isTypeScript) {
|
|
374
382
|
return {
|
|
@@ -377,7 +385,7 @@ function generatePackageJson(isTypeScript) {
|
|
|
377
385
|
private: true,
|
|
378
386
|
type: "module",
|
|
379
387
|
scripts: {
|
|
380
|
-
prepare: "apibara prepare",
|
|
388
|
+
...isTypeScript && { prepare: "apibara prepare" },
|
|
381
389
|
dev: "apibara dev",
|
|
382
390
|
start: "apibara start",
|
|
383
391
|
build: "apibara build",
|
|
@@ -390,7 +398,6 @@ function generatePackageJson(isTypeScript) {
|
|
|
390
398
|
},
|
|
391
399
|
devDependencies: {
|
|
392
400
|
...isTypeScript && {
|
|
393
|
-
"@rollup/plugin-typescript": packageVersions["@rollup/plugin-typescript"],
|
|
394
401
|
"@types/node": packageVersions["@types/node"],
|
|
395
402
|
typescript: packageVersions.typescript
|
|
396
403
|
}
|
|
@@ -418,13 +425,10 @@ function generateTsConfig() {
|
|
|
418
425
|
};
|
|
419
426
|
}
|
|
420
427
|
function generateApibaraConfig(isTypeScript) {
|
|
421
|
-
return
|
|
428
|
+
return `import { defineConfig } from "apibara/config";
|
|
422
429
|
|
|
423
430
|
export default defineConfig({
|
|
424
|
-
runtimeConfig: {}
|
|
425
|
-
rollupConfig: {
|
|
426
|
-
plugins: [typescript()${isTypeScript ? " as Plugin" : ""}],
|
|
427
|
-
},` : ""}
|
|
431
|
+
runtimeConfig: {},
|
|
428
432
|
});
|
|
429
433
|
`;
|
|
430
434
|
}
|
|
@@ -434,18 +438,22 @@ function generateIndexer({
|
|
|
434
438
|
chain,
|
|
435
439
|
language
|
|
436
440
|
}) {
|
|
437
|
-
return
|
|
438
|
-
import {
|
|
441
|
+
return `import { defineIndexer } from "@apibara/indexer";
|
|
442
|
+
import { useLogger } from "@apibara/indexer/plugins";
|
|
439
443
|
${storage === "postgres" ? `import { drizzleStorage } from "@apibara/plugin-drizzle";` : ""}
|
|
444
|
+
${storage === "postgres" ? `import { drizzle } from "@apibara/plugin-drizzle";` : ""}
|
|
445
|
+
${chain === "ethereum" ? `import { EvmStream } from "@apibara/evm";` : chain === "beaconchain" ? `import { BeaconChainStream } from "@apibara/beaconchain";` : chain === "starknet" ? `import { StarknetStream } from "@apibara/starknet";` : ""}
|
|
440
446
|
${language === "typescript" ? `import type { ApibaraRuntimeConfig } from "apibara/types";` : ""}
|
|
441
|
-
import
|
|
442
|
-
${storage === "postgres" ? `import { getDrizzlePgDatabase } from "../lib/db";` : ""}
|
|
447
|
+
${storage === "postgres" ? `import * as schema from "../lib/schema";` : ""}
|
|
443
448
|
|
|
444
449
|
|
|
445
450
|
export default function (runtimeConfig${language === "typescript" ? ": ApibaraRuntimeConfig" : ""}) {
|
|
446
451
|
const indexerId = "${indexerId}";
|
|
447
452
|
const { startingBlock, streamUrl${storage === "postgres" ? ", postgresConnectionString" : ""} } = runtimeConfig[indexerId];
|
|
448
|
-
${storage === "postgres" ?
|
|
453
|
+
${storage === "postgres" ? `const db = drizzle({
|
|
454
|
+
schema,
|
|
455
|
+
connectionString: postgresConnectionString,
|
|
456
|
+
});` : ""}
|
|
449
457
|
|
|
450
458
|
return defineIndexer(${chain === "ethereum" ? "EvmStream" : chain === "beaconchain" ? "BeaconChainStream" : chain === "starknet" ? "StarknetStream" : ""})({
|
|
451
459
|
streamUrl,
|
|
@@ -454,7 +462,7 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
454
462
|
filter: {
|
|
455
463
|
header: "always",
|
|
456
464
|
},
|
|
457
|
-
plugins: [${storage === "postgres" ? "drizzleStorage({ db,
|
|
465
|
+
plugins: [${storage === "postgres" ? "drizzleStorage({ db, migrate: { migrationsFolder: './drizzle' } })" : ""}],
|
|
458
466
|
async transform({ endCursor, finality }) {
|
|
459
467
|
const logger = useLogger();
|
|
460
468
|
|
|
@@ -466,14 +474,12 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
466
474
|
);
|
|
467
475
|
|
|
468
476
|
${storage === "postgres" ? `// Example snippet to insert data into db using drizzle with postgres
|
|
469
|
-
//
|
|
470
|
-
|
|
471
|
-
//
|
|
472
|
-
//
|
|
473
|
-
//
|
|
474
|
-
//
|
|
475
|
-
// });
|
|
476
|
-
// }` : ""}
|
|
477
|
+
// const { db: database } = useDrizzleStorage();
|
|
478
|
+
|
|
479
|
+
// await database.insert(schema.cursorTable).values({
|
|
480
|
+
// endCursor: Number(endCursor?.orderKey),
|
|
481
|
+
// uniqueKey: \`\${endCursor?.uniqueKey}\`,
|
|
482
|
+
// });` : ""}
|
|
477
483
|
},
|
|
478
484
|
});
|
|
479
485
|
}
|
|
@@ -493,16 +499,16 @@ async function createIndexerFile(options) {
|
|
|
493
499
|
const indexerContent = generateIndexer(options);
|
|
494
500
|
fs.mkdirSync(path.dirname(indexerFilePath), { recursive: true });
|
|
495
501
|
fs.writeFileSync(indexerFilePath, indexerContent);
|
|
502
|
+
await formatFile(indexerFilePath);
|
|
496
503
|
}
|
|
497
|
-
function updatePackageJson({
|
|
504
|
+
async function updatePackageJson({
|
|
498
505
|
cwd,
|
|
499
506
|
chain,
|
|
500
507
|
storage,
|
|
501
508
|
language
|
|
502
509
|
}) {
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
);
|
|
510
|
+
const packageJsonPath = path.join(cwd, "package.json");
|
|
511
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
506
512
|
if (chain === "ethereum") {
|
|
507
513
|
packageJson.dependencies["@apibara/evm"] = packageVersions["@apibara/evm"];
|
|
508
514
|
} else if (chain === "beaconchain") {
|
|
@@ -522,12 +528,10 @@ function updatePackageJson({
|
|
|
522
528
|
packageJson.devDependencies["@types/pg"] = packageVersions["@types/pg"];
|
|
523
529
|
}
|
|
524
530
|
}
|
|
525
|
-
fs.writeFileSync(
|
|
526
|
-
|
|
527
|
-
JSON.stringify(packageJson, null, 2)
|
|
528
|
-
);
|
|
531
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
532
|
+
await formatFile(packageJsonPath);
|
|
529
533
|
}
|
|
530
|
-
function updateApibaraConfigFile({
|
|
534
|
+
async function updateApibaraConfigFile({
|
|
531
535
|
indexerId,
|
|
532
536
|
cwd,
|
|
533
537
|
chain,
|
|
@@ -571,14 +575,10 @@ function updateApibaraConfigFile({
|
|
|
571
575
|
});
|
|
572
576
|
}
|
|
573
577
|
sourceFile.saveSync();
|
|
574
|
-
|
|
575
|
-
tabSize: 2,
|
|
576
|
-
insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: true,
|
|
577
|
-
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true
|
|
578
|
-
});
|
|
578
|
+
await formatFile(pathToConfig);
|
|
579
579
|
}
|
|
580
580
|
async function createDrizzleStorageFiles(options) {
|
|
581
|
-
const { cwd, language, storage } = options;
|
|
581
|
+
const { cwd, language, storage, indexerId } = options;
|
|
582
582
|
if (storage !== "postgres")
|
|
583
583
|
return;
|
|
584
584
|
const fileExtension = language === "typescript" ? "ts" : "js";
|
|
@@ -592,14 +592,15 @@ async function createDrizzleStorageFiles(options) {
|
|
|
592
592
|
const drizzleConfigContent = `${language === "typescript" ? 'import type { Config } from "drizzle-kit";' : ""}
|
|
593
593
|
|
|
594
594
|
export default {
|
|
595
|
-
schema: "./lib/schema
|
|
595
|
+
schema: "./lib/schema.${fileExtension}",
|
|
596
596
|
out: "./drizzle",
|
|
597
597
|
dialect: "postgresql",
|
|
598
598
|
dbCredentials: {
|
|
599
|
-
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "",
|
|
599
|
+
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}",
|
|
600
600
|
},
|
|
601
601
|
}${language === "typescript" ? " satisfies Config" : ""};`;
|
|
602
602
|
fs.writeFileSync(drizzleConfigPath, drizzleConfigContent);
|
|
603
|
+
await formatFile(drizzleConfigPath);
|
|
603
604
|
consola.success(`Created ${cyan(drizzleConfigFileName)}`);
|
|
604
605
|
}
|
|
605
606
|
const schemaFileName = `schema.${fileExtension}`;
|
|
@@ -610,63 +611,23 @@ export default {
|
|
|
610
611
|
fileName: `lib/${schemaFileName}`
|
|
611
612
|
});
|
|
612
613
|
if (!schemaExists || schemaOverwrite) {
|
|
613
|
-
const schemaContent = `// --- Add your pg table schemas here ----
|
|
614
|
+
const schemaContent = `// --- Add your pg table schemas here ----
|
|
614
615
|
|
|
615
616
|
// import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
616
617
|
|
|
617
|
-
// export const
|
|
618
|
+
// export const cursorTable = pgTable("cursor_table", {
|
|
618
619
|
// id: uuid("id").primaryKey().defaultRandom(),
|
|
619
|
-
//
|
|
620
|
-
//
|
|
620
|
+
// endCursor: bigint("end_cursor", { mode: "number" }),
|
|
621
|
+
// uniqueKey: text("unique_key"),
|
|
621
622
|
// });
|
|
622
623
|
|
|
623
624
|
export {};
|
|
624
625
|
`;
|
|
625
626
|
fs.mkdirSync(path.dirname(schemaPath), { recursive: true });
|
|
626
627
|
fs.writeFileSync(schemaPath, schemaContent);
|
|
628
|
+
await formatFile(schemaPath);
|
|
627
629
|
consola.success(`Created ${cyan("lib/schema.ts")}`);
|
|
628
630
|
}
|
|
629
|
-
const dbFileName = `db.${fileExtension}`;
|
|
630
|
-
const dbPath = path.join(cwd, "lib", dbFileName);
|
|
631
|
-
const { exists: dbExists, overwrite: dbOverwrite } = await checkFileExists(
|
|
632
|
-
dbPath,
|
|
633
|
-
{
|
|
634
|
-
askPrompt: true,
|
|
635
|
-
fileName: `lib/${dbFileName}`,
|
|
636
|
-
allowIgnore: true
|
|
637
|
-
}
|
|
638
|
-
);
|
|
639
|
-
if (!dbExists || dbOverwrite) {
|
|
640
|
-
const dbContent = `import * as schema from "./schema";
|
|
641
|
-
import { drizzle as nodePgDrizzle } from "drizzle-orm/node-postgres";
|
|
642
|
-
import { drizzle as pgLiteDrizzle } from "drizzle-orm/pglite";
|
|
643
|
-
import pg from "pg";
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
export function getDrizzlePgDatabase(connectionString${language === "typescript" ? ": string" : ""}) {
|
|
647
|
-
// Create pglite instance
|
|
648
|
-
if (connectionString.includes("memory")) {
|
|
649
|
-
return {
|
|
650
|
-
db: pgLiteDrizzle({
|
|
651
|
-
schema,
|
|
652
|
-
connection: {
|
|
653
|
-
dataDir: connectionString,
|
|
654
|
-
},
|
|
655
|
-
}),
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
// Create node-postgres instance
|
|
660
|
-
const pool = new pg.Pool({
|
|
661
|
-
connectionString,
|
|
662
|
-
});
|
|
663
|
-
|
|
664
|
-
return { db: nodePgDrizzle(pool, { schema }) };
|
|
665
|
-
}`;
|
|
666
|
-
fs.mkdirSync(path.dirname(dbPath), { recursive: true });
|
|
667
|
-
fs.writeFileSync(dbPath, dbContent);
|
|
668
|
-
consola.success(`Created ${cyan(`lib/${dbFileName}`)}`);
|
|
669
|
-
}
|
|
670
631
|
console.log("\n");
|
|
671
632
|
if (!schemaExists || schemaOverwrite) {
|
|
672
633
|
consola.info(
|
|
@@ -682,15 +643,15 @@ ${yellow(`
|
|
|
682
643
|
|
|
683
644
|
import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
684
645
|
|
|
685
|
-
export const
|
|
646
|
+
export const cursorTable = pgTable("cursor_table", {
|
|
686
647
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
687
|
-
|
|
688
|
-
|
|
648
|
+
endCursor: bigint("end_cursor", { mode: "number" }),
|
|
649
|
+
uniqueKey: text("unique_key"),
|
|
689
650
|
});`)}`);
|
|
690
651
|
console.log("\n");
|
|
691
652
|
}
|
|
692
653
|
consola.info(
|
|
693
|
-
`Run ${green(`${options.packageManager} run drizzle:generate`)} & ${green(`${options.packageManager} run drizzle:migrate`)} to generate and apply migrations.`
|
|
654
|
+
`Run ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:generate`)} & ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:migrate`)} to generate and apply migrations.`
|
|
694
655
|
);
|
|
695
656
|
}
|
|
696
657
|
async function createStorageRelatedFiles(options) {
|
|
@@ -699,6 +660,90 @@ async function createStorageRelatedFiles(options) {
|
|
|
699
660
|
await createDrizzleStorageFiles(options);
|
|
700
661
|
}
|
|
701
662
|
}
|
|
663
|
+
const gitIgnoreItems = [
|
|
664
|
+
{
|
|
665
|
+
isRecommended: false,
|
|
666
|
+
value: "node_modules"
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
isRecommended: false,
|
|
670
|
+
value: "dist"
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
isRecommended: true,
|
|
674
|
+
description: "build and dev files of apibara",
|
|
675
|
+
value: ".apibara"
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
isRecommended: false,
|
|
679
|
+
value: ".env"
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
isRecommended: false,
|
|
683
|
+
description: "for mac users",
|
|
684
|
+
value: ".DS_Store"
|
|
685
|
+
}
|
|
686
|
+
];
|
|
687
|
+
async function createGitIgnoreFile(cwd) {
|
|
688
|
+
const gitIgnorePath = path.join(cwd, ".gitignore");
|
|
689
|
+
if (fs.existsSync(gitIgnorePath)) {
|
|
690
|
+
const result = await prompts([
|
|
691
|
+
{
|
|
692
|
+
type: "select",
|
|
693
|
+
name: "overwrite",
|
|
694
|
+
message: `${cyan(".gitignore")} already exists. Please choose how to proceed:`,
|
|
695
|
+
initial: 0,
|
|
696
|
+
choices: [
|
|
697
|
+
{
|
|
698
|
+
title: "Choose items to append in your .gitignore",
|
|
699
|
+
value: "append"
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
title: "Keep original",
|
|
703
|
+
value: "ignore"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
title: "Overwrite",
|
|
707
|
+
value: "overwrite"
|
|
708
|
+
}
|
|
709
|
+
]
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
type: (overwrite2) => overwrite2 === "append" ? "multiselect" : null,
|
|
713
|
+
name: "ignoreItems",
|
|
714
|
+
message: "Choose items to append in your .gitignore",
|
|
715
|
+
choices: gitIgnoreItems.map((item) => ({
|
|
716
|
+
title: `${yellow(item.value)}${item.description ? ` - ${item.description}` : ""}${item.isRecommended ? ` ${green("(recommended)")}` : ""}`,
|
|
717
|
+
value: item.value
|
|
718
|
+
}))
|
|
719
|
+
}
|
|
720
|
+
]);
|
|
721
|
+
const { overwrite, ignoreItems } = result;
|
|
722
|
+
if (overwrite === "append" && ignoreItems.length > 0) {
|
|
723
|
+
const gitIgnoreContent = fs.readFileSync(gitIgnorePath, "utf8");
|
|
724
|
+
fs.writeFileSync(
|
|
725
|
+
gitIgnorePath,
|
|
726
|
+
`${gitIgnoreContent}
|
|
727
|
+
${result.ignoreItems.join("\n")}`
|
|
728
|
+
);
|
|
729
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
if (overwrite === "overwrite") {
|
|
733
|
+
fs.writeFileSync(
|
|
734
|
+
gitIgnorePath,
|
|
735
|
+
gitIgnoreItems.map((item) => item.value).join("\n")
|
|
736
|
+
);
|
|
737
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
fs.writeFileSync(
|
|
742
|
+
gitIgnorePath,
|
|
743
|
+
gitIgnoreItems.map((item) => item.value).join("\n")
|
|
744
|
+
);
|
|
745
|
+
consola.success(`Created ${cyan(".gitignore")}`);
|
|
746
|
+
}
|
|
702
747
|
|
|
703
748
|
async function initializeProject({
|
|
704
749
|
argTargetDir,
|
|
@@ -776,36 +821,43 @@ async function initializeProject({
|
|
|
776
821
|
consola$1.info(`Initializing project in ${argTargetDir}
|
|
777
822
|
|
|
778
823
|
`);
|
|
824
|
+
const packageJsonPath = path.join(root, "package.json");
|
|
779
825
|
const packageJson = generatePackageJson(isTs);
|
|
780
826
|
fs.writeFileSync(
|
|
781
|
-
|
|
827
|
+
packageJsonPath,
|
|
782
828
|
JSON.stringify(packageJson, null, 2) + "\n"
|
|
783
829
|
);
|
|
784
|
-
|
|
830
|
+
await formatFile(packageJsonPath);
|
|
831
|
+
consola$1.success("Created", cyan("package.json"));
|
|
785
832
|
if (isTs) {
|
|
833
|
+
const tsConfigPath = path.join(root, "tsconfig.json");
|
|
786
834
|
const tsConfig = generateTsConfig();
|
|
787
|
-
fs.writeFileSync(
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
);
|
|
791
|
-
consola$1.success("Created ", cyan("tsconfig.json"));
|
|
835
|
+
fs.writeFileSync(tsConfigPath, JSON.stringify(tsConfig, null, 2) + "\n");
|
|
836
|
+
await formatFile(tsConfigPath);
|
|
837
|
+
consola$1.success("Created", cyan("tsconfig.json"));
|
|
792
838
|
}
|
|
793
|
-
const
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
);
|
|
798
|
-
|
|
839
|
+
const apibaraConfigPath = path.join(root, `apibara.config.${configExt}`);
|
|
840
|
+
const apibaraConfig = generateApibaraConfig();
|
|
841
|
+
fs.writeFileSync(apibaraConfigPath, apibaraConfig);
|
|
842
|
+
await formatFile(apibaraConfigPath);
|
|
843
|
+
consola$1.success("Created", cyan(`apibara.config.${configExt}`));
|
|
844
|
+
const indexersDir = path.join(root, "indexers");
|
|
845
|
+
if (!fs.existsSync(indexersDir)) {
|
|
846
|
+
fs.mkdirSync(indexersDir, { recursive: true });
|
|
847
|
+
consola$1.success(`Created ${cyan("indexers")} directory`);
|
|
848
|
+
}
|
|
849
|
+
await createGitIgnoreFile(root);
|
|
850
|
+
console.log("\n");
|
|
799
851
|
consola$1.ready(green("Project initialized successfully"));
|
|
800
852
|
console.log();
|
|
801
853
|
if (!argNoCreateIndexer) {
|
|
802
854
|
consola$1.info("Let's create an indexer\n");
|
|
803
|
-
await addIndexer({});
|
|
855
|
+
await addIndexer({ argRootDir: argTargetDir });
|
|
804
856
|
} else {
|
|
805
857
|
const pkgManager = getPackageManager();
|
|
806
858
|
consola$1.info(
|
|
807
859
|
"Run ",
|
|
808
|
-
green(`${pkgManager.name}
|
|
860
|
+
green(`${pkgManager.name} install`),
|
|
809
861
|
" to install all dependencies"
|
|
810
862
|
);
|
|
811
863
|
}
|
|
@@ -816,9 +868,11 @@ async function addIndexer({
|
|
|
816
868
|
argChain,
|
|
817
869
|
argNetwork,
|
|
818
870
|
argStorage,
|
|
819
|
-
argDnaUrl
|
|
871
|
+
argDnaUrl,
|
|
872
|
+
argRootDir
|
|
820
873
|
}) {
|
|
821
|
-
const
|
|
874
|
+
const cwd = path.join(process.cwd(), argRootDir ?? ".");
|
|
875
|
+
const configExists = hasApibaraConfig(cwd);
|
|
822
876
|
if (!configExists) {
|
|
823
877
|
consola$1.error("No apibara.config found in the current directory.");
|
|
824
878
|
const prompt_initialize = await prompts({
|
|
@@ -842,7 +896,7 @@ async function addIndexer({
|
|
|
842
896
|
);
|
|
843
897
|
}
|
|
844
898
|
}
|
|
845
|
-
const language = getApibaraConfigLanguage(
|
|
899
|
+
const language = getApibaraConfigLanguage(cwd);
|
|
846
900
|
validateIndexerId(argIndexerId, true);
|
|
847
901
|
validateChain(argChain, true);
|
|
848
902
|
validateNetwork(argChain, argNetwork, true);
|
|
@@ -855,7 +909,15 @@ async function addIndexer({
|
|
|
855
909
|
name: "prompt_indexerId",
|
|
856
910
|
message: reset("Indexer ID:"),
|
|
857
911
|
initial: argIndexerId ?? "my-indexer",
|
|
858
|
-
validate: (id) => validateIndexerId(id)
|
|
912
|
+
validate: (id) => validateIndexerId(id) ? checkFileExists(
|
|
913
|
+
path.join(
|
|
914
|
+
cwd,
|
|
915
|
+
"indexers",
|
|
916
|
+
`${id}.indexer.${language === "typescript" ? "ts" : "js"}`
|
|
917
|
+
)
|
|
918
|
+
).then(
|
|
919
|
+
({ exists }) => exists ? `Indexer ${cyan(`${id}.indexer.${language === "typescript" ? "ts" : "js"}`)} already exists` : true
|
|
920
|
+
) : "Invalid indexer ID, it cannot be empty and must be in kebab-case format"
|
|
859
921
|
},
|
|
860
922
|
{
|
|
861
923
|
type: argChain ? null : "select",
|
|
@@ -931,7 +993,7 @@ async function addIndexer({
|
|
|
931
993
|
const indexerFileId = argIndexerId ?? prompt_indexerId;
|
|
932
994
|
const pkgManager = getPackageManager();
|
|
933
995
|
const options = {
|
|
934
|
-
cwd
|
|
996
|
+
cwd,
|
|
935
997
|
indexerFileId,
|
|
936
998
|
indexerId: convertKebabToCamelCase(indexerFileId),
|
|
937
999
|
chain: argChain ?? prompt_chain?.name,
|
|
@@ -941,11 +1003,11 @@ async function addIndexer({
|
|
|
941
1003
|
language,
|
|
942
1004
|
packageManager: pkgManager.name
|
|
943
1005
|
};
|
|
944
|
-
updateApibaraConfigFile(options);
|
|
1006
|
+
await updateApibaraConfigFile(options);
|
|
945
1007
|
consola$1.success(
|
|
946
1008
|
`Updated ${cyan("apibara.config." + (language === "typescript" ? "ts" : "js"))}`
|
|
947
1009
|
);
|
|
948
|
-
updatePackageJson(options);
|
|
1010
|
+
await updatePackageJson(options);
|
|
949
1011
|
consola$1.success(`Updated ${cyan("package.json")}`);
|
|
950
1012
|
await createIndexerFile(options);
|
|
951
1013
|
consola$1.success(
|
|
@@ -953,8 +1015,10 @@ async function addIndexer({
|
|
|
953
1015
|
);
|
|
954
1016
|
await createStorageRelatedFiles(options);
|
|
955
1017
|
console.log();
|
|
1018
|
+
const baseCommand = `${options.packageManager} install`;
|
|
1019
|
+
const tsCommand = `${baseCommand} && ${options.packageManager} run prepare`;
|
|
956
1020
|
consola$1.info(
|
|
957
|
-
`Before running the indexer, run ${cyan(
|
|
1021
|
+
`Before running the indexer, run ${cyan(language === "typescript" ? tsCommand : baseCommand)}`
|
|
958
1022
|
);
|
|
959
1023
|
}
|
|
960
1024
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { builtinModules } from 'node:module';
|
|
3
|
+
import defu from 'defu';
|
|
4
|
+
import { join } from 'pathe';
|
|
5
|
+
import virtual from '@rollup/plugin-virtual';
|
|
6
|
+
import { hash } from 'ohash';
|
|
7
|
+
|
|
8
|
+
function appConfig(apibara) {
|
|
9
|
+
return virtual({
|
|
10
|
+
"#apibara-internal-virtual/config": `
|
|
11
|
+
import * as projectConfig from '${apibara.options._c12.configFile}';
|
|
12
|
+
|
|
13
|
+
export const config = projectConfig.default;
|
|
14
|
+
`
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function indexers(apibara) {
|
|
19
|
+
const indexers2 = [...new Set(apibara.indexers)];
|
|
20
|
+
return virtual({
|
|
21
|
+
"#apibara-internal-virtual/indexers": `
|
|
22
|
+
${indexers2.map((i) => `import * as _${hash(i)} from '${i.indexer}';`).join("\n")}
|
|
23
|
+
|
|
24
|
+
export const indexers = [
|
|
25
|
+
${indexers2.map((i) => `{ name: "${i.name}", indexer: _${hash(i)} }`).join(",\n")}
|
|
26
|
+
];
|
|
27
|
+
`
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const runtimeDependencies = [
|
|
32
|
+
"better-sqlite3",
|
|
33
|
+
"@electric-sql/pglite",
|
|
34
|
+
"pg",
|
|
35
|
+
// https://socket.io/docs/v4/server-installation/#additional-packages
|
|
36
|
+
"utf-8-validate",
|
|
37
|
+
"bufferutil",
|
|
38
|
+
"node-fetch"
|
|
39
|
+
];
|
|
40
|
+
function getRolldownConfig(apibara) {
|
|
41
|
+
const extensions = [
|
|
42
|
+
".ts",
|
|
43
|
+
".mjs",
|
|
44
|
+
".js",
|
|
45
|
+
".json",
|
|
46
|
+
".node",
|
|
47
|
+
".tsx",
|
|
48
|
+
".jsx"
|
|
49
|
+
];
|
|
50
|
+
const tsConfigExists = existsSync(
|
|
51
|
+
join(apibara.options.rootDir, "tsconfig.json")
|
|
52
|
+
);
|
|
53
|
+
const rolldownConfig = defu(
|
|
54
|
+
// biome-ignore lint/suspicious/noExplicitAny: apibara.options.rolldownConfig is typed
|
|
55
|
+
apibara.options.rolldownConfig,
|
|
56
|
+
{
|
|
57
|
+
platform: "node",
|
|
58
|
+
input: apibara.options.entry,
|
|
59
|
+
output: {
|
|
60
|
+
dir: join(apibara.options.outputDir || "./.apibara/build"),
|
|
61
|
+
format: "esm",
|
|
62
|
+
entryFileNames: "[name].mjs",
|
|
63
|
+
chunkFileNames: "chunks/[name]-[hash].mjs",
|
|
64
|
+
sourcemap: true
|
|
65
|
+
},
|
|
66
|
+
plugins: [],
|
|
67
|
+
onwarn(warning, rolldownWarn) {
|
|
68
|
+
if (!["CIRCULAR_DEPENDENCY", "EVAL", "THIS_IS_UNDEFINED"].includes(
|
|
69
|
+
warning.code || ""
|
|
70
|
+
) && !warning.message.includes("Unsupported source map comment") && !warning.message.includes("@__PURE__") && !warning.message.includes("/*#__PURE__*/")) {
|
|
71
|
+
rolldownWarn(warning);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
resolve: {
|
|
75
|
+
extensions,
|
|
76
|
+
preferBuiltins: !!apibara.options.node,
|
|
77
|
+
mainFields: ["main"],
|
|
78
|
+
exportConditions: apibara.options.exportConditions,
|
|
79
|
+
tsconfigFilename: tsConfigExists ? "tsconfig.json" : void 0
|
|
80
|
+
},
|
|
81
|
+
treeshake: true,
|
|
82
|
+
external: [...builtinModules, ...runtimeDependencies]
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
rolldownConfig.plugins?.push(indexers(apibara));
|
|
86
|
+
rolldownConfig.plugins?.push(appConfig(apibara));
|
|
87
|
+
return rolldownConfig;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { getRolldownConfig };
|
package/dist/runtime/dev.mjs
CHANGED
|
@@ -33,6 +33,9 @@ const startCommand = defineCommand({
|
|
|
33
33
|
await Promise.all(
|
|
34
34
|
selectedIndexers.map(async (indexer) => {
|
|
35
35
|
const indexerInstance = createIndexer(indexer, preset);
|
|
36
|
+
if (!indexerInstance) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
36
39
|
const client = createClient(
|
|
37
40
|
indexerInstance.streamConfig,
|
|
38
41
|
indexerInstance.options.streamUrl
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const availableIndexers: any;
|
|
2
|
-
export declare function createIndexer(indexerName: string, preset?: string): import("@apibara/indexer").Indexer<unknown, unknown
|
|
2
|
+
export declare function createIndexer(indexerName: string, preset?: string): import("@apibara/indexer").Indexer<unknown, unknown> | undefined;
|