apibara 2.1.0-beta.4 → 2.1.0-beta.41
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/add.mjs.map +1 -0
- package/dist/chunks/build.mjs +4 -2
- package/dist/chunks/build.mjs.map +1 -0
- package/dist/chunks/dev.mjs +55 -21
- package/dist/chunks/dev.mjs.map +1 -0
- package/dist/chunks/init.mjs +11 -7
- package/dist/chunks/init.mjs.map +1 -0
- package/dist/chunks/prepare.mjs +4 -2
- package/dist/chunks/prepare.mjs.map +1 -0
- package/dist/chunks/start.mjs +16 -4
- 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 +33 -0
- package/dist/common/index.d.ts +33 -0
- package/dist/common/index.mjs +91 -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 +134 -69
- 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 +168 -139
- 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 +141 -0
- package/dist/rolldown/index.mjs.map +1 -0
- package/dist/runtime/dev.mjs +39 -17
- package/dist/runtime/internal/app.d.ts +14 -1
- package/dist/runtime/internal/app.mjs +26 -21
- package/dist/runtime/project-info.d.ts +3 -0
- package/dist/runtime/project-info.mjs +67 -0
- package/dist/runtime/start.mjs +78 -11
- 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 -3
- package/src/cli/commands/start.ts +18 -3
- package/src/cli/commands/write-project-info.ts +56 -0
- package/src/cli/index.ts +2 -0
- package/src/common/cli.ts +40 -0
- package/src/common/constants.ts +6 -0
- package/src/common/helper.ts +86 -0
- package/src/common/index.ts +3 -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/core/scan.ts +1 -1
- package/src/create/add.ts +14 -20
- package/src/create/constants.ts +5 -7
- package/src/create/init.ts +8 -5
- package/src/create/templates.ts +144 -116
- package/src/create/types.ts +3 -0
- package/src/create/utils.ts +20 -7
- 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 +86 -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/rolldown/plugins/static-config.ts +21 -0
- package/src/runtime/dev.ts +49 -19
- package/src/runtime/internal/app.ts +42 -29
- package/src/runtime/project-info.ts +90 -0
- package/src/runtime/start.ts +91 -11
- 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/src/types/virtual/static-config.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/cli/common.ts +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,16 @@ ${
|
|
|
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
|
-
const
|
|
103
|
-
const { startingBlock, streamUrl${storage === "postgres" ? ", postgresConnectionString" : ""} } = runtimeConfig[indexerId];
|
|
90
|
+
const { startingBlock, streamUrl } = runtimeConfig["${indexerId}"];
|
|
104
91
|
${
|
|
105
92
|
storage === "postgres"
|
|
106
|
-
?
|
|
93
|
+
? `const db = drizzle({
|
|
94
|
+
schema,
|
|
95
|
+
});`
|
|
107
96
|
: ""
|
|
108
97
|
}
|
|
109
98
|
|
|
@@ -120,9 +109,9 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
120
109
|
finality: "accepted",
|
|
121
110
|
startingBlock: BigInt(startingBlock),
|
|
122
111
|
filter: {
|
|
123
|
-
|
|
112
|
+
${chain === "ethereum" ? "logs: []," : chain === "starknet" ? "events: []," : ""}
|
|
124
113
|
},
|
|
125
|
-
plugins: [${storage === "postgres" ? "drizzleStorage({ db,
|
|
114
|
+
plugins: [${storage === "postgres" ? "drizzleStorage({ db, migrate: { migrationsFolder: './drizzle' } })" : ""}],
|
|
126
115
|
async transform({ endCursor, finality }) {
|
|
127
116
|
const logger = useLogger();
|
|
128
117
|
|
|
@@ -136,14 +125,12 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
136
125
|
${
|
|
137
126
|
storage === "postgres"
|
|
138
127
|
? `// Example snippet to insert data into db using drizzle with postgres
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
// });
|
|
146
|
-
// }`
|
|
128
|
+
// const { db: database } = useDrizzleStorage();
|
|
129
|
+
|
|
130
|
+
// await database.insert(schema.cursorTable).values({
|
|
131
|
+
// endCursor: Number(endCursor?.orderKey),
|
|
132
|
+
// uniqueKey: \`\${endCursor?.uniqueKey}\`,
|
|
133
|
+
// });`
|
|
147
134
|
: ""
|
|
148
135
|
}
|
|
149
136
|
},
|
|
@@ -156,7 +143,7 @@ export async function createIndexerFile(options: IndexerOptions) {
|
|
|
156
143
|
const indexerFilePath = path.join(
|
|
157
144
|
options.cwd,
|
|
158
145
|
"indexers",
|
|
159
|
-
`${options.indexerFileId}.indexer.${options.
|
|
146
|
+
`${options.indexerFileId}.indexer.${options.extension}`,
|
|
160
147
|
);
|
|
161
148
|
|
|
162
149
|
const { exists, overwrite } = await checkFileExists(indexerFilePath, {
|
|
@@ -227,20 +214,14 @@ export async function updateApibaraConfigFile({
|
|
|
227
214
|
language,
|
|
228
215
|
network,
|
|
229
216
|
dnaUrl,
|
|
217
|
+
extension,
|
|
230
218
|
}: IndexerOptions) {
|
|
231
|
-
const pathToConfig = path.join(
|
|
232
|
-
cwd,
|
|
233
|
-
`apibara.config.${language === "typescript" ? "ts" : "js"}`,
|
|
234
|
-
);
|
|
219
|
+
const pathToConfig = path.join(cwd, `apibara.config.${extension}`);
|
|
235
220
|
|
|
236
221
|
const runtimeConfigString = `{
|
|
237
222
|
startingBlock: 0,
|
|
238
|
-
streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
|
|
239
|
-
|
|
240
|
-
? `,
|
|
241
|
-
postgresConnectionString: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}"`
|
|
242
|
-
: ""
|
|
243
|
-
}}`;
|
|
223
|
+
streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
|
|
224
|
+
}`;
|
|
244
225
|
|
|
245
226
|
const project = new Project();
|
|
246
227
|
const sourceFile = project.addSourceFileAtPath(pathToConfig);
|
|
@@ -284,12 +265,16 @@ export async function updateApibaraConfigFile({
|
|
|
284
265
|
}
|
|
285
266
|
|
|
286
267
|
export async function createDrizzleStorageFiles(options: IndexerOptions) {
|
|
287
|
-
const {
|
|
268
|
+
const {
|
|
269
|
+
cwd,
|
|
270
|
+
language,
|
|
271
|
+
storage,
|
|
272
|
+
indexerId,
|
|
273
|
+
extension: fileExtension,
|
|
274
|
+
} = options;
|
|
288
275
|
|
|
289
276
|
if (storage !== "postgres") return;
|
|
290
277
|
|
|
291
|
-
const fileExtension = language === "typescript" ? "ts" : "js";
|
|
292
|
-
|
|
293
278
|
/**
|
|
294
279
|
*
|
|
295
280
|
*
|
|
@@ -312,11 +297,11 @@ export async function createDrizzleStorageFiles(options: IndexerOptions) {
|
|
|
312
297
|
const drizzleConfigContent = `${language === "typescript" ? 'import type { Config } from "drizzle-kit";' : ""}
|
|
313
298
|
|
|
314
299
|
export default {
|
|
315
|
-
schema: "./lib/schema
|
|
300
|
+
schema: "./lib/schema.${fileExtension}",
|
|
316
301
|
out: "./drizzle",
|
|
317
302
|
dialect: "postgresql",
|
|
318
303
|
dbCredentials: {
|
|
319
|
-
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "",
|
|
304
|
+
url: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}",
|
|
320
305
|
},
|
|
321
306
|
}${language === "typescript" ? " satisfies Config" : ""};`;
|
|
322
307
|
|
|
@@ -347,14 +332,14 @@ export default {
|
|
|
347
332
|
});
|
|
348
333
|
|
|
349
334
|
if (!schemaExists || schemaOverwrite) {
|
|
350
|
-
const schemaContent = `// --- Add your pg table schemas here ----
|
|
335
|
+
const schemaContent = `// --- Add your pg table schemas here ----
|
|
351
336
|
|
|
352
337
|
// import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
353
338
|
|
|
354
|
-
// export const
|
|
339
|
+
// export const cursorTable = pgTable("cursor_table", {
|
|
355
340
|
// id: uuid("id").primaryKey().defaultRandom(),
|
|
356
|
-
//
|
|
357
|
-
//
|
|
341
|
+
// endCursor: bigint("end_cursor", { mode: "number" }),
|
|
342
|
+
// uniqueKey: text("unique_key"),
|
|
358
343
|
// });
|
|
359
344
|
|
|
360
345
|
export {};
|
|
@@ -366,64 +351,7 @@ export {};
|
|
|
366
351
|
|
|
367
352
|
await formatFile(schemaPath);
|
|
368
353
|
|
|
369
|
-
consola.success(`Created ${cyan(
|
|
370
|
-
}
|
|
371
|
-
|
|
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}`)}`);
|
|
354
|
+
consola.success(`Created ${cyan(`lib/${schemaFileName}`)}`);
|
|
427
355
|
}
|
|
428
356
|
|
|
429
357
|
console.log("\n");
|
|
@@ -440,22 +368,22 @@ export function getDrizzlePgDatabase(connectionString${language === "typescript"
|
|
|
440
368
|
|
|
441
369
|
${yellow(`
|
|
442
370
|
┌──────────────────────────────────────────┐
|
|
443
|
-
│ lib/schema
|
|
371
|
+
│ lib/schema │
|
|
444
372
|
└──────────────────────────────────────────┘
|
|
445
373
|
|
|
446
374
|
import { bigint, pgTable, text, uuid } from "drizzle-orm/pg-core";
|
|
447
375
|
|
|
448
|
-
export const
|
|
376
|
+
export const cursorTable = pgTable("cursor_table", {
|
|
449
377
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
450
|
-
|
|
451
|
-
|
|
378
|
+
endCursor: bigint("end_cursor", { mode: "number" }),
|
|
379
|
+
uniqueKey: text("unique_key"),
|
|
452
380
|
});`)}`);
|
|
453
381
|
|
|
454
382
|
console.log("\n");
|
|
455
383
|
}
|
|
456
384
|
|
|
457
385
|
consola.info(
|
|
458
|
-
`Run ${green(`${options.packageManager} run drizzle:generate`)} & ${green(`${options.packageManager} run drizzle:migrate`)} to generate and apply migrations.`,
|
|
386
|
+
`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
387
|
);
|
|
460
388
|
}
|
|
461
389
|
|
|
@@ -466,3 +394,103 @@ export async function createStorageRelatedFiles(options: IndexerOptions) {
|
|
|
466
394
|
await createDrizzleStorageFiles(options);
|
|
467
395
|
}
|
|
468
396
|
}
|
|
397
|
+
|
|
398
|
+
const gitIgnoreItems: {
|
|
399
|
+
isRecommended: boolean;
|
|
400
|
+
description?: string;
|
|
401
|
+
value: string;
|
|
402
|
+
}[] = [
|
|
403
|
+
{
|
|
404
|
+
isRecommended: false,
|
|
405
|
+
value: "node_modules",
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
isRecommended: false,
|
|
409
|
+
value: "dist",
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
isRecommended: true,
|
|
413
|
+
description: "build and dev files of apibara",
|
|
414
|
+
value: ".apibara",
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
isRecommended: false,
|
|
418
|
+
value: ".env",
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
isRecommended: false,
|
|
422
|
+
description: "for mac users",
|
|
423
|
+
value: ".DS_Store",
|
|
424
|
+
},
|
|
425
|
+
];
|
|
426
|
+
|
|
427
|
+
export async function createGitIgnoreFile(cwd: string) {
|
|
428
|
+
const gitIgnorePath = path.join(cwd, ".gitignore");
|
|
429
|
+
|
|
430
|
+
if (fs.existsSync(gitIgnorePath)) {
|
|
431
|
+
const result = await prompts([
|
|
432
|
+
{
|
|
433
|
+
type: "select",
|
|
434
|
+
name: "overwrite",
|
|
435
|
+
message: `${cyan(".gitignore")} already exists. Please choose how to proceed:`,
|
|
436
|
+
initial: 0,
|
|
437
|
+
choices: [
|
|
438
|
+
{
|
|
439
|
+
title: "Choose items to append in your .gitignore",
|
|
440
|
+
value: "append",
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
title: "Keep original",
|
|
444
|
+
value: "ignore",
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
title: "Overwrite",
|
|
448
|
+
value: "overwrite",
|
|
449
|
+
},
|
|
450
|
+
],
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
type: (overwrite: "append" | "ignore" | "overwrite") =>
|
|
454
|
+
overwrite === "append" ? "multiselect" : null,
|
|
455
|
+
name: "ignoreItems",
|
|
456
|
+
message: "Choose items to append in your .gitignore",
|
|
457
|
+
choices: gitIgnoreItems.map((item) => ({
|
|
458
|
+
title: `${yellow(item.value)}${
|
|
459
|
+
item.description ? ` - ${item.description}` : ""
|
|
460
|
+
}${item.isRecommended ? ` ${green("(recommended)")}` : ""}`,
|
|
461
|
+
value: item.value,
|
|
462
|
+
})),
|
|
463
|
+
},
|
|
464
|
+
]);
|
|
465
|
+
|
|
466
|
+
const { overwrite, ignoreItems } = result as {
|
|
467
|
+
overwrite: "append" | "ignore" | "overwrite";
|
|
468
|
+
ignoreItems: string[];
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
if (overwrite === "append" && ignoreItems.length > 0) {
|
|
472
|
+
const gitIgnoreContent = fs.readFileSync(gitIgnorePath, "utf8");
|
|
473
|
+
fs.writeFileSync(
|
|
474
|
+
gitIgnorePath,
|
|
475
|
+
`${gitIgnoreContent}\n${result.ignoreItems.join("\n")}`,
|
|
476
|
+
);
|
|
477
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (overwrite === "overwrite") {
|
|
482
|
+
fs.writeFileSync(
|
|
483
|
+
gitIgnorePath,
|
|
484
|
+
gitIgnoreItems.map((item) => item.value).join("\n"),
|
|
485
|
+
);
|
|
486
|
+
consola.success(`Updated ${cyan(".gitignore")}`);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
fs.writeFileSync(
|
|
492
|
+
gitIgnorePath,
|
|
493
|
+
gitIgnoreItems.map((item) => item.value).join("\n"),
|
|
494
|
+
);
|
|
495
|
+
consola.success(`Created ${cyan(".gitignore")}`);
|
|
496
|
+
}
|
package/src/create/types.ts
CHANGED
|
@@ -16,6 +16,8 @@ export type Network =
|
|
|
16
16
|
|
|
17
17
|
export type Storage = "postgres" | "none";
|
|
18
18
|
|
|
19
|
+
export type FileExtension = "js" | "ts" | "mjs";
|
|
20
|
+
|
|
19
21
|
export type IndexerOptions = {
|
|
20
22
|
cwd: string;
|
|
21
23
|
indexerFileId: string;
|
|
@@ -26,6 +28,7 @@ export type IndexerOptions = {
|
|
|
26
28
|
dnaUrl?: string;
|
|
27
29
|
packageManager: string;
|
|
28
30
|
language: Language;
|
|
31
|
+
extension: FileExtension;
|
|
29
32
|
};
|
|
30
33
|
|
|
31
34
|
export type PkgInfo = {
|
package/src/create/utils.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as prettier from "prettier";
|
|
|
4
4
|
import prompts from "prompts";
|
|
5
5
|
import { blue, cyan, red, yellow } from "./colors";
|
|
6
6
|
import { dnaUrls, networks } from "./constants";
|
|
7
|
-
import type { Chain, Language, Network, PkgInfo } from "./types";
|
|
7
|
+
import type { Chain, FileExtension, Language, Network, PkgInfo } from "./types";
|
|
8
8
|
|
|
9
9
|
export function isEmpty(path: string) {
|
|
10
10
|
const files = fs.readdirSync(path);
|
|
@@ -31,7 +31,8 @@ export function validateLanguage(language?: string, throwError = false) {
|
|
|
31
31
|
language === "typescript" ||
|
|
32
32
|
language === "ts" ||
|
|
33
33
|
language === "javascript" ||
|
|
34
|
-
language === "js"
|
|
34
|
+
language === "js" ||
|
|
35
|
+
language === "mjs"
|
|
35
36
|
) {
|
|
36
37
|
return true;
|
|
37
38
|
}
|
|
@@ -49,7 +50,7 @@ export function getLanguageFromAlias(alias: string): Language {
|
|
|
49
50
|
if (alias === "ts" || alias === "typescript") {
|
|
50
51
|
return "typescript";
|
|
51
52
|
}
|
|
52
|
-
if (alias === "js" || alias === "javascript") {
|
|
53
|
+
if (alias === "js" || alias === "javascript" || alias === "mjs") {
|
|
53
54
|
return "javascript";
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -184,19 +185,31 @@ export function validateDnaUrl(dnaUrl?: string, throwError = false) {
|
|
|
184
185
|
export function hasApibaraConfig(cwd: string): boolean {
|
|
185
186
|
const configPathJS = path.join(cwd, "apibara.config.js");
|
|
186
187
|
const configPathTS = path.join(cwd, "apibara.config.ts");
|
|
188
|
+
const configPathMJS = path.join(cwd, "apibara.config.mjs");
|
|
187
189
|
|
|
188
|
-
return
|
|
190
|
+
return (
|
|
191
|
+
fs.existsSync(configPathJS) ||
|
|
192
|
+
fs.existsSync(configPathTS) ||
|
|
193
|
+
fs.existsSync(configPathMJS)
|
|
194
|
+
);
|
|
189
195
|
}
|
|
190
196
|
|
|
191
|
-
export function getApibaraConfigLanguage(cwd: string):
|
|
197
|
+
export function getApibaraConfigLanguage(cwd: string): {
|
|
198
|
+
language: Language;
|
|
199
|
+
extension: FileExtension;
|
|
200
|
+
} {
|
|
192
201
|
const configPathJS = path.join(cwd, "apibara.config.js");
|
|
193
202
|
const configPathTS = path.join(cwd, "apibara.config.ts");
|
|
203
|
+
const configPathMJS = path.join(cwd, "apibara.config.mjs");
|
|
194
204
|
|
|
205
|
+
if (fs.existsSync(configPathMJS)) {
|
|
206
|
+
return { language: "javascript", extension: "mjs" };
|
|
207
|
+
}
|
|
195
208
|
if (fs.existsSync(configPathJS)) {
|
|
196
|
-
return "javascript";
|
|
209
|
+
return { language: "javascript", extension: "js" };
|
|
197
210
|
}
|
|
198
211
|
if (fs.existsSync(configPathTS)) {
|
|
199
|
-
return "typescript";
|
|
212
|
+
return { language: "typescript", extension: "ts" };
|
|
200
213
|
}
|
|
201
214
|
|
|
202
215
|
throw new Error(red("✖") + " No apibara.config found");
|
|
@@ -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,86 @@
|
|
|
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
|
+
import { staticConfig } from "./plugins/static-config";
|
|
14
|
+
|
|
15
|
+
const runtimeDependencies = [
|
|
16
|
+
"better-sqlite3",
|
|
17
|
+
"@electric-sql/pglite",
|
|
18
|
+
"pg",
|
|
19
|
+
// https://socket.io/docs/v4/server-installation/#additional-packages
|
|
20
|
+
"utf-8-validate",
|
|
21
|
+
"bufferutil",
|
|
22
|
+
"fsevents",
|
|
23
|
+
// was giving unresolved import warnings from `node-fetch` library.
|
|
24
|
+
"encoding",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
export function getRolldownConfig(apibara: Apibara): RolldownOptions {
|
|
28
|
+
const extensions: string[] = [
|
|
29
|
+
".ts",
|
|
30
|
+
".mjs",
|
|
31
|
+
".js",
|
|
32
|
+
".json",
|
|
33
|
+
".node",
|
|
34
|
+
".tsx",
|
|
35
|
+
".jsx",
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const tsConfigExists = existsSync(
|
|
39
|
+
join(apibara.options.rootDir, "tsconfig.json"),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const rolldownConfig: RolldownOptions & {
|
|
43
|
+
plugins: RolldownPluginOption[];
|
|
44
|
+
} = defu(
|
|
45
|
+
// biome-ignore lint/suspicious/noExplicitAny: apibara.options.rolldownConfig is typed
|
|
46
|
+
apibara.options.rolldownConfig as any,
|
|
47
|
+
<ConfigExport>{
|
|
48
|
+
platform: "node",
|
|
49
|
+
input: apibara.options.entry,
|
|
50
|
+
output: {
|
|
51
|
+
dir: join(apibara.options.outputDir || "./.apibara/build"),
|
|
52
|
+
format: "esm",
|
|
53
|
+
entryFileNames: "[name].mjs",
|
|
54
|
+
chunkFileNames: "chunks/[name]-[hash].mjs",
|
|
55
|
+
sourcemap: true,
|
|
56
|
+
},
|
|
57
|
+
plugins: [],
|
|
58
|
+
onwarn(warning, rolldownWarn) {
|
|
59
|
+
if (
|
|
60
|
+
!["CIRCULAR_DEPENDENCY", "EVAL", "THIS_IS_UNDEFINED"].includes(
|
|
61
|
+
warning.code || "",
|
|
62
|
+
) &&
|
|
63
|
+
!warning.message.includes("Unsupported source map comment") &&
|
|
64
|
+
!warning.message.includes("@__PURE__") &&
|
|
65
|
+
!warning.message.includes("/*#__PURE__*/")
|
|
66
|
+
) {
|
|
67
|
+
rolldownWarn(warning);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
resolve: {
|
|
71
|
+
extensions,
|
|
72
|
+
preferBuiltins: !!apibara.options.node,
|
|
73
|
+
mainFields: ["main"],
|
|
74
|
+
exportConditions: apibara.options.exportConditions,
|
|
75
|
+
tsconfigFilename: tsConfigExists ? "tsconfig.json" : undefined,
|
|
76
|
+
},
|
|
77
|
+
treeshake: true,
|
|
78
|
+
external: [...builtinModules, ...runtimeDependencies],
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
rolldownConfig.plugins?.push(staticConfig(apibara));
|
|
83
|
+
rolldownConfig.plugins?.push(instrumentation(apibara));
|
|
84
|
+
rolldownConfig.plugins?.push(indexers(apibara));
|
|
85
|
+
return rolldownConfig;
|
|
86
|
+
}
|
|
@@ -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" : apibara.options._c12.configFile?.endsWith(".mjs") ? "mjs" : "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
|
+
}
|