apibara 2.0.0-beta.5 → 2.0.0-beta.7

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.
@@ -0,0 +1,28 @@
1
+ import { createApibara, prepare, writeTypes, build as build$1 } from 'apibara/core';
2
+ import { defineCommand } from 'citty';
3
+ import consola__default from 'consola';
4
+ import { resolve } from 'pathe';
5
+ import { c as commonArgs } from '../shared/apibara.1b515d04.mjs';
6
+
7
+ const build = defineCommand({
8
+ meta: {
9
+ name: "build",
10
+ description: "Build indexer"
11
+ },
12
+ args: {
13
+ ...commonArgs
14
+ },
15
+ async run({ args }) {
16
+ consola__default.start("Building");
17
+ const rootDir = resolve(args.dir || args._dir || ".");
18
+ const apibara = await createApibara({
19
+ rootDir
20
+ });
21
+ await prepare(apibara);
22
+ await writeTypes(apibara);
23
+ await build$1(apibara);
24
+ await apibara.close();
25
+ }
26
+ });
27
+
28
+ export { build as default };
@@ -0,0 +1,96 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createApibara, prepare, writeTypes, build } from 'apibara/core';
3
+ import { defineCommand } from 'citty';
4
+ import consola__default from 'consola';
5
+ import { resolve } from 'pathe';
6
+ import { c as commonArgs } from '../shared/apibara.1b515d04.mjs';
7
+
8
+ const hmrKeyRe = /^runtimeConfig\./;
9
+ let childProcess;
10
+ const dev = defineCommand({
11
+ meta: {
12
+ name: "dev",
13
+ description: "Start the development server"
14
+ },
15
+ args: {
16
+ ...commonArgs,
17
+ indexers: {
18
+ type: "string",
19
+ description: "Comma-separated list of indexers to run"
20
+ },
21
+ preset: {
22
+ type: "string",
23
+ description: "Preset to use"
24
+ },
25
+ sink: {
26
+ type: "string",
27
+ description: "Sink to use"
28
+ }
29
+ },
30
+ async run({ args }) {
31
+ consola__default.start("Starting dev server");
32
+ const rootDir = resolve(args.dir || args._dir || ".");
33
+ let apibara;
34
+ const reload = async () => {
35
+ if (apibara) {
36
+ consola__default.info("Restarting dev server");
37
+ if ("unwatch" in apibara.options._c12) {
38
+ await apibara.options._c12.unwatch();
39
+ }
40
+ await apibara.close();
41
+ }
42
+ apibara = await createApibara(
43
+ {
44
+ rootDir
45
+ },
46
+ {
47
+ watch: true,
48
+ c12: {
49
+ async onUpdate({ getDiff, newConfig }) {
50
+ const diff = getDiff();
51
+ if (diff.length === 0) {
52
+ return;
53
+ }
54
+ consola__default.info(
55
+ `Nitro config updated:
56
+ ${diff.map((entry) => ` ${entry.toString()}`).join("\n")}`
57
+ );
58
+ await (diff.every((e) => hmrKeyRe.test(e.key)) ? apibara.updateConfig(newConfig.config || {}) : reload());
59
+ }
60
+ }
61
+ },
62
+ true
63
+ );
64
+ apibara.hooks.hookOnce("restart", reload);
65
+ await prepare(apibara);
66
+ await writeTypes(apibara);
67
+ await build(apibara);
68
+ apibara.hooks.hook("dev:reload", () => {
69
+ if (childProcess) {
70
+ consola__default.start("Restarting indexers");
71
+ childProcess.kill();
72
+ } else {
73
+ consola__default.success("Dev server started");
74
+ consola__default.success("Starting indexers");
75
+ }
76
+ const childArgs = [
77
+ resolve(apibara.options.outputDir || "./.apibara/build", "main.mjs"),
78
+ ...args.indexers ? ["--indexers", args.indexers] : [],
79
+ ...args.preset ? ["--preset", args.preset] : [],
80
+ ...args.sink ? ["--sink", args.sink] : []
81
+ ];
82
+ childProcess = spawn("node", childArgs, {
83
+ stdio: "inherit"
84
+ });
85
+ childProcess.on("close", (code) => {
86
+ if (code !== null) {
87
+ consola__default.log(`Indexers process exited with code ${code}`);
88
+ }
89
+ });
90
+ });
91
+ };
92
+ await reload();
93
+ }
94
+ });
95
+
96
+ export { dev as default };
@@ -0,0 +1,23 @@
1
+ import { createApibara, writeTypes } from 'apibara/core';
2
+ import { defineCommand } from 'citty';
3
+ import consola__default from 'consola';
4
+ import { resolve } from 'pathe';
5
+ import { c as commonArgs } from '../shared/apibara.1b515d04.mjs';
6
+
7
+ const prepare = defineCommand({
8
+ meta: {
9
+ name: "prepare",
10
+ description: "Generate types for the project"
11
+ },
12
+ args: {
13
+ ...commonArgs
14
+ },
15
+ async run({ args }) {
16
+ consola__default.start("Preparing Types");
17
+ const rootDir = resolve(args.dir || ".");
18
+ const apibara = await createApibara({ rootDir });
19
+ await writeTypes(apibara);
20
+ }
21
+ });
22
+
23
+ export { prepare as default };
@@ -0,0 +1,5 @@
1
+ import * as citty from 'citty';
2
+
3
+ declare const mainCli: citty.CommandDef<citty.ArgsDef>;
4
+
5
+ export { mainCli };
@@ -0,0 +1,5 @@
1
+ import * as citty from 'citty';
2
+
3
+ declare const mainCli: citty.CommandDef<citty.ArgsDef>;
4
+
5
+ export { mainCli };
@@ -0,0 +1,17 @@
1
+ import { defineCommand, runMain } from 'citty';
2
+
3
+ const mainCli = defineCommand({
4
+ meta: {
5
+ name: "apibara",
6
+ description: "Apibara CLI",
7
+ version: "2.0.0"
8
+ },
9
+ subCommands: {
10
+ dev: () => import('../chunks/dev.mjs').then((r) => r.default),
11
+ build: () => import('../chunks/build.mjs').then((r) => r.default),
12
+ prepare: () => import('../chunks/prepare.mjs').then((r) => r.default)
13
+ }
14
+ });
15
+ runMain(mainCli);
16
+
17
+ export { mainCli };
@@ -0,0 +1,5 @@
1
+ import { DeepPartial, ApibaraConfig } from 'apibara/types';
2
+
3
+ declare function defineConfig<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}>(config: ApibaraConfig<T, R>): ApibaraConfig<T, R>;
4
+
5
+ export { defineConfig };
@@ -0,0 +1,5 @@
1
+ import { DeepPartial, ApibaraConfig } from 'apibara/types';
2
+
3
+ declare function defineConfig<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}>(config: ApibaraConfig<T, R>): ApibaraConfig<T, R>;
4
+
5
+ export { defineConfig };
@@ -0,0 +1,5 @@
1
+ function defineConfig(config) {
2
+ return config;
3
+ }
4
+
5
+ export { defineConfig };
@@ -0,0 +1,11 @@
1
+ import { ApibaraConfig, LoadConfigOptions, Apibara } from 'apibara/types';
2
+
3
+ declare function createApibara(config?: ApibaraConfig, opts?: LoadConfigOptions, dev?: boolean): Promise<Apibara>;
4
+
5
+ declare function build(apibara: Apibara): Promise<void>;
6
+
7
+ declare function prepare(apibara: Apibara): Promise<void>;
8
+
9
+ declare function writeTypes(apibara: Apibara): Promise<void>;
10
+
11
+ export { build, createApibara, prepare, writeTypes };
@@ -0,0 +1,11 @@
1
+ import { ApibaraConfig, LoadConfigOptions, Apibara } from 'apibara/types';
2
+
3
+ declare function createApibara(config?: ApibaraConfig, opts?: LoadConfigOptions, dev?: boolean): Promise<Apibara>;
4
+
5
+ declare function build(apibara: Apibara): Promise<void>;
6
+
7
+ declare function prepare(apibara: Apibara): Promise<void>;
8
+
9
+ declare function writeTypes(apibara: Apibara): Promise<void>;
10
+
11
+ export { build, createApibara, prepare, writeTypes };
@@ -0,0 +1,345 @@
1
+ import consola__default from 'consola';
2
+ import { createHooks } from 'hookable';
3
+ import { watchConfig, loadConfig } from 'c12';
4
+ import { klona } from 'klona/full';
5
+ import { resolve, isAbsolute, relative, join, dirname } from 'pathe';
6
+ import defu from 'defu';
7
+ import { getRollupConfig } from 'apibara/rollup';
8
+ import { watch } from 'chokidar';
9
+ import { debounce } from 'perfect-debounce';
10
+ import * as rollup from 'rollup';
11
+ import { rollup as rollup$1 } from 'rollup';
12
+ import fsp from 'node:fs/promises';
13
+ import fse from 'fs-extra';
14
+ import { generateTypes, resolveSchema } from 'untyped';
15
+
16
+ const ApibaraDefaults = {
17
+ rootDir: ".",
18
+ runtimeConfig: {},
19
+ hooks: {},
20
+ buildDir: ".apibara",
21
+ typescript: {
22
+ strict: false,
23
+ generateTsConfig: true,
24
+ generateRuntimeConfigTypes: true,
25
+ tsconfigPath: "types/tsconfig.json",
26
+ internalPaths: false,
27
+ tsConfig: {}
28
+ }
29
+ };
30
+
31
+ async function resolvePathOptions(options) {
32
+ options.rootDir = resolve(options.rootDir || ".");
33
+ for (const key of ["buildDir"]) {
34
+ options[key] = resolve(options.rootDir, options[key]);
35
+ }
36
+ if (!options.outputDir) {
37
+ options.outputDir = resolve(options.rootDir, ".apibara/build");
38
+ }
39
+ }
40
+
41
+ async function presetResolver(options) {
42
+ if (options.preset && options.presets?.[options.preset]) {
43
+ const new_options = defu(options.presets[options.preset], options);
44
+ Object.assign(options, new_options);
45
+ }
46
+ }
47
+
48
+ async function resolveRuntimeConfigOptions(options) {
49
+ options.runtimeConfig = { ...options.runtimeConfig, default: "value" };
50
+ process.env.APIBARA_RUNTIME_CONFIG = JSON.stringify(options.runtimeConfig);
51
+ }
52
+
53
+ const configResolvers = [
54
+ resolvePathOptions,
55
+ resolveRuntimeConfigOptions,
56
+ presetResolver
57
+ ];
58
+ async function loadOptions(configOverrides = {}, opts = {}, dev = false) {
59
+ const options = await _loadUserConfig(configOverrides, opts, dev);
60
+ for (const resolver of configResolvers) {
61
+ await resolver(options);
62
+ }
63
+ return options;
64
+ }
65
+ async function _loadUserConfig(configOverrides = {}, opts = {}, dev = false) {
66
+ configOverrides = klona(configOverrides);
67
+ const loadedConfig = await (opts.watch ? watchConfig : loadConfig)({
68
+ name: "apibara",
69
+ dotenv: dev,
70
+ cwd: configOverrides.rootDir,
71
+ overrides: {
72
+ ...configOverrides
73
+ },
74
+ defaults: { ...ApibaraDefaults },
75
+ ...opts.c12
76
+ });
77
+ const options = klona(loadedConfig.config);
78
+ options._config = configOverrides;
79
+ options._c12 = loadedConfig;
80
+ if (dev) {
81
+ options.dev = dev;
82
+ }
83
+ return options;
84
+ }
85
+
86
+ async function updateApibaraConfig(apibara, config) {
87
+ await apibara.hooks.callHook("rollup:reload");
88
+ consola__default.success("Apibara config hot reloaded!");
89
+ }
90
+
91
+ async function createApibara(config = {}, opts = {}, dev = false) {
92
+ const options = await loadOptions(config, opts, dev);
93
+ const apibara = {
94
+ options,
95
+ hooks: createHooks(),
96
+ close: () => apibara.hooks.callHook("close"),
97
+ logger: consola__default.withTag("apibara"),
98
+ async updateConfig(config2) {
99
+ updateApibaraConfig(apibara);
100
+ }
101
+ };
102
+ apibara.hooks.addHooks(apibara.options.hooks);
103
+ return apibara;
104
+ }
105
+
106
+ function formatRollupError(_error) {
107
+ try {
108
+ const logs = [_error.toString()];
109
+ const errors = _error?.errors || [_error];
110
+ for (const error of errors) {
111
+ const id = error.path || error.id || _error.id;
112
+ let path = isAbsolute(id) ? relative(process.cwd(), id) : id;
113
+ const location = error.loc || error.location;
114
+ if (location) {
115
+ path += `:${location.line}:${location.column}`;
116
+ }
117
+ const text = error.text || error.frame;
118
+ logs.push(
119
+ // biome-ignore lint/style/useTemplate: <explanation>
120
+ `Rollup error while processing \`${path}\`` + text ? "\n\n" + text : ""
121
+ );
122
+ }
123
+ return logs.join("\n");
124
+ } catch {
125
+ return _error?.toString();
126
+ }
127
+ }
128
+
129
+ async function watchDev(apibara, rollupConfig) {
130
+ let rollupWatcher;
131
+ async function load() {
132
+ if (rollupWatcher) {
133
+ await rollupWatcher.close();
134
+ }
135
+ rollupWatcher = startRollupWatcher(apibara, rollupConfig);
136
+ }
137
+ const reload = debounce(load);
138
+ const watchPatterns = [join(apibara.options.rootDir, "indexers")];
139
+ const watchReloadEvents = /* @__PURE__ */ new Set(["add", "addDir", "unlink", "unlinkDir"]);
140
+ const reloadWatcher = watch(watchPatterns, { ignoreInitial: true }).on(
141
+ "all",
142
+ (event) => {
143
+ if (watchReloadEvents.has(event)) {
144
+ reload();
145
+ }
146
+ }
147
+ );
148
+ apibara.hooks.hook("close", () => {
149
+ rollupWatcher.close();
150
+ reloadWatcher.close();
151
+ });
152
+ apibara.hooks.hook("rollup:reload", () => reload());
153
+ await load();
154
+ }
155
+ function startRollupWatcher(apibara, rollupConfig) {
156
+ const watcher = rollup.watch(
157
+ defu(rollupConfig, {
158
+ watch: {
159
+ chokidar: apibara.options.watchOptions
160
+ }
161
+ })
162
+ );
163
+ let start;
164
+ watcher.on("event", (event) => {
165
+ switch (event.code) {
166
+ case "START": {
167
+ return;
168
+ }
169
+ case "BUNDLE_START": {
170
+ start = Date.now();
171
+ return;
172
+ }
173
+ case "END": {
174
+ apibara.hooks.callHook("compiled", apibara);
175
+ apibara.logger.success(
176
+ "Indexers built",
177
+ start ? `in ${Date.now() - start} ms` : ""
178
+ );
179
+ apibara.hooks.callHook("dev:reload");
180
+ return;
181
+ }
182
+ case "ERROR": {
183
+ apibara.logger.error(formatRollupError(event.error));
184
+ }
185
+ }
186
+ });
187
+ return watcher;
188
+ }
189
+
190
+ async function buildProduction(apibara, rollupConfig) {
191
+ try {
192
+ const bundle = await rollup$1(rollupConfig);
193
+ if (Array.isArray(rollupConfig.output)) {
194
+ for (const outputOptions of rollupConfig.output) {
195
+ await bundle.write(outputOptions);
196
+ }
197
+ } else if (rollupConfig.output) {
198
+ await bundle.write(rollupConfig.output);
199
+ } else {
200
+ throw new Error("No output options specified in Rollup config");
201
+ }
202
+ await bundle.close();
203
+ consola__default.success("Build completed successfully!");
204
+ } catch (error) {
205
+ console.error("Build failed:", error);
206
+ throw error;
207
+ }
208
+ }
209
+
210
+ async function build(apibara) {
211
+ const rollupConfig = getRollupConfig(apibara);
212
+ await apibara.hooks.callHook("rollup:before", apibara, rollupConfig);
213
+ return apibara.options.dev ? await watchDev(apibara, rollupConfig) : await buildProduction(apibara, rollupConfig);
214
+ }
215
+
216
+ async function prepare(apibara) {
217
+ await prepareDir(apibara.options.buildDir);
218
+ await prepareDir(apibara.options.outputDir);
219
+ consola__default.success("Output directory cleaned");
220
+ }
221
+ async function prepareDir(dir) {
222
+ await fsp.mkdir(dir, { recursive: true });
223
+ await fse.emptyDir(dir);
224
+ }
225
+
226
+ async function writeTypes(apibara) {
227
+ const typesDir = resolve(apibara.options.buildDir, "types");
228
+ const config = [
229
+ "// Generated by apibara",
230
+ `
231
+ declare module "apibara/types" {`,
232
+ apibara.options.typescript.generateRuntimeConfigTypes ? generateTypes(
233
+ await resolveSchema(
234
+ Object.fromEntries(
235
+ Object.entries(apibara.options.runtimeConfig)
236
+ )
237
+ ),
238
+ {
239
+ interfaceName: "ApibaraRuntimeConfig",
240
+ addExport: false,
241
+ addDefaults: false,
242
+ allowExtraKeys: false,
243
+ indentation: 2
244
+ }
245
+ ) : "",
246
+ "}",
247
+ // Makes this a module for augmentation purposes
248
+ "export type {}"
249
+ ];
250
+ const declarations = [
251
+ // local apibara augmentations
252
+ '/// <reference path="./apibara-config.d.ts" />'
253
+ ];
254
+ const buildFiles = [];
255
+ buildFiles.push({
256
+ path: join(typesDir, "apibara-config.d.ts"),
257
+ contents: config.join("\n")
258
+ });
259
+ buildFiles.push({
260
+ path: join(typesDir, "apibara.d.ts"),
261
+ contents: declarations.join("\n")
262
+ });
263
+ if (apibara.options.typescript.generateTsConfig) {
264
+ const tsConfigPath = resolve(
265
+ apibara.options.buildDir,
266
+ apibara.options.typescript.tsconfigPath
267
+ );
268
+ const tsconfigDir = dirname(tsConfigPath);
269
+ const tsConfig = defu(apibara.options.typescript.tsConfig, {
270
+ compilerOptions: {
271
+ forceConsistentCasingInFileNames: true,
272
+ strict: apibara.options.typescript.strict,
273
+ noEmit: true,
274
+ target: "ESNext",
275
+ module: "ESNext",
276
+ moduleResolution: "Bundler",
277
+ allowJs: true,
278
+ resolveJsonModule: true,
279
+ jsx: "preserve",
280
+ allowSyntheticDefaultImports: true,
281
+ jsxFactory: "h",
282
+ jsxFragmentFactory: "Fragment"
283
+ },
284
+ include: [
285
+ relativeWithDot(tsconfigDir, join(typesDir, "apibara.d.ts")).replace(
286
+ /^(?=[^.])/,
287
+ "./"
288
+ )
289
+ ]
290
+ });
291
+ for (const alias in tsConfig.compilerOptions.paths) {
292
+ const paths = tsConfig.compilerOptions.paths[alias];
293
+ tsConfig.compilerOptions.paths[alias] = await Promise.all(
294
+ paths.map(async (path) => {
295
+ if (!isAbsolute(path)) {
296
+ return path;
297
+ }
298
+ const stats = await fsp.stat(path).catch(
299
+ () => null
300
+ /* file does not exist */
301
+ );
302
+ return relativeWithDot(
303
+ tsconfigDir,
304
+ stats?.isFile() ? path.replace(/(?<=\w)\.\w+$/g, "") : path
305
+ );
306
+ })
307
+ );
308
+ }
309
+ tsConfig.include = [
310
+ ...new Set(
311
+ tsConfig.include.map(
312
+ (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
313
+ )
314
+ )
315
+ ];
316
+ if (tsConfig.exclude) {
317
+ tsConfig.exclude = [
318
+ ...new Set(
319
+ tsConfig.exclude.map(
320
+ (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
321
+ )
322
+ )
323
+ ];
324
+ }
325
+ buildFiles.push({
326
+ path: tsConfigPath,
327
+ contents: JSON.stringify(tsConfig, null, 2)
328
+ });
329
+ }
330
+ await Promise.all(
331
+ buildFiles.map(async (file) => {
332
+ const _file = resolve(apibara.options.buildDir, file.path);
333
+ await fsp.mkdir(dirname(_file), { recursive: true });
334
+ await fsp.writeFile(_file, file.contents);
335
+ })
336
+ );
337
+ consola__default.success("Types generated");
338
+ }
339
+ const RELATIVE_RE = /^\.{1,2}\//;
340
+ function relativeWithDot(from, to) {
341
+ const rel = relative(from, to);
342
+ return RELATIVE_RE.test(rel) ? rel : `./${rel}`;
343
+ }
344
+
345
+ export { build, createApibara, prepare, writeTypes };
@@ -0,0 +1,5 @@
1
+ import { ApibaraRuntimeConfig } from 'apibara/types';
2
+
3
+ declare function useRuntimeConfig(): ApibaraRuntimeConfig;
4
+
5
+ export { useRuntimeConfig };
@@ -0,0 +1,5 @@
1
+ import { ApibaraRuntimeConfig } from 'apibara/types';
2
+
3
+ declare function useRuntimeConfig(): ApibaraRuntimeConfig;
4
+
5
+ export { useRuntimeConfig };
@@ -0,0 +1,5 @@
1
+ function useRuntimeConfig() {
2
+ return JSON.parse(process.env.APIBARA_RUNTIME_CONFIG || "{}");
3
+ }
4
+
5
+ export { useRuntimeConfig };
@@ -0,0 +1 @@
1
+ export * from 'citty';
@@ -0,0 +1 @@
1
+ export * from 'citty';
@@ -0,0 +1 @@
1
+ export * from 'citty';
@@ -0,0 +1,2 @@
1
+ export * from 'consola';
2
+ import 'citty';
@@ -0,0 +1,2 @@
1
+ export * from 'consola';
2
+ import 'citty';
@@ -0,0 +1 @@
1
+ export * from 'consola';
@@ -0,0 +1,5 @@
1
+ import { Apibara, RollupConfig } from 'apibara/types';
2
+
3
+ declare const getRollupConfig: (apibara: Apibara, dev?: boolean) => RollupConfig;
4
+
5
+ export { getRollupConfig };
@@ -0,0 +1,5 @@
1
+ import { Apibara, RollupConfig } from 'apibara/types';
2
+
3
+ declare const getRollupConfig: (apibara: Apibara, dev?: boolean) => RollupConfig;
4
+
5
+ export { getRollupConfig };
@@ -0,0 +1,187 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { builtinModules } from 'node:module';
3
+ import commonjs from '@rollup/plugin-commonjs';
4
+ import json from '@rollup/plugin-json';
5
+ import { nodeResolve } from '@rollup/plugin-node-resolve';
6
+ import typescript from '@rollup/plugin-typescript';
7
+ import fse from 'fs-extra';
8
+ import { join, basename } from 'pathe';
9
+
10
+ const getRollupConfig = (apibara, dev = false) => {
11
+ const extensions = [
12
+ ".ts",
13
+ ".mjs",
14
+ ".js",
15
+ ".json",
16
+ ".node",
17
+ ".tsx",
18
+ ".jsx"
19
+ ];
20
+ const indexerDir = join(apibara.options.rootDir, "indexers");
21
+ const configPath = join(apibara.options.rootDir, "./apibara.config.ts");
22
+ if (!existsSync(indexerDir)) {
23
+ throw new Error(`Indexers directory not found: ${indexerDir}`);
24
+ }
25
+ if (!existsSync(configPath)) {
26
+ throw new Error(`Config file not found: ${configPath}`);
27
+ }
28
+ let indexerFiles = [];
29
+ try {
30
+ indexerFiles = fse.readdirSync(indexerDir).filter((file) => file.endsWith(".indexer.ts"));
31
+ if (indexerFiles.length === 0) {
32
+ console.warn(`No indexer files found in ${indexerDir}`);
33
+ }
34
+ } catch (error) {
35
+ console.error(`Error reading indexers directory: ${error}`);
36
+ }
37
+ const indexerImports = indexerFiles.map(
38
+ (file, index) => `import indexer${index} from '${join(indexerDir, file)}';`
39
+ ).join("\n");
40
+ const mainContent = `
41
+ import { createClient } from "@apibara/protocol";
42
+ import { createIndexer, run } from "@apibara/indexer";
43
+ import { consola as _consola } from "apibara/internal/consola";
44
+ import { defineCommand, runMain } from "apibara/internal/citty";
45
+ import config from './${configPath}';
46
+
47
+ const consola = _consola.withTag("Apibara | ");
48
+
49
+ ${indexerImports}
50
+
51
+ const indexers = {
52
+ ${indexerFiles.map(
53
+ (file, index) => `'${basename(file, ".indexer.ts")}': indexer${index},`
54
+ ).join("\n ")}
55
+ };
56
+
57
+ const command = defineCommand({
58
+ meta: {
59
+ name: "run-indexers",
60
+ description: "Run Apibara indexers",
61
+ },
62
+ args: {
63
+ indexers: {
64
+ type: "string",
65
+ description: "Comma-separated list of indexers to run",
66
+ },
67
+ preset: {
68
+ type: "string",
69
+ description: "Preset to use",
70
+ },
71
+ sink: {
72
+ type: "string",
73
+ description: "Sink to use",
74
+ },
75
+ },
76
+ async run({ args }) {
77
+ const selectedIndexers = args.indexers ? args.indexers.split(',') : Object.keys(indexers);
78
+ const preset = args.preset || config.preset || 'default';
79
+ const sinkName = args.sink || 'default';
80
+
81
+ // Apply preset
82
+ let runtimeConfig = { ...config.runtimeConfig };
83
+ if (preset && config.presets && config.presets[preset]) {
84
+ runtimeConfig = { ...runtimeConfig, ...config.presets[preset].runtimeConfig };
85
+ }
86
+
87
+ // Get sink function
88
+ const sinkFunction = config.sink?.[sinkName];
89
+ if (!sinkFunction) {
90
+ throw new Error(\`Sink \${sinkName} not found\`);
91
+ }
92
+
93
+ await Promise.all(selectedIndexers.map(async (name) => {
94
+ if (!indexers[name]) {
95
+ console.error(\`Indexer \${name} not found\`);
96
+ return;
97
+ }
98
+
99
+ const indexerConfig = indexers[name]
100
+ const indexer = typeof indexerConfig === 'function'
101
+ ? await createIndexer(indexerConfig(runtimeConfig))
102
+ : createIndexer(indexerConfig);
103
+
104
+ const client = createClient(indexer.streamConfig, indexer.options.streamUrl);
105
+ const sink = sinkFunction();
106
+
107
+ try {
108
+ consola.log("Running Indexer: ", name);
109
+ await run(client, indexer, sink);
110
+ } catch (error) {
111
+ consola.error(\`Error in indexer \${name}:\`, error);
112
+ }
113
+ }));
114
+ },
115
+ });
116
+
117
+ runMain(command);
118
+ `;
119
+ return {
120
+ input: {
121
+ main: "virtual:main.ts"
122
+ },
123
+ output: {
124
+ dir: join(apibara.options.outputDir || "./.apibara/build"),
125
+ format: "esm",
126
+ exports: "auto",
127
+ entryFileNames: "[name].mjs",
128
+ chunkFileNames: "chunks/[name]-[hash].mjs",
129
+ generatedCode: {
130
+ constBindings: true
131
+ },
132
+ sourcemap: true,
133
+ sourcemapExcludeSources: true,
134
+ sourcemapIgnoreList(relativePath, sourcemapPath) {
135
+ return relativePath.includes("node_modules");
136
+ }
137
+ },
138
+ plugins: [
139
+ {
140
+ name: "virtual",
141
+ resolveId(id) {
142
+ if (id === "virtual:main.ts") {
143
+ return id;
144
+ }
145
+ return null;
146
+ },
147
+ load(id) {
148
+ if (id === "virtual:main.ts") {
149
+ return mainContent;
150
+ }
151
+ return null;
152
+ }
153
+ },
154
+ nodeResolve({
155
+ extensions,
156
+ preferBuiltins: true
157
+ }),
158
+ commonjs(),
159
+ json(),
160
+ typescript({
161
+ tsconfig: join(apibara.options.rootDir, "./tsconfig.json"),
162
+ compilerOptions: {
163
+ outDir: join(apibara.options.outputDir || "./.apibara/build"),
164
+ declarationDir: join(apibara.options.outputDir || "./.apibara/build"),
165
+ noEmit: false,
166
+ types: ["node"]
167
+ }
168
+ })
169
+ ],
170
+ onwarn(warning, rollupWarn) {
171
+ if (!["CIRCULAR_DEPENDENCY", "EVAL"].includes(warning.code || "") && !warning.message.includes("Unsupported source map comment") && !warning.message.includes("@__PURE__")) {
172
+ rollupWarn(warning);
173
+ }
174
+ },
175
+ treeshake: true,
176
+ external: [
177
+ ...builtinModules,
178
+ "@apibara/indexer",
179
+ "@apibara/protocol",
180
+ "@apibara/evm",
181
+ "@apibara/starknet",
182
+ "@apibara/beaconchain"
183
+ ]
184
+ };
185
+ };
186
+
187
+ export { getRollupConfig };
@@ -0,0 +1,8 @@
1
+ const commonArgs = {
2
+ dir: {
3
+ type: "string",
4
+ description: "project root directory"
5
+ }
6
+ };
7
+
8
+ export { commonArgs as c };
@@ -0,0 +1,87 @@
1
+ import { ConsolaInstance } from 'consola';
2
+ import { NestedHooks, Hookable } from 'hookable';
3
+ import { Sink } from '@apibara/indexer';
4
+ import { C12InputConfig, WatchConfigOptions, ResolvedConfig, ConfigWatcher } from 'c12';
5
+ import { WatchOptions } from 'chokidar';
6
+ import { TSConfig } from 'pkg-types';
7
+ import { InputOptions, OutputOptions } from 'rollup';
8
+
9
+ type DeepPartial<T> = T extends Record<string, any> ? {
10
+ [P in keyof T]?: DeepPartial<T[P]> | T[P];
11
+ } : T;
12
+
13
+ type RollupConfig = InputOptions & {
14
+ output: OutputOptions;
15
+ };
16
+
17
+ interface ApibaraHooks {
18
+ "rollup:before": (apibara: Apibara, rollupConfig: RollupConfig) => void;
19
+ compiled: (apibara: Apibara) => void;
20
+ "dev:reload": () => void;
21
+ "rollup:reload": () => void;
22
+ restart: () => void;
23
+ close: () => void;
24
+ }
25
+
26
+ /**
27
+ * Apibara Config type (apibara.config)
28
+ */
29
+ interface ApibaraConfig<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}> extends DeepPartial<Omit<ApibaraOptions<T, R>, "preset" | "presets" | "dev">>, C12InputConfig<ApibaraConfig<T, R>> {
30
+ sink?: {
31
+ default: () => Sink;
32
+ [key: string]: () => Sink;
33
+ };
34
+ runtimeConfig?: R;
35
+ presets?: T;
36
+ preset?: keyof T;
37
+ }
38
+ type ApibaraDynamicConfig = Pick<ApibaraConfig, "runtimeConfig">;
39
+ /**
40
+ * Config loader options
41
+ */
42
+ interface LoadConfigOptions {
43
+ watch?: boolean;
44
+ c12?: WatchConfigOptions;
45
+ }
46
+ interface ApibaraOptions<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}> {
47
+ _config: ApibaraConfig<T, R>;
48
+ _c12: ResolvedConfig<ApibaraConfig<T, R>> | ConfigWatcher<ApibaraConfig<T, R>>;
49
+ sink: {
50
+ default: () => Sink;
51
+ [key: string]: () => Sink;
52
+ };
53
+ presets?: T;
54
+ preset?: keyof T;
55
+ debug: boolean;
56
+ runtimeConfig: R;
57
+ rootDir: string;
58
+ buildDir: string;
59
+ outputDir: string;
60
+ dev: boolean;
61
+ watchOptions: WatchOptions;
62
+ hooks: NestedHooks<ApibaraHooks>;
63
+ rollupConfig?: RollupConfig;
64
+ entry: string;
65
+ minify: boolean;
66
+ typescript: {
67
+ strict?: boolean;
68
+ internalPaths?: boolean;
69
+ generateRuntimeConfigTypes?: boolean;
70
+ generateTsConfig?: boolean;
71
+ /** the path of the generated `tsconfig.json`, relative to buildDir */
72
+ tsconfigPath: string;
73
+ tsConfig?: Partial<TSConfig>;
74
+ };
75
+ }
76
+
77
+ interface Apibara {
78
+ options: ApibaraOptions;
79
+ hooks: Hookable<ApibaraHooks>;
80
+ logger: ConsolaInstance;
81
+ close: () => Promise<void>;
82
+ updateConfig: (config: ApibaraDynamicConfig) => void | Promise<void>;
83
+ }
84
+
85
+ type ApibaraRuntimeConfig = Record<string, unknown>;
86
+
87
+ export type { Apibara, ApibaraConfig, ApibaraDynamicConfig, ApibaraHooks, ApibaraOptions, ApibaraRuntimeConfig, DeepPartial, LoadConfigOptions, RollupConfig };
@@ -0,0 +1,87 @@
1
+ import { ConsolaInstance } from 'consola';
2
+ import { NestedHooks, Hookable } from 'hookable';
3
+ import { Sink } from '@apibara/indexer';
4
+ import { C12InputConfig, WatchConfigOptions, ResolvedConfig, ConfigWatcher } from 'c12';
5
+ import { WatchOptions } from 'chokidar';
6
+ import { TSConfig } from 'pkg-types';
7
+ import { InputOptions, OutputOptions } from 'rollup';
8
+
9
+ type DeepPartial<T> = T extends Record<string, any> ? {
10
+ [P in keyof T]?: DeepPartial<T[P]> | T[P];
11
+ } : T;
12
+
13
+ type RollupConfig = InputOptions & {
14
+ output: OutputOptions;
15
+ };
16
+
17
+ interface ApibaraHooks {
18
+ "rollup:before": (apibara: Apibara, rollupConfig: RollupConfig) => void;
19
+ compiled: (apibara: Apibara) => void;
20
+ "dev:reload": () => void;
21
+ "rollup:reload": () => void;
22
+ restart: () => void;
23
+ close: () => void;
24
+ }
25
+
26
+ /**
27
+ * Apibara Config type (apibara.config)
28
+ */
29
+ interface ApibaraConfig<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}> extends DeepPartial<Omit<ApibaraOptions<T, R>, "preset" | "presets" | "dev">>, C12InputConfig<ApibaraConfig<T, R>> {
30
+ sink?: {
31
+ default: () => Sink;
32
+ [key: string]: () => Sink;
33
+ };
34
+ runtimeConfig?: R;
35
+ presets?: T;
36
+ preset?: keyof T;
37
+ }
38
+ type ApibaraDynamicConfig = Pick<ApibaraConfig, "runtimeConfig">;
39
+ /**
40
+ * Config loader options
41
+ */
42
+ interface LoadConfigOptions {
43
+ watch?: boolean;
44
+ c12?: WatchConfigOptions;
45
+ }
46
+ interface ApibaraOptions<T extends Record<string, DeepPartial<ApibaraConfig<T, R>>> = {}, R extends Record<string, unknown> = {}> {
47
+ _config: ApibaraConfig<T, R>;
48
+ _c12: ResolvedConfig<ApibaraConfig<T, R>> | ConfigWatcher<ApibaraConfig<T, R>>;
49
+ sink: {
50
+ default: () => Sink;
51
+ [key: string]: () => Sink;
52
+ };
53
+ presets?: T;
54
+ preset?: keyof T;
55
+ debug: boolean;
56
+ runtimeConfig: R;
57
+ rootDir: string;
58
+ buildDir: string;
59
+ outputDir: string;
60
+ dev: boolean;
61
+ watchOptions: WatchOptions;
62
+ hooks: NestedHooks<ApibaraHooks>;
63
+ rollupConfig?: RollupConfig;
64
+ entry: string;
65
+ minify: boolean;
66
+ typescript: {
67
+ strict?: boolean;
68
+ internalPaths?: boolean;
69
+ generateRuntimeConfigTypes?: boolean;
70
+ generateTsConfig?: boolean;
71
+ /** the path of the generated `tsconfig.json`, relative to buildDir */
72
+ tsconfigPath: string;
73
+ tsConfig?: Partial<TSConfig>;
74
+ };
75
+ }
76
+
77
+ interface Apibara {
78
+ options: ApibaraOptions;
79
+ hooks: Hookable<ApibaraHooks>;
80
+ logger: ConsolaInstance;
81
+ close: () => Promise<void>;
82
+ updateConfig: (config: ApibaraDynamicConfig) => void | Promise<void>;
83
+ }
84
+
85
+ type ApibaraRuntimeConfig = Record<string, unknown>;
86
+
87
+ export type { Apibara, ApibaraConfig, ApibaraDynamicConfig, ApibaraHooks, ApibaraOptions, ApibaraRuntimeConfig, DeepPartial, LoadConfigOptions, RollupConfig };
@@ -0,0 +1 @@
1
+
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "apibara",
3
- "version": "2.0.0-beta.5",
3
+ "version": "2.0.0-beta.7",
4
4
  "type": "module",
