apibara 2.1.0-beta.3 → 2.1.0-beta.31
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 +17 -8
- package/dist/chunks/add.mjs.map +1 -0
- package/dist/chunks/build.mjs +5 -2
- package/dist/chunks/build.mjs.map +1 -0
- package/dist/chunks/dev.mjs +56 -21
- package/dist/chunks/dev.mjs.map +1 -0
- package/dist/chunks/init.mjs +12 -7
- package/dist/chunks/init.mjs.map +1 -0
- package/dist/chunks/prepare.mjs +5 -2
- package/dist/chunks/prepare.mjs.map +1 -0
- package/dist/chunks/start.mjs +16 -11
- package/dist/chunks/start.mjs.map +1 -0
- package/dist/chunks/write-project-info.mjs +51 -0
- package/dist/chunks/write-project-info.mjs.map +1 -0
- package/dist/cli/index.mjs +3 -1
- package/dist/cli/index.mjs.map +1 -0
- package/dist/common/index.d.mts +28 -0
- package/dist/common/index.d.ts +28 -0
- package/dist/common/index.mjs +64 -0
- package/dist/common/index.mjs.map +1 -0
- package/dist/config/index.mjs +1 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/core/index.mjs +133 -68
- package/dist/core/index.mjs.map +1 -0
- package/dist/create/index.d.mts +2 -1
- package/dist/create/index.d.ts +2 -1
- package/dist/create/index.mjs +144 -115
- package/dist/create/index.mjs.map +1 -0
- package/dist/hooks/index.mjs +6 -1
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/indexer/index.d.ts +1 -0
- package/dist/indexer/index.mjs +1 -0
- package/dist/indexer/plugins.d.ts +1 -0
- package/dist/indexer/plugins.mjs +1 -0
- package/dist/indexer/testing.d.ts +1 -0
- package/dist/indexer/testing.mjs +1 -0
- package/dist/indexer/vcr.d.ts +1 -0
- package/dist/indexer/vcr.mjs +1 -0
- package/dist/rolldown/index.d.mts +7 -0
- package/dist/rolldown/index.d.ts +7 -0
- package/dist/rolldown/index.mjs +122 -0
- package/dist/rolldown/index.mjs.map +1 -0
- package/dist/runtime/dev.mjs +23 -10
- package/dist/runtime/internal/app.d.ts +16 -1
- package/dist/runtime/internal/app.mjs +51 -21
- package/dist/runtime/project-info.d.ts +3 -0
- package/dist/runtime/project-info.mjs +67 -0
- package/dist/runtime/start.mjs +27 -10
- package/dist/shared/apibara.63c9a277.mjs +30 -0
- package/dist/shared/apibara.63c9a277.mjs.map +1 -0
- package/dist/shared/apibara.730bb1e4.mjs +18 -0
- package/dist/shared/apibara.730bb1e4.mjs.map +1 -0
- package/dist/types/index.d.mts +24 -20
- package/dist/types/index.d.ts +24 -20
- package/dist/types/index.mjs +1 -0
- package/dist/types/index.mjs.map +1 -0
- package/package.json +33 -16
- package/src/cli/commands/add.ts +16 -7
- package/src/cli/commands/build.ts +5 -2
- package/src/cli/commands/dev.ts +64 -20
- package/src/cli/commands/init.ts +12 -7
- package/src/cli/commands/prepare.ts +4 -2
- package/src/cli/commands/start.ts +17 -10
- 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/common/constants.ts +6 -0
- package/src/common/helper.ts +86 -0
- package/src/common/index.ts +2 -0
- package/src/core/apibara.ts +7 -2
- package/src/core/build/build.ts +13 -5
- package/src/core/build/dev.ts +46 -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 +15 -7
- package/src/core/config/resolvers/runtime.resolver.ts +44 -0
- package/src/core/config/update.ts +6 -2
- package/src/create/add.ts +10 -9
- package/src/create/constants.ts +9 -11
- package/src/create/init.ts +8 -5
- package/src/create/templates.ts +132 -105
- package/src/hooks/useRuntimeConfig.ts +4 -1
- package/src/indexer/index.ts +1 -0
- package/src/indexer/plugins.ts +1 -0
- package/src/indexer/testing.ts +1 -0
- package/src/indexer/vcr.ts +1 -0
- package/src/rolldown/config.ts +84 -0
- package/src/rolldown/index.ts +2 -0
- package/src/{rollup → rolldown}/plugins/indexers.ts +3 -3
- package/src/rolldown/plugins/instrumentation.ts +68 -0
- package/src/runtime/dev.ts +25 -9
- package/src/runtime/internal/app.ts +75 -29
- package/src/runtime/project-info.ts +90 -0
- package/src/runtime/start.ts +30 -9
- package/src/types/config.ts +27 -13
- 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/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/preset.resolver.ts +0 -9
- 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/src/types/virtual/config.d.ts +0 -3
package/src/create/templates.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { consola } from "consola";
|
|
4
|
+
import prompts from "prompts";
|
|
4
5
|
import { type ObjectLiteralExpression, Project, SyntaxKind } from "ts-morph";
|
|
5
6
|
import { cyan, green, magenta, yellow } from "./colors";
|
|
6
7
|
import { packageVersions } from "./constants";
|
|
@@ -14,21 +15,18 @@ export function generatePackageJson(isTypeScript: boolean) {
|
|
|
14
15
|
private: true,
|
|
15
16
|
type: "module",
|
|
16
17
|
scripts: {
|
|
17
|
-
prepare: "apibara prepare",
|
|
18
|
+
...(isTypeScript && { prepare: "apibara prepare" }),
|
|
18
19
|
dev: "apibara dev",
|
|
19
20
|
start: "apibara start",
|
|
20
21
|
build: "apibara build",
|
|
21
22
|
...(isTypeScript && { typecheck: "tsc --noEmit" }),
|
|
22
23
|
},
|
|
23
24
|
dependencies: {
|
|
24
|
-
"@apibara/indexer": packageVersions["@apibara/indexer"],
|
|
25
25
|
"@apibara/protocol": packageVersions["@apibara/protocol"],
|
|
26
26
|
apibara: packageVersions.apibara,
|
|
27
27
|
},
|
|
28
28
|
devDependencies: {
|
|
29
29
|
...(isTypeScript && {
|
|
30
|
-
"@rollup/plugin-typescript":
|
|
31
|
-
packageVersions["@rollup/plugin-typescript"],
|
|
32
30
|
"@types/node": packageVersions["@types/node"],
|
|
33
31
|
typescript: packageVersions.typescript,
|
|
34
32
|
}),
|
|
@@ -58,17 +56,10 @@ export function generateTsConfig() {
|
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
export function generateApibaraConfig(isTypeScript: boolean) {
|
|
61
|
-
return
|
|
59
|
+
return `import { defineConfig } from "apibara/config";
|
|
62
60
|
|
|
63
61
|
export default defineConfig({
|
|
64
|
-
runtimeConfig: {}
|
|
65
|
-
isTypeScript
|
|
66
|
-
? `
|
|
67
|
-
rollupConfig: {
|
|
68
|
-
plugins: [typescript()${isTypeScript ? " as Plugin" : ""}],
|
|
69
|
-
},`
|
|
70
|
-
: ""
|
|
71
|
-
}
|
|
62
|
+
runtimeConfig: {},
|
|
72
63
|
});\n`;
|
|
73
64
|
}
|
|
74
65
|
|
|
@@ -78,9 +69,10 @@ export function generateIndexer({
|
|
|
78
69
|
chain,
|
|
79
70
|
language,
|
|
80
71
|
}: IndexerOptions) {
|
|
81
|
-
return `import { defineIndexer } from "
|
|
82
|
-
import { useLogger } from "
|
|
72
|
+
return `import { defineIndexer } from "apibara/indexer";
|
|
73
|
+
import { useLogger } from "apibara/plugins";
|
|
83
74
|
${storage === "postgres" ? `import { drizzleStorage } from "@apibara/plugin-drizzle";` : ""}
|
|
75
|
+
${storage === "postgres" ? `import { drizzle } from "@apibara/plugin-drizzle";` : ""}
|
|
84
76
|
${
|
|
85
77
|
chain === "ethereum"
|
|
86
78
|
? `import { EvmStream } from "@apibara/evm";`
|
|
@@ -91,19 +83,17 @@ ${
|
|
|
91
83
|
: ""
|
|
92
84
|
}
|
|
93
85
|
${language === "typescript" ? `import type { ApibaraRuntimeConfig } from "apibara/types";` : ""}
|
|
94
|
-
${
|
|
95
|
-
storage === "postgres"
|
|
96
|
-
? `import { getDrizzlePgDatabase } from "../lib/db";`
|
|
97
|
-
: ""
|
|
98
|
-
}
|
|
86
|
+
${storage === "postgres" ? `import * as schema from "../lib/schema";` : ""}
|
|
99
87
|
|
|
100
88
|
|
|
101
89
|
export default function (runtimeConfig${language === "typescript" ? ": ApibaraRuntimeConfig" : ""}) {
|
|
102
90
|
const indexerId = "${indexerId}";
|
|
103
|
-
const { startingBlock, streamUrl
|
|
91
|
+
const { startingBlock, streamUrl } = runtimeConfig[indexerId];
|
|
104
92
|
${
|
|
105
93
|
storage === "postgres"
|
|
106
|
-
?
|
|
94
|
+
? `const db = drizzle({
|
|
95
|
+
schema,
|
|
96
|
+
});`
|
|
107
97
|
: ""
|
|
108
98
|
}
|
|
109
99
|
|
|
@@ -122,7 +112,7 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
122
112
|
filter: {
|
|
123
113
|
header: "always",
|
|
124
114
|
},
|
|
125
|
-
plugins: [${storage === "postgres" ? "drizzleStorage({ db,
|
|
115
|
+
plugins: [${storage === "postgres" ? "drizzleStorage({ db, migrate: { migrationsFolder: './drizzle' } })" : ""}],
|
|
126
116
|
async transform({ endCursor, finality }) {
|
|
127
117
|
const logger = useLogger();
|
|
128
118
|
|
|
@@ -136,14 +126,12 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
136
126
|
${
|
|
137
127
|
storage === "postgres"
|
|
138
128
|
? `// Example snippet to insert data into db using drizzle with postgres
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
// });
|
|
146
|
-
// }`
|
|
129
|
+
// const { db: database } = useDrizzleStorage();
|
|
130
|
+
|
|
131
|
+
// await database.insert(schema.cursorTable).values({
|
|
132
|
+
// endCursor: Number(endCursor?.orderKey),
|
|
133
|
+
// uniqueKey: \`\${endCursor?.uniqueKey}\`,
|
|
134
|
+
// });`
|
|
147
135
|
: ""
|
|
148
136
|
}
|
|
149
137
|
},
|
|
@@ -235,12 +223,8 @@ export async function updateApibaraConfigFile({
|
|
|
235
223
|
|
|
236
224
|
const runtimeConfigString = `{
|
|
237
225
|
startingBlock: 0,
|
|
238
|
-
streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
|
|
239
|
-
|
|
240
|
-
? `,
|
|
241
|
-
postgresConnectionString: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}"`
|
|
242
|
-
: ""
|
|
243
|
-
}}`;
|
|
226
|
+
streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
|
|
227
|
+
}`;
|
|
244
228
|
|
|
245
229
|
const project = new Project();
|
|
246
230
|
const sourceFile = project.addSourceFileAtPath(pathToConfig);
|
|
@@ -284,7 +268,7 @@ export async function updateApibaraConfigFile({
|
|
|
284
268
|
}
|
|
285
269
|
|
|
286
270
|
export async function createDrizzleStorageFiles(options: IndexerOptions) {
|
|
287
|
-
const { cwd, language, storage } = options;
|
|
271
|
+
const { cwd, language, storage, indexerId } = options;
|
|
288
272
|
|
|
289
273
|
if (storage !== "postgres") return;
|
|
290
274
|
|
|
@@ -312,11 +296,11 @@ export async function createDrizzleStorageFiles(options: IndexerOptions) {
|
|
|
312
296
|
const drizzleConfigContent = `${language === "typescript" ? 'import type { Config } from "drizzle-kit";' : ""}
|
|
313
297
|
|
|
314
298
|
export default {
|
|
315
|
-
schema: "./lib/schema
|
|
299
|
+
schema: "./lib/schema.${fileExtension}",
|
|
316
300
|
out: "./drizzle",
|
|
317
301
|
dialect: "postgresql",
|
|
318
302
|
dbCredentials: {
|
|
319
|
-
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "",
|
|
303
|
+
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}",
|
|
320
304
|
},
|
|
321
305
|
}${language === "typescript" ? " satisfies Config" : ""};`;
|
|
322
306
|
|
|
@@ -347,14 +331,14 @@ export default {
|
|
|
347
331
|
});
|
|
348
332
|
|
|
349
333
|
if (!schemaExists || schemaOverwrite) {
|
|
350
|
-
const schemaContent = `// --- Add your pg table schemas here ----
|
|
334
|
+
const schemaContent = `// --- Add your pg table schemas here ----
|
|
351
335
|
|
|
352
336
|
// import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
353
337
|
|
|
354
|
-
// export const
|
|
338
|
+
// export const cursorTable = pgTable("cursor_table", {
|
|
355
339
|
// id: uuid("id").primaryKey().defaultRandom(),
|
|
356
|
-
//
|
|
357
|
-
//
|
|
340
|
+
// endCursor: bigint("end_cursor", { mode: "number" }),
|
|
341
|
+
// uniqueKey: text("unique_key"),
|
|
358
342
|
// });
|
|
359
343
|
|
|
360
344
|
export {};
|
|
@@ -369,63 +353,6 @@ export {};
|
|
|
369
353
|
consola.success(`Created ${cyan("lib/schema.ts")}`);
|
|
370
354
|
}
|
|
371
355
|
|
|
372
|
-
/**
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
* DB File
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*/
|
|
379
|
-
const dbFileName = `db.${fileExtension}`;
|
|
380
|
-
|
|
381
|
-
const dbPath = path.join(cwd, "lib", dbFileName);
|
|
382
|
-
|
|
383
|
-
const { exists: dbExists, overwrite: dbOverwrite } = await checkFileExists(
|
|
384
|
-
dbPath,
|
|
385
|
-
{
|
|
386
|
-
askPrompt: true,
|
|
387
|
-
fileName: `lib/${dbFileName}`,
|
|
388
|
-
allowIgnore: true,
|
|
389
|
-
},
|
|
390
|
-
);
|
|
391
|
-
|
|
392
|
-
if (!dbExists || dbOverwrite) {
|
|
393
|
-
const dbContent = `import * as schema from "./schema";
|
|
394
|
-
import { drizzle as nodePgDrizzle } from "drizzle-orm/node-postgres";
|
|
395
|
-
import { drizzle as pgLiteDrizzle } from "drizzle-orm/pglite";
|
|
396
|
-
import pg from "pg";
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
export function getDrizzlePgDatabase(connectionString${language === "typescript" ? ": string" : ""}) {
|
|
400
|
-
// Create pglite instance
|
|
401
|
-
if (connectionString.includes("memory")) {
|
|
402
|
-
return {
|
|
403
|
-
db: pgLiteDrizzle({
|
|
404
|
-
schema,
|
|
405
|
-
connection: {
|
|
406
|
-
dataDir: connectionString,
|
|
407
|
-
},
|
|
408
|
-
}),
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Create node-postgres instance
|
|
413
|
-
const pool = new pg.Pool({
|
|
414
|
-
connectionString,
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
return { db: nodePgDrizzle(pool, { schema }) };
|
|
418
|
-
}`;
|
|
419
|
-
|
|
420
|
-
// create directory if it doesn't exist
|
|
421
|
-
fs.mkdirSync(path.dirname(dbPath), { recursive: true });
|
|
422
|
-
fs.writeFileSync(dbPath, dbContent);
|
|
423
|
-
|
|
424
|
-
await formatFile(dbPath);
|
|
425
|
-
|
|
426
|
-
consola.success(`Created ${cyan(`lib/${dbFileName}`)}`);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
356
|
console.log("\n");
|
|
430
357
|
|
|
431
358
|
// If schema file is created, show the example
|
|
@@ -445,17 +372,17 @@ ${yellow(`
|
|
|
445
372
|
|
|
446
373
|
import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
447
374
|
|
|
448
|
-
export const
|
|
375
|
+
export const cursorTable = pgTable("cursor_table", {
|
|
449
376
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
450
|
-
|
|
451
|
-
|
|
377
|
+
endCursor: bigint("end_cursor", { mode: "number" }),
|
|
378
|
+
uniqueKey: text("unique_key"),
|
|
452
379
|
});`)}`);
|
|
453
380
|
|
|
454
381
|
console.log("\n");
|
|
455
382
|
}
|
|
456
383
|
|
|
457
384
|
consola.info(
|
|
458
|
-
`Run ${green(`${options.packageManager} run drizzle:generate`)} & ${green(`${options.packageManager} run drizzle:migrate`)} to generate and apply migrations.`,
|
|
385
|
+
`Run ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:generate`)} & ${green(`${options.packageManager}${options.packageManager === "npm" ? " run" : ""} drizzle:migrate`)} to generate and apply migrations.`,
|
|
459
386
|
);
|
|
460
387
|
}
|
|
461
388
|
|
|
@@ -466,3 +393,103 @@ export async function createStorageRelatedFiles(options: IndexerOptions) {
|
|
|
466
393
|
await createDrizzleStorageFiles(options);
|
|
467
394
|
}
|
|
468
395
|
}
|
|
396
|
+
|
|
397
|
+
const gitIgnoreItems: {
|
|
398
|
+
isRecommended: boolean;
|
|
399
|
+
description?: string;
|
|
400
|
+
value: string;
|
|
401
|
+
}[] = [
|
|
402
|
+
{
|
|
403
|
+
isRecommended: false,
|
|
404
|
+
value: "node_modules",
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
isRecommended: false,
|
|
408
|
+
value: "dist",
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
isRecommended: true,
|
|
412
|
+
description: "build and dev files of apibara",
|
|
413
|
+
value: ".apibara",
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
isRecommended: false,
|
|
417
|
+
value: ".env",
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
isRecommended: false,
|
|
421
|
+
description: "for mac users",
|
|
422
|
+
value: ".DS_Store",
|
|
423
|
+
},
|
|
424
|
+
];
|
|
425
|
+
|
|
426
|
+
export async function createGitIgnoreFile(cwd: string) {
|
|
427
|
+
const gitIgnorePath = path.join(cwd, ".gitignore");
|
|
428
|
+
|
|
429
|
+
if (fs.existsSync(gitIgnorePath)) {
|
|
430
|
+
const result = await prompts([
|
|
431
|
+
{
|
|
432
|
+
type: "select",
|
|
433
|
+
name: "overwrite",
|
|
434
|
+
message: `${cyan(".gitignore")} already exists. Please choose how to proceed:`,
|
|
435
|
+
initial: 0,
|
|
436
|
+
choices: [
|
|
437
|
+
{
|
|
438
|
+
title: "Choose items to append in your .gitignore",
|
|
439
|
+
value: "append",
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
title: "Keep original",
|
|
443
|
+
value: "ignore",
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
title: "Overwrite",
|
|
447
|
+
value: "overwrite",
|
|
448
|
+
},
|
|
449
|
+
],
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
type: (overwrite: "append" | "ignore" | "overwrite") =>
|
|
453
|
+
overwrite === "append" ? "multiselect" : null,
|
|
454
|
+
name: "ignoreItems",
|
|
455
|
+
message: "Choose items to append in your .gitignore",
|
|
456
|
+
choices: gitIgnoreItems.map((item) => ({
|
|
457
|
+
title: `${yellow(item.value)}${
|
|
458
|
+
item.description ? ` - ${item.description}` : ""
|
|
459
|
+
}${item.isRecommended ? ` ${green("(recommended)")}` : ""}`,
|
|
460
|
+
value: item.value,
|
|
461
|
+
})),
|
|
462
|
+
},
|
|
463
|
+
]);
|
|
464
|
+
|
|
465
|
+
const { overwrite, ignoreItems } = result as {
|
|
466
|
+
overwrite: "append" | "ignore" | "overwrite";
|
|
467
|
+
ignoreItems: string[];
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
if (overwrite === "append" && ignoreItems.length > 0) {
|
|
471
|
+
const gitIgnoreContent = fs.readFileSync(gitIgnorePath, "utf8");
|
|
472
|
+
fs.writeFileSync(
|
|
473
|
+
gitIgnorePath,
|
|
474
|
+
`${gitIgnoreContent}\n${result.ignoreItems.join("\n")}`,
|
|
475
|
+
);
|
|
476
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (overwrite === "overwrite") {
|
|
481
|
+
fs.writeFileSync(
|
|
482
|
+
gitIgnorePath,
|
|
483
|
+
gitIgnoreItems.map((item) => item.value).join("\n"),
|
|
484
|
+
);
|
|
485
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
fs.writeFileSync(
|
|
491
|
+
gitIgnorePath,
|
|
492
|
+
gitIgnoreItems.map((item) => item.value).join("\n"),
|
|
493
|
+
);
|
|
494
|
+
consola.success(`Created ${cyan(".gitignore")}`);
|
|
495
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { ENV_INTERNAL_APIBARA_PROCESSED_RUNTIME } from "apibara/common";
|
|
1
2
|
import type { ApibaraRuntimeConfig } from "apibara/types";
|
|
2
3
|
|
|
3
4
|
export function useRuntimeConfig(): ApibaraRuntimeConfig {
|
|
4
|
-
return JSON.parse(
|
|
5
|
+
return JSON.parse(
|
|
6
|
+
process.env[ENV_INTERNAL_APIBARA_PROCESSED_RUNTIME] || "{}",
|
|
7
|
+
);
|
|
5
8
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@apibara/indexer";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@apibara/indexer/plugins";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@apibara/indexer/testing";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@apibara/indexer/vcr";
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { builtinModules } from "node:module";
|
|
3
|
+
import type { Apibara } from "apibara/types";
|
|
4
|
+
import defu from "defu";
|
|
5
|
+
import { join } from "pathe";
|
|
6
|
+
import type {
|
|
7
|
+
ConfigExport,
|
|
8
|
+
RolldownOptions,
|
|
9
|
+
RolldownPluginOption,
|
|
10
|
+
} from "rolldown";
|
|
11
|
+
import { indexers } from "./plugins/indexers";
|
|
12
|
+
import { instrumentation } from "./plugins/instrumentation";
|
|
13
|
+
|
|
14
|
+
const runtimeDependencies = [
|
|
15
|
+
"better-sqlite3",
|
|
16
|
+
"@electric-sql/pglite",
|
|
17
|
+
"pg",
|
|
18
|
+
// https://socket.io/docs/v4/server-installation/#additional-packages
|
|
19
|
+
"utf-8-validate",
|
|
20
|
+
"bufferutil",
|
|
21
|
+
// was giving unresolved import warnings from `node-fetch` library.
|
|
22
|
+
"encoding",
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
export function getRolldownConfig(apibara: Apibara): RolldownOptions {
|
|
26
|
+
const extensions: string[] = [
|
|
27
|
+
".ts",
|
|
28
|
+
".mjs",
|
|
29
|
+
".js",
|
|
30
|
+
".json",
|
|
31
|
+
".node",
|
|
32
|
+
".tsx",
|
|
33
|
+
".jsx",
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const tsConfigExists = existsSync(
|
|
37
|
+
join(apibara.options.rootDir, "tsconfig.json"),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const rolldownConfig: RolldownOptions & {
|
|
41
|
+
plugins: RolldownPluginOption[];
|
|
42
|
+
} = defu(
|
|
43
|
+
// biome-ignore lint/suspicious/noExplicitAny: apibara.options.rolldownConfig is typed
|
|
44
|
+
apibara.options.rolldownConfig as any,
|
|
45
|
+
<ConfigExport>{
|
|
46
|
+
platform: "node",
|
|
47
|
+
input: apibara.options.entry,
|
|
48
|
+
output: {
|
|
49
|
+
dir: join(apibara.options.outputDir || "./.apibara/build"),
|
|
50
|
+
format: "esm",
|
|
51
|
+
entryFileNames: "[name].mjs",
|
|
52
|
+
chunkFileNames: "chunks/[name]-[hash].mjs",
|
|
53
|
+
sourcemap: true,
|
|
54
|
+
},
|
|
55
|
+
plugins: [],
|
|
56
|
+
onwarn(warning, rolldownWarn) {
|
|
57
|
+
if (
|
|
58
|
+
!["CIRCULAR_DEPENDENCY", "EVAL", "THIS_IS_UNDEFINED"].includes(
|
|
59
|
+
warning.code || "",
|
|
60
|
+
) &&
|
|
61
|
+
!warning.message.includes("Unsupported source map comment") &&
|
|
62
|
+
!warning.message.includes("@__PURE__") &&
|
|
63
|
+
!warning.message.includes("/*#__PURE__*/")
|
|
64
|
+
) {
|
|
65
|
+
rolldownWarn(warning);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
resolve: {
|
|
69
|
+
extensions,
|
|
70
|
+
preferBuiltins: !!apibara.options.node,
|
|
71
|
+
mainFields: ["main"],
|
|
72
|
+
exportConditions: apibara.options.exportConditions,
|
|
73
|
+
tsconfigFilename: tsConfigExists ? "tsconfig.json" : undefined,
|
|
74
|
+
},
|
|
75
|
+
treeshake: true,
|
|
76
|
+
external: [...builtinModules, ...runtimeDependencies],
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
rolldownConfig.plugins?.push(instrumentation(apibara));
|
|
81
|
+
rolldownConfig.plugins?.push(indexers(apibara));
|
|
82
|
+
|
|
83
|
+
return rolldownConfig;
|
|
84
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import virtual from "@rollup/plugin-virtual";
|
|
2
2
|
import type { Apibara } from "apibara/types";
|
|
3
3
|
import { hash } from "ohash";
|
|
4
|
+
import type { RolldownPluginOption } from "rolldown";
|
|
4
5
|
|
|
5
6
|
export function indexers(apibara: Apibara) {
|
|
6
7
|
const indexers = [...new Set(apibara.indexers)];
|
|
7
|
-
|
|
8
8
|
return virtual({
|
|
9
9
|
"#apibara-internal-virtual/indexers": `
|
|
10
|
-
${indexers.map((i) => `import _${hash(i)} from '${i.indexer}';`).join("\n")}
|
|
10
|
+
${indexers.map((i) => `import * as _${hash(i)} from '${i.indexer}';`).join("\n")}
|
|
11
11
|
|
|
12
12
|
export const indexers = [
|
|
13
13
|
${indexers.map((i) => `{ name: "${i.name}", indexer: _${hash(i)} }`).join(",\n")}
|
|
14
14
|
];
|
|
15
15
|
`,
|
|
16
|
-
});
|
|
16
|
+
}) as RolldownPluginOption;
|
|
17
17
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import virtual from "@rollup/plugin-virtual";
|
|
4
|
+
import type { Apibara } from "apibara/types";
|
|
5
|
+
import type { RolldownPluginOption } from "rolldown";
|
|
6
|
+
|
|
7
|
+
export function instrumentation(apibara: Apibara) {
|
|
8
|
+
const instrumentationPath = join(
|
|
9
|
+
apibara.options._c12.cwd!,
|
|
10
|
+
`instrumentation.${apibara.options._c12.configFile?.endsWith(".ts") ? "ts" : "js"}`,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
if (!existsSync(instrumentationPath)) {
|
|
14
|
+
return virtual({
|
|
15
|
+
"#apibara-internal-virtual/instrumentation": `
|
|
16
|
+
let register = undefined;
|
|
17
|
+
let logger = undefined;
|
|
18
|
+
|
|
19
|
+
export { register, logger };
|
|
20
|
+
`,
|
|
21
|
+
}) as RolldownPluginOption;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* We are importing the instrumentation file inline with "require" instead of "import" at the top of the file to avoid warnings from rolldown
|
|
26
|
+
* when some methods are not defined in the instrumentation file.
|
|
27
|
+
*
|
|
28
|
+
* Example warning:
|
|
29
|
+
*
|
|
30
|
+
* [IMPORT_IS_UNDEFINED] Warning: Import `logger` will always be undefined because there is no matching export in 'instrumentation.ts'
|
|
31
|
+
* ╭─[virtual:#apibara-internal-virtual/instrumentation:11:35]
|
|
32
|
+
* │
|
|
33
|
+
* 11 │ if (instrumentation && typeof instrumentation.logger === "function") {
|
|
34
|
+
* │ ───────────┬──────────
|
|
35
|
+
* │ ╰────────────
|
|
36
|
+
* ────╯
|
|
37
|
+
|
|
38
|
+
* [IMPORT_IS_UNDEFINED] Warning: Import `logger` will always be undefined because there is no matching export in 'instrumentation.ts'
|
|
39
|
+
* ╭─[virtual:#apibara-internal-virtual/instrumentation:12:16]
|
|
40
|
+
* │
|
|
41
|
+
* 12 │ logger = instrumentation.logger;
|
|
42
|
+
* │ ───────────┬──────────
|
|
43
|
+
* │ ╰────────────
|
|
44
|
+
* ────╯
|
|
45
|
+
*/
|
|
46
|
+
return virtual({
|
|
47
|
+
"#apibara-internal-virtual/instrumentation": `
|
|
48
|
+
let register = undefined;
|
|
49
|
+
let logger = undefined;
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const instrumentation = require('${instrumentationPath}');
|
|
53
|
+
|
|
54
|
+
if (instrumentation?.register && typeof instrumentation.register === "function") {
|
|
55
|
+
register = instrumentation.register;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (instrumentation?.logger && typeof instrumentation.logger === "function") {
|
|
59
|
+
logger = instrumentation.logger;
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
// Silently handle any require errors
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { register, logger };
|
|
66
|
+
`,
|
|
67
|
+
}) as RolldownPluginOption;
|
|
68
|
+
}
|
package/src/runtime/dev.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { runWithReconnect } from "@apibara/indexer";
|
|
2
|
-
import {
|
|
2
|
+
import { getRuntimeDataFromEnv } from "apibara/common";
|
|
3
3
|
import { defineCommand, runMain } from "citty";
|
|
4
|
-
import {
|
|
4
|
+
import { blueBright } from "picocolors";
|
|
5
|
+
import {
|
|
6
|
+
availableIndexers,
|
|
7
|
+
createAuthenticatedClient,
|
|
8
|
+
createIndexer,
|
|
9
|
+
} from "./internal/app";
|
|
5
10
|
|
|
6
11
|
const startCommand = defineCommand({
|
|
7
12
|
meta: {
|
|
@@ -13,13 +18,11 @@ const startCommand = defineCommand({
|
|
|
13
18
|
type: "string",
|
|
14
19
|
description: "Which indexers to run",
|
|
15
20
|
},
|
|
16
|
-
preset: {
|
|
17
|
-
type: "string",
|
|
18
|
-
description: "Preset to use",
|
|
19
|
-
},
|
|
20
21
|
},
|
|
21
22
|
async run({ args }) {
|
|
22
|
-
const { indexers: indexersArgs
|
|
23
|
+
const { indexers: indexersArgs } = args;
|
|
24
|
+
|
|
25
|
+
const { processedRuntimeConfig, preset } = getRuntimeDataFromEnv();
|
|
23
26
|
|
|
24
27
|
let selectedIndexers = availableIndexers;
|
|
25
28
|
if (indexersArgs) {
|
|
@@ -36,13 +39,26 @@ const startCommand = defineCommand({
|
|
|
36
39
|
|
|
37
40
|
await Promise.all(
|
|
38
41
|
selectedIndexers.map(async (indexer) => {
|
|
39
|
-
const
|
|
42
|
+
const { indexer: indexerInstance, logger } =
|
|
43
|
+
createIndexer({
|
|
44
|
+
indexerName: indexer,
|
|
45
|
+
processedRuntimeConfig,
|
|
46
|
+
preset,
|
|
47
|
+
}) ?? {};
|
|
48
|
+
if (!indexerInstance) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
40
51
|
|
|
41
|
-
const client =
|
|
52
|
+
const client = createAuthenticatedClient(
|
|
42
53
|
indexerInstance.streamConfig,
|
|
43
54
|
indexerInstance.options.streamUrl,
|
|
55
|
+
indexerInstance.options.clientOptions,
|
|
44
56
|
);
|
|
45
57
|
|
|
58
|
+
if (logger) {
|
|
59
|
+
logger.info(`Indexer ${blueBright(indexer)} started`);
|
|
60
|
+
}
|
|
61
|
+
|
|
46
62
|
await runWithReconnect(client, indexerInstance);
|
|
47
63
|
}),
|
|
48
64
|
);
|