apibara 2.0.0-beta.4 → 2.0.0-beta.40
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/build.mjs +28 -0
- package/dist/chunks/dev.mjs +100 -0
- package/dist/chunks/prepare.mjs +21 -0
- package/dist/chunks/start.mjs +56 -0
- package/dist/cli/index.d.mts +5 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.mjs +19 -0
- package/dist/config/index.d.mts +5 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.mjs +5 -0
- package/dist/core/index.d.mts +11 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.mjs +310 -0
- package/dist/hooks/index.d.mts +5 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/index.mjs +5 -0
- package/dist/rollup/index.d.mts +5 -0
- package/dist/rollup/index.d.ts +5 -0
- package/dist/rollup/index.mjs +150 -0
- package/dist/runtime/dev.d.ts +3 -0
- package/dist/runtime/dev.mjs +55 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.mjs +2 -0
- package/dist/runtime/internal/app.d.ts +2 -0
- package/dist/runtime/internal/app.mjs +56 -0
- package/dist/runtime/internal/logger.d.ts +14 -0
- package/dist/runtime/internal/logger.mjs +45 -0
- package/dist/runtime/start.d.ts +3 -0
- package/dist/runtime/start.mjs +41 -0
- package/dist/shared/apibara.1b515d04.mjs +8 -0
- package/dist/types/index.d.mts +90 -0
- package/dist/types/index.d.ts +90 -0
- package/dist/types/index.mjs +1 -0
- package/package.json +28 -8
- package/runtime-meta.d.ts +2 -0
- package/runtime-meta.mjs +7 -0
- package/src/cli/commands/build.ts +5 -3
- package/src/cli/commands/dev.ts +29 -19
- package/src/cli/commands/prepare.ts +0 -2
- package/src/cli/commands/start.ts +61 -0
- package/src/cli/index.ts +1 -0
- package/src/config/index.ts +5 -4
- package/src/core/apibara.ts +4 -2
- package/src/core/build/build.ts +2 -0
- package/src/core/build/dev.ts +1 -0
- package/src/core/build/prepare.ts +5 -2
- package/src/core/build/prod.ts +10 -6
- package/src/core/build/types.ts +4 -95
- package/src/core/config/defaults.ts +1 -4
- package/src/core/config/loader.ts +1 -0
- package/src/core/config/resolvers/runtime-config.resolver.ts +1 -1
- package/src/core/config/update.ts +2 -3
- package/src/core/path.ts +11 -0
- package/src/core/scan.ts +40 -0
- package/src/rollup/config.ts +67 -188
- package/src/rollup/plugins/config.ts +12 -0
- package/src/rollup/plugins/esm-shim.ts +69 -0
- package/src/rollup/plugins/indexers.ts +17 -0
- package/src/runtime/dev.ts +64 -0
- package/src/runtime/index.ts +2 -0
- package/src/runtime/internal/app.ts +78 -0
- package/src/runtime/internal/logger.ts +70 -0
- package/src/runtime/start.ts +48 -0
- package/src/types/apibara.ts +8 -0
- package/src/types/config.ts +28 -27
- package/src/types/hooks.ts +1 -0
- package/src/types/virtual/config.d.ts +3 -0
- package/src/types/virtual/indexers.d.ts +10 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createApibara, prepare, writeTypes, build as build$1 } from 'apibara/core';
|
|
2
|
+
import { runtimeDir } from 'apibara/runtime/meta';
|
|
3
|
+
import { defineCommand } from 'citty';
|
|
4
|
+
import { resolve, join } 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
|
+
const rootDir = resolve(args.dir || args._dir || ".");
|
|
17
|
+
const apibara = await createApibara({
|
|
18
|
+
rootDir
|
|
19
|
+
});
|
|
20
|
+
apibara.options.entry = join(runtimeDir, "start.mjs");
|
|
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,100 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createApibara, prepare, writeTypes, build } from 'apibara/core';
|
|
3
|
+
import { runtimeDir } from 'apibara/runtime/meta';
|
|
4
|
+
import { defineCommand } from 'citty';
|
|
5
|
+
import { colors } from 'consola/utils';
|
|
6
|
+
import { resolve, join } from 'pathe';
|
|
7
|
+
import { c as commonArgs } from '../shared/apibara.1b515d04.mjs';
|
|
8
|
+
|
|
9
|
+
const hmrKeyRe = /^runtimeConfig\./;
|
|
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
|
+
},
|
|
26
|
+
async run({ args }) {
|
|
27
|
+
const rootDir = resolve(args.dir || args._dir || ".");
|
|
28
|
+
let apibara;
|
|
29
|
+
let childProcess;
|
|
30
|
+
const reload = async () => {
|
|
31
|
+
if (apibara) {
|
|
32
|
+
apibara.logger.info("Restarting dev server");
|
|
33
|
+
if ("unwatch" in apibara.options._c12) {
|
|
34
|
+
await apibara.options._c12.unwatch();
|
|
35
|
+
}
|
|
36
|
+
await apibara.close();
|
|
37
|
+
}
|
|
38
|
+
apibara = await createApibara(
|
|
39
|
+
{
|
|
40
|
+
rootDir
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
watch: true,
|
|
44
|
+
c12: {
|
|
45
|
+
async onUpdate({ getDiff, newConfig }) {
|
|
46
|
+
const diff = getDiff();
|
|
47
|
+
if (diff.length === 0) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
apibara.logger.info(
|
|
51
|
+
`Config updated:
|
|
52
|
+
${diff.map((entry) => ` ${entry.toString()}`).join("\n")}`
|
|
53
|
+
);
|
|
54
|
+
await (diff.every((e) => hmrKeyRe.test(e.key)) ? apibara.updateConfig(newConfig.config || {}) : reload());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
true
|
|
59
|
+
);
|
|
60
|
+
apibara.hooks.hookOnce("restart", reload);
|
|
61
|
+
apibara.options.entry = join(runtimeDir, "dev.mjs");
|
|
62
|
+
await prepare(apibara);
|
|
63
|
+
await writeTypes(apibara);
|
|
64
|
+
await build(apibara);
|
|
65
|
+
apibara.hooks.hook("dev:restart", () => {
|
|
66
|
+
if (childProcess) {
|
|
67
|
+
apibara.logger.info("Change detected, stopping indexers to restart");
|
|
68
|
+
childProcess.kill();
|
|
69
|
+
childProcess = void 0;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
apibara.hooks.hook("dev:reload", () => {
|
|
73
|
+
if (childProcess) {
|
|
74
|
+
childProcess.kill();
|
|
75
|
+
} else {
|
|
76
|
+
apibara.logger.success("Restarting indexers");
|
|
77
|
+
}
|
|
78
|
+
const childArgs = [
|
|
79
|
+
resolve(apibara.options.outputDir || "./.apibara/build", "dev.mjs"),
|
|
80
|
+
"start",
|
|
81
|
+
...args.indexers ? ["--indexers", args.indexers] : [],
|
|
82
|
+
...args.preset ? ["--preset", args.preset] : []
|
|
83
|
+
];
|
|
84
|
+
childProcess = spawn("node", childArgs, {
|
|
85
|
+
stdio: "inherit"
|
|
86
|
+
});
|
|
87
|
+
childProcess.on("close", (code) => {
|
|
88
|
+
if (code !== null) {
|
|
89
|
+
apibara.logger.log(
|
|
90
|
+
`Indexers process exited with code ${colors.red(code)}`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
await reload();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export { dev as default };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createApibara, writeTypes } from 'apibara/core';
|
|
2
|
+
import { defineCommand } from 'citty';
|
|
3
|
+
import { resolve } from 'pathe';
|
|
4
|
+
import { c as commonArgs } from '../shared/apibara.1b515d04.mjs';
|
|
5
|
+
|
|
6
|
+
const prepare = defineCommand({
|
|
7
|
+
meta: {
|
|
8
|
+
name: "prepare",
|
|
9
|
+
description: "Generate types for the project"
|
|
10
|
+
},
|
|
11
|
+
args: {
|
|
12
|
+
...commonArgs
|
|
13
|
+
},
|
|
14
|
+
async run({ args }) {
|
|
15
|
+
const rootDir = resolve(args.dir || ".");
|
|
16
|
+
const apibara = await createApibara({ rootDir });
|
|
17
|
+
await writeTypes(apibara);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export { prepare as default };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createApibara } from 'apibara/core';
|
|
3
|
+
import { defineCommand } from 'citty';
|
|
4
|
+
import fse from 'fs-extra';
|
|
5
|
+
import { resolve } from 'pathe';
|
|
6
|
+
import { c as commonArgs } from '../shared/apibara.1b515d04.mjs';
|
|
7
|
+
|
|
8
|
+
const start = defineCommand({
|
|
9
|
+
meta: {
|
|
10
|
+
name: "start",
|
|
11
|
+
description: "Start one indexer"
|
|
12
|
+
},
|
|
13
|
+
args: {
|
|
14
|
+
...commonArgs,
|
|
15
|
+
indexer: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "The indexer to start",
|
|
18
|
+
required: true
|
|
19
|
+
},
|
|
20
|
+
preset: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "The preset to use"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
async run({ args }) {
|
|
26
|
+
const { indexer, preset } = args;
|
|
27
|
+
const rootDir = resolve(args.dir || args._dir || ".");
|
|
28
|
+
const apibara = await createApibara({
|
|
29
|
+
rootDir
|
|
30
|
+
});
|
|
31
|
+
apibara.logger.start(
|
|
32
|
+
`Starting indexer ${indexer}${preset ? ` with preset ${preset}` : ""}`
|
|
33
|
+
);
|
|
34
|
+
const outputDir = apibara.options.outputDir || "./.apibara/build";
|
|
35
|
+
const entry = resolve(outputDir, "start.mjs");
|
|
36
|
+
if (!fse.existsSync(entry)) {
|
|
37
|
+
apibara.logger.error(
|
|
38
|
+
`Output directory ${outputDir} does not exist. Try building the indexer with "apibara build" first.`
|
|
39
|
+
);
|
|
40
|
+
return process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
await apibara.close();
|
|
43
|
+
const childArgs = [
|
|
44
|
+
entry,
|
|
45
|
+
"start",
|
|
46
|
+
"--indexer",
|
|
47
|
+
indexer,
|
|
48
|
+
...preset ? ["--preset", preset] : []
|
|
49
|
+
];
|
|
50
|
+
spawn("node", childArgs, {
|
|
51
|
+
stdio: "inherit"
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export { start as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineCommand, runMain } from 'citty';
|
|
3
|
+
|
|
4
|
+
const mainCli = defineCommand({
|
|
5
|
+
meta: {
|
|
6
|
+
name: "apibara",
|
|
7
|
+
description: "Apibara CLI",
|
|
8
|
+
version: "2.0.0"
|
|
9
|
+
},
|
|
10
|
+
subCommands: {
|
|
11
|
+
dev: () => import('../chunks/dev.mjs').then((r) => r.default),
|
|
12
|
+
build: () => import('../chunks/build.mjs').then((r) => r.default),
|
|
13
|
+
start: () => import('../chunks/start.mjs').then((r) => r.default),
|
|
14
|
+
prepare: () => import('../chunks/prepare.mjs').then((r) => r.default)
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
runMain(mainCli);
|
|
18
|
+
|
|
19
|
+
export { mainCli };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DeepPartial, ApibaraConfig } from 'apibara/types';
|
|
2
|
+
|
|
3
|
+
declare function defineConfig<T extends Record<string, DeepPartial<Pick<ApibaraConfig<T, R>, "runtimeConfig">>> = Record<string, never>, R extends Record<string, unknown> = Record<string, never>>(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<Pick<ApibaraConfig<T, R>, "runtimeConfig">>> = Record<string, never>, R extends Record<string, unknown> = Record<string, never>>(config: ApibaraConfig<T, R>): ApibaraConfig<T, R>;
|
|
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,310 @@
|
|
|
1
|
+
import consola from 'consola';
|
|
2
|
+
import { createHooks } from 'hookable';
|
|
3
|
+
import { watchConfig, loadConfig } from 'c12';
|
|
4
|
+
import { klona } from 'klona/full';
|
|
5
|
+
import { resolve, join, basename, isAbsolute, relative, dirname } from 'pathe';
|
|
6
|
+
import defu from 'defu';
|
|
7
|
+
import fse from 'fs-extra';
|
|
8
|
+
import { getRollupConfig } from 'apibara/rollup';
|
|
9
|
+
import { watch } from 'chokidar';
|
|
10
|
+
import { debounce } from 'perfect-debounce';
|
|
11
|
+
import * as rollup from 'rollup';
|
|
12
|
+
import { rollup as rollup$1 } from 'rollup';
|
|
13
|
+
import { colors } from 'consola/utils';
|
|
14
|
+
import fsp from 'node:fs/promises';
|
|
15
|
+
import { generateTypes, resolveSchema } from 'untyped';
|
|
16
|
+
|
|
17
|
+
const ApibaraDefaults = {
|
|
18
|
+
rootDir: ".",
|
|
19
|
+
indexersDir: "indexers",
|
|
20
|
+
runtimeConfig: {},
|
|
21
|
+
hooks: {},
|
|
22
|
+
buildDir: ".apibara",
|
|
23
|
+
typescript: {
|
|
24
|
+
strict: false,
|
|
25
|
+
generateRuntimeConfigTypes: true,
|
|
26
|
+
internalPaths: false
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
async function resolvePathOptions(options) {
|
|
31
|
+
options.rootDir = resolve(options.rootDir || ".");
|
|
32
|
+
for (const key of ["buildDir"]) {
|
|
33
|
+
options[key] = resolve(options.rootDir, options[key]);
|
|
34
|
+
}
|
|
35
|
+
if (!options.outputDir) {
|
|
36
|
+
options.outputDir = resolve(options.rootDir, ".apibara/build");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function presetResolver(options) {
|
|
41
|
+
if (options.preset && options.presets?.[options.preset]) {
|
|
42
|
+
const new_options = defu(options.presets[options.preset], options);
|
|
43
|
+
Object.assign(options, new_options);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function resolveRuntimeConfigOptions(options) {
|
|
48
|
+
options.runtimeConfig = { ...options.runtimeConfig };
|
|
49
|
+
process.env.APIBARA_RUNTIME_CONFIG = JSON.stringify(options.runtimeConfig);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const configResolvers = [
|
|
53
|
+
resolvePathOptions,
|
|
54
|
+
resolveRuntimeConfigOptions,
|
|
55
|
+
presetResolver
|
|
56
|
+
];
|
|
57
|
+
async function loadOptions(configOverrides = {}, opts = {}, dev = false) {
|
|
58
|
+
const options = await _loadUserConfig(configOverrides, opts, dev);
|
|
59
|
+
for (const resolver of configResolvers) {
|
|
60
|
+
await resolver(options);
|
|
61
|
+
}
|
|
62
|
+
return options;
|
|
63
|
+
}
|
|
64
|
+
async function _loadUserConfig(configOverrides = {}, opts = {}, dev = false) {
|
|
65
|
+
configOverrides = klona(configOverrides);
|
|
66
|
+
const loadedConfig = await (opts.watch ? watchConfig : loadConfig)({
|
|
67
|
+
name: "apibara",
|
|
68
|
+
dotenv: dev,
|
|
69
|
+
cwd: configOverrides.rootDir,
|
|
70
|
+
overrides: {
|
|
71
|
+
...configOverrides
|
|
72
|
+
},
|
|
73
|
+
defaults: { ...ApibaraDefaults },
|
|
74
|
+
...opts.c12
|
|
75
|
+
});
|
|
76
|
+
const options = klona(loadedConfig.config);
|
|
77
|
+
options._config = configOverrides;
|
|
78
|
+
options._c12 = loadedConfig;
|
|
79
|
+
if (dev) {
|
|
80
|
+
options.dev = dev;
|
|
81
|
+
}
|
|
82
|
+
return options;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function updateApibaraConfig(apibara, _config) {
|
|
86
|
+
await apibara.hooks.callHook("rollup:reload");
|
|
87
|
+
apibara.logger.success("Apibara config hot reloaded!");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const INDEXER_EXTENSIONS = [".indexer.ts", ".indexer.js"];
|
|
91
|
+
async function scanIndexers(apibara) {
|
|
92
|
+
apibara.logger.debug("Scanning indexers");
|
|
93
|
+
const indexersDir = join(
|
|
94
|
+
apibara.options.rootDir,
|
|
95
|
+
apibara.options.indexersDir
|
|
96
|
+
);
|
|
97
|
+
if (!fse.existsSync(indexersDir)) {
|
|
98
|
+
throw new Error(`Indexers directory not found: ${indexersDir}`);
|
|
99
|
+
}
|
|
100
|
+
apibara.indexers = [];
|
|
101
|
+
for (const file of fse.readdirSync(indexersDir)) {
|
|
102
|
+
const indexerName = indexerNameFromFile(file);
|
|
103
|
+
if (indexerName) {
|
|
104
|
+
apibara.indexers.push({
|
|
105
|
+
name: indexerName,
|
|
106
|
+
indexer: join(indexersDir, file)
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
apibara.logger.debug(`Found ${apibara.indexers.length} indexers`);
|
|
111
|
+
}
|
|
112
|
+
function indexerNameFromFile(file) {
|
|
113
|
+
for (const extension of INDEXER_EXTENSIONS) {
|
|
114
|
+
if (file.endsWith(extension)) {
|
|
115
|
+
return basename(file, extension);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function createApibara(config = {}, opts = {}, dev = false) {
|
|
121
|
+
const options = await loadOptions(config, opts, dev);
|
|
122
|
+
const apibara = {
|
|
123
|
+
options,
|
|
124
|
+
indexers: [],
|
|
125
|
+
hooks: createHooks(),
|
|
126
|
+
close: () => apibara.hooks.callHook("close"),
|
|
127
|
+
logger: consola.withTag("apibara"),
|
|
128
|
+
async updateConfig(config2) {
|
|
129
|
+
updateApibaraConfig(apibara);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
apibara.hooks.addHooks(apibara.options.hooks);
|
|
133
|
+
await scanIndexers(apibara);
|
|
134
|
+
return apibara;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function formatRollupError(_error) {
|
|
138
|
+
try {
|
|
139
|
+
const logs = [_error.toString()];
|
|
140
|
+
const errors = _error?.errors || [_error];
|
|
141
|
+
for (const error of errors) {
|
|
142
|
+
const id = error.path || error.id || _error.id;
|
|
143
|
+
let path = isAbsolute(id) ? relative(process.cwd(), id) : id;
|
|
144
|
+
const location = error.loc || error.location;
|
|
145
|
+
if (location) {
|
|
146
|
+
path += `:${location.line}:${location.column}`;
|
|
147
|
+
}
|
|
148
|
+
const text = error.text || error.frame;
|
|
149
|
+
logs.push(
|
|
150
|
+
// biome-ignore lint/style/useTemplate: <explanation>
|
|
151
|
+
`Rollup error while processing \`${path}\`` + text ? "\n\n" + text : ""
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
return logs.join("\n");
|
|
155
|
+
} catch {
|
|
156
|
+
return _error?.toString();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function watchDev(apibara, rollupConfig) {
|
|
161
|
+
let rollupWatcher;
|
|
162
|
+
async function load() {
|
|
163
|
+
if (rollupWatcher) {
|
|
164
|
+
await rollupWatcher.close();
|
|
165
|
+
}
|
|
166
|
+
rollupWatcher = startRollupWatcher(apibara, rollupConfig);
|
|
167
|
+
}
|
|
168
|
+
const reload = debounce(load);
|
|
169
|
+
const watchPatterns = [join(apibara.options.rootDir, "indexers")];
|
|
170
|
+
const watchReloadEvents = /* @__PURE__ */ new Set(["add", "addDir", "unlink", "unlinkDir"]);
|
|
171
|
+
const reloadWatcher = watch(watchPatterns, { ignoreInitial: true }).on(
|
|
172
|
+
"all",
|
|
173
|
+
(event) => {
|
|
174
|
+
if (watchReloadEvents.has(event)) {
|
|
175
|
+
reload();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
apibara.hooks.hook("close", () => {
|
|
180
|
+
rollupWatcher.close();
|
|
181
|
+
reloadWatcher.close();
|
|
182
|
+
});
|
|
183
|
+
apibara.hooks.hook("rollup:reload", () => reload());
|
|
184
|
+
await load();
|
|
185
|
+
}
|
|
186
|
+
function startRollupWatcher(apibara, rollupConfig) {
|
|
187
|
+
const watcher = rollup.watch(
|
|
188
|
+
defu(rollupConfig, {
|
|
189
|
+
watch: {
|
|
190
|
+
chokidar: apibara.options.watchOptions
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
);
|
|
194
|
+
let start;
|
|
195
|
+
watcher.on("event", (event) => {
|
|
196
|
+
switch (event.code) {
|
|
197
|
+
case "START": {
|
|
198
|
+
apibara.hooks.callHook("dev:restart");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
case "BUNDLE_START": {
|
|
202
|
+
start = Date.now();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
case "END": {
|
|
206
|
+
apibara.hooks.callHook("compiled", apibara);
|
|
207
|
+
apibara.logger.success(
|
|
208
|
+
"Indexers built",
|
|
209
|
+
start ? `in ${Date.now() - start} ms` : ""
|
|
210
|
+
);
|
|
211
|
+
apibara.hooks.callHook("dev:reload");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
case "ERROR": {
|
|
215
|
+
apibara.logger.error(formatRollupError(event.error));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
return watcher;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function buildProduction(apibara, rollupConfig) {
|
|
223
|
+
apibara.logger.start(
|
|
224
|
+
`Building ${colors.cyan(apibara.indexers.length)} indexers`
|
|
225
|
+
);
|
|
226
|
+
try {
|
|
227
|
+
const bundle = await rollup$1(rollupConfig);
|
|
228
|
+
if (Array.isArray(rollupConfig.output)) {
|
|
229
|
+
for (const outputOptions of rollupConfig.output) {
|
|
230
|
+
await bundle.write(outputOptions);
|
|
231
|
+
}
|
|
232
|
+
} else if (rollupConfig.output) {
|
|
233
|
+
await bundle.write(rollupConfig.output);
|
|
234
|
+
} else {
|
|
235
|
+
throw new Error("No output options specified in Rollup config");
|
|
236
|
+
}
|
|
237
|
+
await bundle.close();
|
|
238
|
+
apibara.logger.success("Build succeeded!");
|
|
239
|
+
apibara.logger.info(
|
|
240
|
+
`You can start the indexers with ${colors.cyan("apibara start")}`
|
|
241
|
+
);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
apibara.logger.error("Build failed", error);
|
|
244
|
+
throw error;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function build(apibara) {
|
|
249
|
+
const rollupConfig = getRollupConfig(apibara);
|
|
250
|
+
await apibara.hooks.callHook("rollup:before", apibara, rollupConfig);
|
|
251
|
+
return apibara.options.dev ? await watchDev(apibara, rollupConfig) : await buildProduction(apibara, rollupConfig);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function prettyPath(path, highlight = true) {
|
|
255
|
+
const rel = relative(process.cwd(), path);
|
|
256
|
+
return highlight ? colors.cyan(rel) : rel;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async function prepare(apibara) {
|
|
260
|
+
await prepareDir(apibara.options.buildDir);
|
|
261
|
+
await prepareDir(apibara.options.outputDir);
|
|
262
|
+
apibara.logger.success(
|
|
263
|
+
`Output directory ${prettyPath(apibara.options.outputDir)} cleaned`
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
async function prepareDir(dir) {
|
|
267
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
268
|
+
await fse.emptyDir(dir);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async function writeTypes(apibara) {
|
|
272
|
+
const typesDir = resolve(apibara.options.buildDir, "types");
|
|
273
|
+
const config = [
|
|
274
|
+
"// Generated by apibara",
|
|
275
|
+
`
|
|
276
|
+
declare module "apibara/types" {`,
|
|
277
|
+
apibara.options.typescript.generateRuntimeConfigTypes ? generateTypes(
|
|
278
|
+
await resolveSchema(
|
|
279
|
+
Object.fromEntries(
|
|
280
|
+
Object.entries(apibara.options.runtimeConfig)
|
|
281
|
+
)
|
|
282
|
+
),
|
|
283
|
+
{
|
|
284
|
+
interfaceName: "ApibaraRuntimeConfig",
|
|
285
|
+
addExport: false,
|
|
286
|
+
addDefaults: false,
|
|
287
|
+
allowExtraKeys: false,
|
|
288
|
+
indentation: 2
|
|
289
|
+
}
|
|
290
|
+
) : "",
|
|
291
|
+
"}",
|
|
292
|
+
// Makes this a module for augmentation purposes
|
|
293
|
+
"export type {};"
|
|
294
|
+
];
|
|
295
|
+
const buildFiles = [];
|
|
296
|
+
buildFiles.push({
|
|
297
|
+
path: join(typesDir, "apibara-config.d.ts"),
|
|
298
|
+
contents: config.join("\n")
|
|
299
|
+
});
|
|
300
|
+
await Promise.all(
|
|
301
|
+
buildFiles.map(async (file) => {
|
|
302
|
+
const _file = resolve(apibara.options.buildDir, file.path);
|
|
303
|
+
await fsp.mkdir(dirname(_file), { recursive: true });
|
|
304
|
+
await fsp.writeFile(_file, file.contents);
|
|
305
|
+
})
|
|
306
|
+
);
|
|
307
|
+
apibara.logger.success(`Types written to ${prettyPath(typesDir)}`);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export { build, createApibara, prepare, writeTypes };
|