apibara 2.0.0-beta.4 → 2.0.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.
Files changed (85) hide show
  1. package/dist/chunks/add.mjs +44 -0
  2. package/dist/chunks/build.mjs +28 -0
  3. package/dist/chunks/dev.mjs +100 -0
  4. package/dist/chunks/init.mjs +41 -0
  5. package/dist/chunks/prepare.mjs +21 -0
  6. package/dist/chunks/start.mjs +56 -0
  7. package/dist/cli/index.d.mts +5 -0
  8. package/dist/cli/index.d.ts +5 -0
  9. package/dist/cli/index.mjs +21 -0
  10. package/dist/config/index.d.mts +5 -0
  11. package/dist/config/index.d.ts +5 -0
  12. package/dist/config/index.mjs +5 -0
  13. package/dist/core/index.d.mts +11 -0
  14. package/dist/core/index.d.ts +11 -0
  15. package/dist/core/index.mjs +309 -0
  16. package/dist/create/index.d.mts +17 -0
  17. package/dist/create/index.d.ts +17 -0
  18. package/dist/create/index.mjs +958 -0
  19. package/dist/hooks/index.d.mts +5 -0
  20. package/dist/hooks/index.d.ts +5 -0
  21. package/dist/hooks/index.mjs +5 -0
  22. package/dist/rollup/index.d.mts +6 -0
  23. package/dist/rollup/index.d.ts +6 -0
  24. package/dist/rollup/index.mjs +150 -0
  25. package/dist/runtime/dev.d.ts +3 -0
  26. package/dist/runtime/dev.mjs +55 -0
  27. package/dist/runtime/index.d.ts +2 -0
  28. package/dist/runtime/index.mjs +2 -0
  29. package/dist/runtime/internal/app.d.ts +2 -0
  30. package/dist/runtime/internal/app.mjs +56 -0
  31. package/dist/runtime/internal/logger.d.ts +14 -0
  32. package/dist/runtime/internal/logger.mjs +45 -0
  33. package/dist/runtime/start.d.ts +3 -0
  34. package/dist/runtime/start.mjs +41 -0
  35. package/dist/shared/apibara.1b515d04.mjs +8 -0
  36. package/dist/types/index.d.mts +90 -0
  37. package/dist/types/index.d.ts +90 -0
  38. package/dist/types/index.mjs +1 -0
  39. package/package.json +36 -8
  40. package/runtime-meta.d.ts +2 -0
  41. package/runtime-meta.mjs +7 -0
  42. package/src/cli/commands/add.ts +44 -0
  43. package/src/cli/commands/build.ts +5 -3
  44. package/src/cli/commands/dev.ts +29 -19
  45. package/src/cli/commands/init.ts +40 -0
  46. package/src/cli/commands/prepare.ts +0 -2
  47. package/src/cli/commands/start.ts +61 -0
  48. package/src/cli/index.ts +3 -0
  49. package/src/config/index.ts +5 -4
  50. package/src/core/apibara.ts +4 -2
  51. package/src/core/build/build.ts +2 -0
  52. package/src/core/build/dev.ts +1 -0
  53. package/src/core/build/error.ts +0 -1
  54. package/src/core/build/prepare.ts +5 -2
  55. package/src/core/build/prod.ts +10 -6
  56. package/src/core/build/types.ts +4 -95
  57. package/src/core/config/defaults.ts +1 -4
  58. package/src/core/config/loader.ts +1 -0
  59. package/src/core/config/resolvers/runtime-config.resolver.ts +1 -1
  60. package/src/core/config/update.ts +2 -3
  61. package/src/core/path.ts +11 -0
  62. package/src/core/scan.ts +40 -0
  63. package/src/create/add.ts +225 -0
  64. package/src/create/colors.ts +15 -0
  65. package/src/create/constants.ts +98 -0
  66. package/src/create/index.ts +2 -0
  67. package/src/create/init.ts +164 -0
  68. package/src/create/templates.ts +462 -0
  69. package/src/create/types.ts +34 -0
  70. package/src/create/utils.ts +412 -0
  71. package/src/rollup/config.ts +67 -188
  72. package/src/rollup/index.ts +1 -0
  73. package/src/rollup/plugins/config.ts +12 -0
  74. package/src/rollup/plugins/esm-shim.ts +69 -0
  75. package/src/rollup/plugins/indexers.ts +17 -0
  76. package/src/runtime/dev.ts +64 -0
  77. package/src/runtime/index.ts +2 -0
  78. package/src/runtime/internal/app.ts +78 -0
  79. package/src/runtime/internal/logger.ts +70 -0
  80. package/src/runtime/start.ts +48 -0
  81. package/src/types/apibara.ts +8 -0
  82. package/src/types/config.ts +28 -27
  83. package/src/types/hooks.ts +1 -0
  84. package/src/types/virtual/config.d.ts +3 -0
  85. package/src/types/virtual/indexers.d.ts +10 -0