5
- "source": "./src/core/index.ts",
6
5
  "main": "./dist/core/index.mjs",
7
6
  "exports": {
8
7
  ".": {
@@ -32,6 +31,14 @@
32
31
  "./hooks": {
33
32
  "types": "./dist/hooks/index.d.ts",
34
33
  "import": "./dist/hooks/index.mjs"
34
+ },
35
+ "./internal/consola": {
36
+ "import": "./dist/internal/consola/index.mjs",
37
+ "types": "./dist/internal/consola/index.d.ts"
38
+ },
39
+ "./internal/citty": {
40
+ "import": "./dist/internal/citty/index.mjs",
41
+ "types": "./dist/internal/citty/index.d.ts"
35
42
  }
36
43
  },
37
44
  "bin": {
@@ -64,10 +71,10 @@
64
71
  "vitest": "^1.6.0"
65
72
  },
66
73
  "dependencies": {
67
- "@apibara/evm": "2.0.0-beta.5",
68
- "@apibara/indexer": "2.0.0-beta.5",
69
- "@apibara/protocol": "2.0.0-beta.5",
70
- "@apibara/starknet": "2.0.0-beta.5",
74
+ "@apibara/evm": "2.0.0-beta.7",
75
+ "@apibara/indexer": "2.0.0-beta.7",
76
+ "@apibara/protocol": "2.0.0-beta.7",
77
+ "@apibara/starknet": "2.0.0-beta.7",
71
78
  "@rollup/plugin-commonjs": "^26.0.1",
72
79
  "@rollup/plugin-json": "^6.1.0",
73
80
  "@rollup/plugin-node-resolve": "^15.2.3",
@@ -93,7 +93,7 @@ export default defineCommand({
93
93
  ...(args.sink ? ["--sink", args.sink] : []),
94
94
  ];
95
95
 
96
- childProcess = spawn("jiti", childArgs, {
96
+ childProcess = spawn("node", childArgs, {
97
97
  stdio: "inherit",
98
98
  });
99
99
 
@@ -0,0 +1 @@
1
+ export * from "citty";
@@ -0,0 +1 @@
1
+ export * from "consola";
@@ -57,10 +57,12 @@ export const getRollupConfig = (
57
57
  const mainContent = `
58
58
  import { createClient } from "@apibara/protocol";
59
59
  import { createIndexer, run } from "@apibara/indexer";
60
- import consola from "consola";
61
- import { defineCommand, runMain } from "citty";
60
+ import { consola as _consola } from "apibara/internal/consola";
61
+ import { defineCommand, runMain } from "apibara/internal/citty";
62
62
  import config from './${configPath}';
63
63
 
64
+ const consola = _consola.withTag("Apibara | ");
65
+
64
66
  ${indexerImports}
65
67
 
66
68
  const indexers = {
@@ -202,7 +204,6 @@ runMain(command);
202
204
  "@apibara/evm",
203
205
  "@apibara/starknet",
204
206
  "@apibara/beaconchain",
205
- "@apibara/cli",
206
207
  ],
207
208
  };
208
209
  };