@@ -0,0 +1,44 @@
1
+ import { addIndexer } from 'apibara/create';
2
+ import { defineCommand } from 'citty';
3
+
4
+ const add = defineCommand({
5
+ meta: {
6
+ name: "add",
7
+ description: "apibara add helps you add a new indexer to your project with sensible defaults."
8
+ },
9
+ args: {
10
+ indexerId: {
11
+ type: "positional",
12
+ description: "Indexer ID",
13
+ required: false
14
+ },
15
+ chain: {
16
+ type: "string",
17
+ description: "Chain"
18
+ },
19
+ network: {
20
+ type: "string",
21
+ description: "Network"
22
+ },
23
+ storage: {
24
+ type: "string",
25
+ description: "Storage"
26
+ },
27
+ dnaUrl: {
28
+ type: "string",
29
+ description: "DNA URL"
30
+ }
31
+ },
32
+ async run({ args }) {
33
+ const { indexerId, chain, network, storage, dnaUrl } = args;
34
+ await addIndexer({
35
+ argIndexerId: indexerId,
36
+ argChain: chain,
37
+ argNetwork: network,
38
+ argStorage: storage,
39
+ argDnaUrl: dnaUrl
40
+ });
41
+ }
42
+ });
43
+
44
+ export { add as default };
@@ -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,41 @@
1
+ import { initializeProject } from 'apibara/create';
2
+ import { defineCommand } from 'citty';
3
+
4
+ const init = defineCommand({
5
+ meta: {
6
+ name: "init",
7
+ description: "Initialize a new Apibara project"
8
+ },
9
+ args: {
10
+ dir: {
11
+ type: "positional",
12
+ description: "Target path to initialize the project",
13
+ required: true
14
+ },
15
+ language: {
16
+ type: "string",
17
+ description: "Language to use: typescript, ts or javascript, js",
18
+ default: "ts",
19
+ alias: "l"
20
+ },
21
+ "no-create-indexer": {
22
+ type: "boolean",
23
+ description: "Do not create an indexer after initialization",
24
+ default: false
25
+ }
26
+ },
27
+ async run({ args }) {
28
+ const {
29
+ dir: targetDir,
30
+ "no-create-indexer": noCreateIndexer,
31
+ language
32
+ } = args;
33
+ await initializeProject({
34
+ argTargetDir: targetDir,
35
+ argLanguage: language,
36
+ argNoCreateIndexer: noCreateIndexer
37
+ });
38
+ }
39
+ });
40
+
41
+ export { init 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,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,21 @@
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
+ init: () => import('../chunks/init.mjs').then((r) => r.default),
16
+ add: () => import('../chunks/add.mjs').then((r) => r.default)
17
+ }
18
+ });
19
+ runMain(mainCli);
20
+
21
+ 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,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,309 @@
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
+ `Rollup error while processing \`${path}\`` + text ? "\n\n" + text : ""
151
+ );
152
+ }
153
+ return logs.join("\n");
154
+ } catch {
155
+ return _error?.toString();
156
+ }
157
+ }
158
+
159
+ async function watchDev(apibara, rollupConfig) {
160
+ let rollupWatcher;
161
+ async function load() {
162
+ if (rollupWatcher) {
163
+ await rollupWatcher.close();
164
+ }
165
+ rollupWatcher = startRollupWatcher(apibara, rollupConfig);
166
+ }
167
+ const reload = debounce(load);
168
+ const watchPatterns = [join(apibara.options.rootDir, "indexers")];
169
+ const watchReloadEvents = /* @__PURE__ */ new Set(["add", "addDir", "unlink", "unlinkDir"]);
170
+ const reloadWatcher = watch(watchPatterns, { ignoreInitial: true }).on(
171
+ "all",
172
+ (event) => {
173
+ if (watchReloadEvents.has(event)) {
174
+ reload();
175
+ }
176
+ }
177
+ );
178
+ apibara.hooks.hook("close", () => {
179
+ rollupWatcher.close();
180
+ reloadWatcher.close();
181
+ });
182
+ apibara.hooks.hook("rollup:reload", () => reload());
183
+ await load();
184
+ }
185
+ function startRollupWatcher(apibara, rollupConfig) {
186
+ const watcher = rollup.watch(
187
+ defu(rollupConfig, {
188
+ watch: {
189
+ chokidar: apibara.options.watchOptions
190
+ }
191
+ })
192
+ );
193
+ let start;
194
+ watcher.on("event", (event) => {
195
+ switch (event.code) {
196
+ case "START": {
197
+ apibara.hooks.callHook("dev:restart");
198
+ return;
199
+ }
200
+ case "BUNDLE_START": {
201
+ start = Date.now();
202
+ return;
203
+ }
204
+ case "END": {
205
+ apibara.hooks.callHook("compiled", apibara);
206
+ apibara.logger.success(
207
+ "Indexers built",
208
+ start ? `in ${Date.now() - start} ms` : ""
209
+ );
210
+ apibara.hooks.callHook("dev:reload");
211
+ return;
212
+ }
213
+ case "ERROR": {
214
+ apibara.logger.error(formatRollupError(event.error));
215
+ }
216
+ }
217
+ });
218
+ return watcher;
219
+ }
220
+
221
+ async function buildProduction(apibara, rollupConfig) {
222
+ apibara.logger.start(
223
+ `Building ${colors.cyan(apibara.indexers.length)} indexers`
224
+ );
225
+ try {
226
+ const bundle = await rollup$1(rollupConfig);
227
+ if (Array.isArray(rollupConfig.output)) {
228
+ for (const outputOptions of rollupConfig.output) {
229
+ await bundle.write(outputOptions);
230
+ }
231
+ } else if (rollupConfig.output) {
232
+ await bundle.write(rollupConfig.output);
233
+ } else {
234
+ throw new Error("No output options specified in Rollup config");
235
+ }
236
+ await bundle.close();
237
+ apibara.logger.success("Build succeeded!");
238
+ apibara.logger.info(
239
+ `You can start the indexers with ${colors.cyan("apibara start")}`
240
+ );
241
+ } catch (error) {
242
+ apibara.logger.error("Build failed", error);
243
+ throw error;
244
+ }
245
+ }
246
+
247
+ async function build(apibara) {
248
+ const rollupConfig = getRollupConfig(apibara);
249
+ await apibara.hooks.callHook("rollup:before", apibara, rollupConfig);
250
+ return apibara.options.dev ? await watchDev(apibara, rollupConfig) : await buildProduction(apibara, rollupConfig);
251
+ }
252
+
253
+ function prettyPath(path, highlight = true) {
254
+ const rel = relative(process.cwd(), path);
255
+ return highlight ? colors.cyan(rel) : rel;
256
+ }
257
+
258
+ async function prepare(apibara) {
259
+ await prepareDir(apibara.options.buildDir);
260
+ await prepareDir(apibara.options.outputDir);
261
+ apibara.logger.success(
262
+ `Output directory ${prettyPath(apibara.options.outputDir)} cleaned`
263
+ );
264
+ }
265
+ async function prepareDir(dir) {
266
+ await fsp.mkdir(dir, { recursive: true });
267
+ await fse.emptyDir(dir);
268
+ }
269
+
270
+ async function writeTypes(apibara) {
271
+ const typesDir = resolve(apibara.options.buildDir, "types");
272
+ const config = [
273
+ "// Generated by apibara",
274
+ `
275
+ declare module "apibara/types" {`,
276
+ apibara.options.typescript.generateRuntimeConfigTypes ? generateTypes(
277
+ await resolveSchema(
278
+ Object.fromEntries(
279
+ Object.entries(apibara.options.runtimeConfig)
280
+ )
281
+ ),
282
+ {
283
+ interfaceName: "ApibaraRuntimeConfig",
284
+ addExport: false,
285
+ addDefaults: false,
286
+ allowExtraKeys: false,
287
+ indentation: 2
288
+ }
289
+ ) : "",
290
+ "}",
291
+ // Makes this a module for augmentation purposes
292
+ "export type {};"
293
+ ];
294
+ const buildFiles = [];
295
+ buildFiles.push({
296
+ path: join(typesDir, "apibara-config.d.ts"),
297
+ contents: config.join("\n")
298
+ });
299
+ await Promise.all(
300
+ buildFiles.map(async (file) => {
301
+ const _file = resolve(apibara.options.buildDir, file.path);
302
+ await fsp.mkdir(dirname(_file), { recursive: true });
303
+ await fsp.writeFile(_file, file.contents);
304
+ })
305
+ );
306
+ apibara.logger.success(`Types written to ${prettyPath(typesDir)}`);
307
+ }
308
+
309
+ export { build, createApibara, prepare, writeTypes };