apibara 2.1.0-beta.3 → 2.1.0-beta.30
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/build.mjs +4 -2
- package/dist/chunks/dev.mjs +44 -14
- package/dist/chunks/init.mjs +11 -7
- package/dist/chunks/prepare.mjs +4 -2
- package/dist/chunks/start.mjs +14 -4
- package/dist/chunks/write-project-info.mjs +50 -0
- package/dist/cli/index.mjs +2 -1
- package/dist/core/index.mjs +98 -68
- package/dist/create/index.d.mts +2 -1
- package/dist/create/index.d.ts +2 -1
- package/dist/create/index.mjs +142 -112
- package/dist/hooks/index.mjs +1 -1
- package/dist/rolldown/index.d.mts +7 -0
- package/dist/rolldown/index.d.ts +7 -0
- package/dist/rolldown/index.mjs +159 -0
- package/dist/runtime/dev.mjs +14 -4
- package/dist/runtime/internal/app.d.ts +6 -1
- package/dist/runtime/internal/app.mjs +50 -19
- package/dist/runtime/internal/helper.d.ts +12 -0
- package/dist/runtime/internal/helper.mjs +33 -0
- package/dist/runtime/project-info.d.ts +3 -0
- package/dist/runtime/project-info.mjs +53 -0
- package/dist/runtime/start.mjs +18 -4
- package/dist/shared/apibara.63c9a277.mjs +29 -0
- package/dist/shared/apibara.730bb1e4.mjs +17 -0
- package/dist/types/index.d.mts +23 -19
- package/dist/types/index.d.ts +23 -19
- package/package.json +13 -16
- package/src/cli/commands/add.ts +16 -7
- package/src/cli/commands/build.ts +5 -2
- package/src/cli/commands/dev.ts +56 -13
- package/src/cli/commands/init.ts +12 -7
- package/src/cli/commands/prepare.ts +4 -2
- package/src/cli/commands/start.ts +16 -3
- package/src/cli/commands/write-project-info.ts +56 -0
- package/src/cli/common.ts +33 -1
- package/src/cli/index.ts +2 -0
- package/src/core/apibara.ts +5 -0
- package/src/core/build/build.ts +13 -5
- package/src/core/build/dev.ts +44 -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 +13 -7
- package/src/core/config/resolvers/preset.resolver.ts +3 -0
- package/src/core/config/update.ts +1 -1
- package/src/create/add.ts +10 -9
- package/src/create/constants.ts +10 -11
- package/src/create/init.ts +8 -5
- package/src/create/templates.ts +130 -102
- package/src/hooks/useRuntimeConfig.ts +1 -1
- package/src/rolldown/config.ts +111 -0
- package/src/rolldown/index.ts +2 -0
- package/src/rolldown/plugins/config.ts +17 -0
- package/src/{rollup → rolldown}/plugins/indexers.ts +3 -3
- package/src/rolldown/plugins/instrumentation.ts +68 -0
- package/src/runtime/dev.ts +16 -4
- package/src/runtime/internal/app.ts +66 -25
- package/src/runtime/internal/helper.ts +55 -0
- package/src/runtime/project-info.ts +72 -0
- package/src/runtime/start.ts +21 -4
- package/src/types/config.ts +23 -12
- 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/config.d.ts +4 -1
- package/src/types/virtual/indexers.d.ts +4 -1
- package/src/types/virtual/instrumentation.d.ts +4 -0
- package/dist/rollup/index.d.mts +0 -6
- package/dist/rollup/index.d.ts +0 -6
- package/dist/rollup/index.mjs +0 -150
- package/dist/shared/apibara.1b515d04.mjs +0 -8
- package/src/core/config/resolvers/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
|
@@ -7,14 +7,8 @@ import { loadConfig, watchConfig } from "c12";
|
|
|
7
7
|
import { klona } from "klona/full";
|
|
8
8
|
import { ApibaraDefaults } from "./defaults";
|
|
9
9
|
import { resolvePathOptions } from "./resolvers/paths.resolver";
|
|
10
|
-
import { presetResolver } from "./resolvers/preset.resolver";
|
|
11
|
-
import { resolveRuntimeConfigOptions } from "./resolvers/runtime-config.resolver";
|
|
12
10
|
|
|
13
|
-
const configResolvers = [
|
|
14
|
-
resolvePathOptions,
|
|
15
|
-
resolveRuntimeConfigOptions,
|
|
16
|
-
presetResolver,
|
|
17
|
-
] as const;
|
|
11
|
+
const configResolvers = [resolvePathOptions] as const;
|
|
18
12
|
|
|
19
13
|
export async function loadOptions(
|
|
20
14
|
configOverrides: ApibaraConfig = {},
|
|
@@ -22,9 +16,21 @@ export async function loadOptions(
|
|
|
22
16
|
dev = false,
|
|
23
17
|
): Promise<ApibaraOptions> {
|
|
24
18
|
const options = await _loadUserConfig(configOverrides, opts, dev);
|
|
19
|
+
|
|
20
|
+
// Check if the runtimeConfig is serializable
|
|
21
|
+
try {
|
|
22
|
+
JSON.stringify(options.runtimeConfig);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
"Non-serializable runtimeConfig. Please ensure the config is serializable.",
|
|
26
|
+
{ cause: error },
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
for (const resolver of configResolvers) {
|
|
26
31
|
await resolver(options);
|
|
27
32
|
}
|
|
33
|
+
|
|
28
34
|
return options;
|
|
29
35
|
}
|
|
30
36
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ApibaraOptions } from "apibara/types";
|
|
2
2
|
import defu from "defu";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @note This resolver is not in use currently, as we resolve presets in runtime files.
|
|
6
|
+
*/
|
|
4
7
|
export async function presetResolver(options: ApibaraOptions) {
|
|
5
8
|
if (options.preset && options.presets?.[options.preset]) {
|
|
6
9
|
const new_options = defu(options.presets[options.preset], options);
|
package/src/create/add.ts
CHANGED
|
@@ -37,6 +37,7 @@ type Options = {
|
|
|
37
37
|
argNetwork?: string;
|
|
38
38
|
argStorage?: string;
|
|
39
39
|
argDnaUrl?: string;
|
|
40
|
+
argRootDir?: string;
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
export async function addIndexer({
|
|
@@ -45,8 +46,10 @@ export async function addIndexer({
|
|
|
45
46
|
argNetwork,
|
|
46
47
|
argStorage,
|
|
47
48
|
argDnaUrl,
|
|
49
|
+
argRootDir,
|
|
48
50
|
}: Options) {
|
|
49
|
-
const
|
|
51
|
+
const cwd = path.join(process.cwd(), argRootDir ?? ".");
|
|
52
|
+
const configExists = hasApibaraConfig(cwd);
|
|
50
53
|
|
|
51
54
|
if (!configExists) {
|
|
52
55
|
consola.error("No apibara.config found in the current directory.");
|
|
@@ -74,7 +77,7 @@ export async function addIndexer({
|
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
const language = getApibaraConfigLanguage(
|
|
80
|
+
const language = getApibaraConfigLanguage(cwd);
|
|
78
81
|
|
|
79
82
|
validateIndexerId(argIndexerId, true);
|
|
80
83
|
validateChain(argChain, true);
|
|
@@ -93,7 +96,7 @@ export async function addIndexer({
|
|
|
93
96
|
validateIndexerId(id)
|
|
94
97
|
? checkFileExists(
|
|
95
98
|
path.join(
|
|
96
|
-
|
|
99
|
+
cwd,
|
|
97
100
|
"indexers",
|
|
98
101
|
`${id}.indexer.${language === "typescript" ? "ts" : "js"}`,
|
|
99
102
|
),
|
|
@@ -197,7 +200,7 @@ export async function addIndexer({
|
|
|
197
200
|
const pkgManager = getPackageManager();
|
|
198
201
|
|
|
199
202
|
const options: IndexerOptions = {
|
|
200
|
-
cwd:
|
|
203
|
+
cwd: cwd,
|
|
201
204
|
indexerFileId,
|
|
202
205
|
indexerId: convertKebabToCamelCase(indexerFileId),
|
|
203
206
|
chain: (argChain as Chain) ?? prompt_chain?.name!,
|
|
@@ -228,11 +231,9 @@ export async function addIndexer({
|
|
|
228
231
|
|
|
229
232
|
console.log();
|
|
230
233
|
|
|
234
|
+
const baseCommand = `${options.packageManager} install`;
|
|
235
|
+
const tsCommand = `${baseCommand} && ${options.packageManager} run prepare`;
|
|
231
236
|
consola.info(
|
|
232
|
-
`Before running the indexer, run ${cyan(
|
|
233
|
-
language === "typescript"
|
|
234
|
-
? " & " + cyan(`${options.packageManager} run prepare`)
|
|
235
|
-
: ""
|
|
236
|
-
}`,
|
|
237
|
+
`Before running the indexer, run ${cyan(language === "typescript" ? tsCommand : baseCommand)}`,
|
|
237
238
|
);
|
|
238
239
|
}
|
package/src/create/constants.ts
CHANGED
|
@@ -66,26 +66,25 @@ export const storages: StorageDataType[] = [
|
|
|
66
66
|
|
|
67
67
|
export const packageVersions = {
|
|
68
68
|
// Required Dependencies
|
|
69
|
-
apibara: "
|
|
70
|
-
"@apibara/indexer": "
|
|
71
|
-
"@apibara/protocol": "
|
|
69
|
+
apibara: "next",
|
|
70
|
+
"@apibara/indexer": "next",
|
|
71
|
+
"@apibara/protocol": "next",
|
|
72
72
|
// Chain Dependencies
|
|
73
|
-
"@apibara/evm": "
|
|
74
|
-
"@apibara/beaconchain": "
|
|
75
|
-
"@apibara/starknet": "
|
|
73
|
+
"@apibara/evm": "next",
|
|
74
|
+
"@apibara/beaconchain": "next",
|
|
75
|
+
"@apibara/starknet": "next",
|
|
76
76
|
// Storage Dependencies
|
|
77
|
-
"@apibara/plugin-drizzle": "
|
|
78
|
-
"@apibara/plugin-mongo": "
|
|
79
|
-
"@apibara/plugin-sqlite": "
|
|
77
|
+
"@apibara/plugin-drizzle": "next",
|
|
78
|
+
"@apibara/plugin-mongo": "next",
|
|
79
|
+
"@apibara/plugin-sqlite": "next",
|
|
80
80
|
// Postgres Dependencies
|
|
81
81
|
"@electric-sql/pglite": "^0.2.17",
|
|
82
|
-
"drizzle-orm": "^0.
|
|
82
|
+
"drizzle-orm": "^0.40.1",
|
|
83
83
|
pg: "^8.13.1",
|
|
84
84
|
"@types/pg": "^8.11.10",
|
|
85
85
|
"drizzle-kit": "^0.29.0",
|
|
86
86
|
// Typescript Dependencies
|
|
87
87
|
typescript: "^5.6.2",
|
|
88
|
-
"@rollup/plugin-typescript": "^11.1.6",
|
|
89
88
|
"@types/node": "^20.5.2",
|
|
90
89
|
};
|
|
91
90
|
|
package/src/create/init.ts
CHANGED
|
@@ -5,6 +5,7 @@ import prompts from "prompts";
|
|
|
5
5
|
import { addIndexer } from "./add";
|
|
6
6
|
import { cyan, green } from "./colors";
|
|
7
7
|
import {
|
|
8
|
+
createGitIgnoreFile,
|
|
8
9
|
generateApibaraConfig,
|
|
9
10
|
generatePackageJson,
|
|
10
11
|
generateTsConfig,
|
|
@@ -129,7 +130,7 @@ export async function initializeProject({
|
|
|
129
130
|
JSON.stringify(packageJson, null, 2) + "\n",
|
|
130
131
|
);
|
|
131
132
|
await formatFile(packageJsonPath);
|
|
132
|
-
consola.success("Created
|
|
133
|
+
consola.success("Created", cyan("package.json"));
|
|
133
134
|
|
|
134
135
|
// Generate tsconfig.json if TypeScript
|
|
135
136
|
if (isTs) {
|
|
@@ -137,7 +138,7 @@ export async function initializeProject({
|
|
|
137
138
|
const tsConfig = generateTsConfig();
|
|
138
139
|
fs.writeFileSync(tsConfigPath, JSON.stringify(tsConfig, null, 2) + "\n");
|
|
139
140
|
await formatFile(tsConfigPath);
|
|
140
|
-
consola.success("Created
|
|
141
|
+
consola.success("Created", cyan("tsconfig.json"));
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
const apibaraConfigPath = path.join(root, `apibara.config.${configExt}`);
|
|
@@ -145,7 +146,7 @@ export async function initializeProject({
|
|
|
145
146
|
const apibaraConfig = generateApibaraConfig(isTs);
|
|
146
147
|
fs.writeFileSync(apibaraConfigPath, apibaraConfig);
|
|
147
148
|
await formatFile(apibaraConfigPath);
|
|
148
|
-
consola.success("Created
|
|
149
|
+
consola.success("Created", cyan(`apibara.config.${configExt}`));
|
|
149
150
|
|
|
150
151
|
// Create "indexers" directory if not exists
|
|
151
152
|
const indexersDir = path.join(root, "indexers");
|
|
@@ -154,6 +155,8 @@ export async function initializeProject({
|
|
|
154
155
|
consola.success(`Created ${cyan("indexers")} directory`);
|
|
155
156
|
}
|
|
156
157
|
|
|
158
|
+
await createGitIgnoreFile(root);
|
|
159
|
+
|
|
157
160
|
console.log("\n");
|
|
158
161
|
|
|
159
162
|
consola.ready(green("Project initialized successfully"));
|
|
@@ -163,12 +166,12 @@ export async function initializeProject({
|
|
|
163
166
|
if (!argNoCreateIndexer) {
|
|
164
167
|
consola.info("Let's create an indexer\n");
|
|
165
168
|
|
|
166
|
-
await addIndexer({});
|
|
169
|
+
await addIndexer({ argRootDir: argTargetDir });
|
|
167
170
|
} else {
|
|
168
171
|
const pkgManager = getPackageManager();
|
|
169
172
|
consola.info(
|
|
170
173
|
"Run ",
|
|
171
|
-
green(`${pkgManager.name}
|
|
174
|
+
green(`${pkgManager.name} install`),
|
|
172
175
|
" to install all dependencies",
|
|
173
176
|
);
|
|
174
177
|
}
|
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,7 +15,7 @@ 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",
|
|
@@ -27,8 +28,6 @@ export function generatePackageJson(isTypeScript: boolean) {
|
|
|
27
28
|
},
|
|
28
29
|
devDependencies: {
|
|
29
30
|
...(isTypeScript && {
|
|
30
|
-
"@rollup/plugin-typescript":
|
|
31
|
-
packageVersions["@rollup/plugin-typescript"],
|
|
32
31
|
"@types/node": packageVersions["@types/node"],
|
|
33
32
|
typescript: packageVersions.typescript,
|
|
34
33
|
}),
|
|
@@ -58,17 +57,10 @@ export function generateTsConfig() {
|
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
export function generateApibaraConfig(isTypeScript: boolean) {
|
|
61
|
-
return
|
|
60
|
+
return `import { defineConfig } from "apibara/config";
|
|
62
61
|
|
|
63
62
|
export default defineConfig({
|
|
64
|
-
runtimeConfig: {}
|
|
65
|
-
isTypeScript
|
|
66
|
-
? `
|
|
67
|
-
rollupConfig: {
|
|
68
|
-
plugins: [typescript()${isTypeScript ? " as Plugin" : ""}],
|
|
69
|
-
},`
|
|
70
|
-
: ""
|
|
71
|
-
}
|
|
63
|
+
runtimeConfig: {},
|
|
72
64
|
});\n`;
|
|
73
65
|
}
|
|
74
66
|
|
|
@@ -81,6 +73,7 @@ export function generateIndexer({
|
|
|
81
73
|
return `import { defineIndexer } from "@apibara/indexer";
|
|
82
74
|
import { useLogger } from "@apibara/indexer/plugins";
|
|
83
75
|
${storage === "postgres" ? `import { drizzleStorage } from "@apibara/plugin-drizzle";` : ""}
|
|
76
|
+
${storage === "postgres" ? `import { drizzle } from "@apibara/plugin-drizzle";` : ""}
|
|
84
77
|
${
|
|
85
78
|
chain === "ethereum"
|
|
86
79
|
? `import { EvmStream } from "@apibara/evm";`
|
|
@@ -91,19 +84,17 @@ ${
|
|
|
91
84
|
: ""
|
|
92
85
|
}
|
|
93
86
|
${language === "typescript" ? `import type { ApibaraRuntimeConfig } from "apibara/types";` : ""}
|
|
94
|
-
${
|
|
95
|
-
storage === "postgres"
|
|
96
|
-
? `import { getDrizzlePgDatabase } from "../lib/db";`
|
|
97
|
-
: ""
|
|
98
|
-
}
|
|
87
|
+
${storage === "postgres" ? `import * as schema from "../lib/schema";` : ""}
|
|
99
88
|
|
|
100
89
|
|
|
101
90
|
export default function (runtimeConfig${language === "typescript" ? ": ApibaraRuntimeConfig" : ""}) {
|
|
102
91
|
const indexerId = "${indexerId}";
|
|
103
|
-
const { startingBlock, streamUrl
|
|
92
|
+
const { startingBlock, streamUrl } = runtimeConfig[indexerId];
|
|
104
93
|
${
|
|
105
94
|
storage === "postgres"
|
|
106
|
-
?
|
|
95
|
+
? `const db = drizzle({
|
|
96
|
+
schema,
|
|
97
|
+
});`
|
|
107
98
|
: ""
|
|
108
99
|
}
|
|
109
100
|
|
|
@@ -122,7 +113,7 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
122
113
|
filter: {
|
|
123
114
|
header: "always",
|
|
124
115
|
},
|
|
125
|
-
plugins: [${storage === "postgres" ? "drizzleStorage({ db,
|
|
116
|
+
plugins: [${storage === "postgres" ? "drizzleStorage({ db, migrate: { migrationsFolder: './drizzle' } })" : ""}],
|
|
126
117
|
async transform({ endCursor, finality }) {
|
|
127
118
|
const logger = useLogger();
|
|
128
119
|
|
|
@@ -136,14 +127,12 @@ export default function (runtimeConfig${language === "typescript" ? ": ApibaraRu
|
|
|
136
127
|
${
|
|
137
128
|
storage === "postgres"
|
|
138
129
|
? `// Example snippet to insert data into db using drizzle with postgres
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
// });
|
|
146
|
-
// }`
|
|
130
|
+
// const { db: database } = useDrizzleStorage();
|
|
131
|
+
|
|
132
|
+
// await database.insert(schema.cursorTable).values({
|
|
133
|
+
// endCursor: Number(endCursor?.orderKey),
|
|
134
|
+
// uniqueKey: \`\${endCursor?.uniqueKey}\`,
|
|
135
|
+
// });`
|
|
147
136
|
: ""
|
|
148
137
|
}
|
|
149
138
|
},
|
|
@@ -235,12 +224,8 @@ export async function updateApibaraConfigFile({
|
|
|
235
224
|
|
|
236
225
|
const runtimeConfigString = `{
|
|
237
226
|
startingBlock: 0,
|
|
238
|
-
streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
|
|
239
|
-
|
|
240
|
-
? `,
|
|
241
|
-
postgresConnectionString: process.env["POSTGRES_CONNECTION_STRING"] ?? "memory://${indexerId}"`
|
|
242
|
-
: ""
|
|
243
|
-
}}`;
|
|
227
|
+
streamUrl: "${dnaUrl ?? getDnaUrl(chain, network)}"
|
|
228
|
+
}`;
|
|
244
229
|
|
|
245
230
|
const project = new Project();
|
|
246
231
|
const sourceFile = project.addSourceFileAtPath(pathToConfig);
|
|
@@ -284,7 +269,7 @@ export async function updateApibaraConfigFile({
|
|
|
284
269
|
}
|
|
285
270
|
|
|
286
271
|
export async function createDrizzleStorageFiles(options: IndexerOptions) {
|
|
287
|
-
const { cwd, language, storage } = options;
|
|
272
|
+
const { cwd, language, storage, indexerId } = options;
|
|
288
273
|
|
|
289
274
|
if (storage !== "postgres") return;
|
|
290
275
|
|
|
@@ -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 {};
|
|
@@ -369,63 +354,6 @@ export {};
|
|
|
369
354
|
consola.success(`Created ${cyan("lib/schema.ts")}`);
|
|
370
355
|
}
|
|
371
356
|
|
|
372
|
-
/**
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
* DB File
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*/
|
|
379
|
-
const dbFileName = `db.${fileExtension}`;
|
|
380
|
-
|
|
381
|
-
const dbPath = path.join(cwd, "lib", dbFileName);
|
|
382
|
-
|
|
383
|
-
const { exists: dbExists, overwrite: dbOverwrite } = await checkFileExists(
|
|
384
|
-
dbPath,
|
|
385
|
-
{
|
|
386
|
-
askPrompt: true,
|
|
387
|
-
fileName: `lib/${dbFileName}`,
|
|
388
|
-
allowIgnore: true,
|
|
389
|
-
},
|
|
390
|
-
);
|
|
391
|
-
|
|
392
|
-
if (!dbExists || dbOverwrite) {
|
|
393
|
-
const dbContent = `import * as schema from "./schema";
|
|
394
|
-
import { drizzle as nodePgDrizzle } from "drizzle-orm/node-postgres";
|
|
395
|
-
import { drizzle as pgLiteDrizzle } from "drizzle-orm/pglite";
|
|
396
|
-
import pg from "pg";
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
export function getDrizzlePgDatabase(connectionString${language === "typescript" ? ": string" : ""}) {
|
|
400
|
-
// Create pglite instance
|
|
401
|
-
if (connectionString.includes("memory")) {
|
|
402
|
-
return {
|
|
403
|
-
db: pgLiteDrizzle({
|
|
404
|
-
schema,
|
|
405
|
-
connection: {
|
|
406
|
-
dataDir: connectionString,
|
|
407
|
-
},
|
|
408
|
-
}),
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Create node-postgres instance
|
|
413
|
-
const pool = new pg.Pool({
|
|
414
|
-
connectionString,
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
return { db: nodePgDrizzle(pool, { schema }) };
|
|
418
|
-
}`;
|
|
419
|
-
|
|
420
|
-
// create directory if it doesn't exist
|
|
421
|
-
fs.mkdirSync(path.dirname(dbPath), { recursive: true });
|
|
422
|
-
fs.writeFileSync(dbPath, dbContent);
|
|
423
|
-
|
|
424
|
-
await formatFile(dbPath);
|
|
425
|
-
|
|
426
|
-
consola.success(`Created ${cyan(`lib/${dbFileName}`)}`);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
357
|
console.log("\n");
|
|
430
358
|
|
|
431
359
|
// If schema file is created, show the example
|
|
@@ -445,17 +373,17 @@ ${yellow(`
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { builtinModules } from "node:module";
|
|
3
|
+
import replace from "@rollup/plugin-replace";
|
|
4
|
+
import type { Apibara } from "apibara/types";
|
|
5
|
+
import defu from "defu";
|
|
6
|
+
import { join } from "pathe";
|
|
7
|
+
import type {
|
|
8
|
+
ConfigExport,
|
|
9
|
+
RolldownOptions,
|
|
10
|
+
RolldownPluginOption,
|
|
11
|
+
} from "rolldown";
|
|
12
|
+
import { appConfig } from "./plugins/config";
|
|
13
|
+
import { indexers } from "./plugins/indexers";
|
|
14
|
+
import { instrumentation } from "./plugins/instrumentation";
|
|
15
|
+
|
|
16
|
+
const runtimeDependencies = [
|
|
17
|
+
"better-sqlite3",
|
|
18
|
+
"@electric-sql/pglite",
|
|
19
|
+
"pg",
|
|
20
|
+
// https://socket.io/docs/v4/server-installation/#additional-packages
|
|
21
|
+
"utf-8-validate",
|
|
22
|
+
"bufferutil",
|
|
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(
|
|
83
|
+
replace({
|
|
84
|
+
preventAssignment: true,
|
|
85
|
+
values: {
|
|
86
|
+
"process.env.APIBARA_CONFIG": getSerializedRuntimeConfig(apibara),
|
|
87
|
+
},
|
|
88
|
+
}) as RolldownPluginOption,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
rolldownConfig.plugins?.push(instrumentation(apibara));
|
|
92
|
+
rolldownConfig.plugins?.push(indexers(apibara));
|
|
93
|
+
rolldownConfig.plugins?.push(appConfig(apibara));
|
|
94
|
+
|
|
95
|
+
return rolldownConfig;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function getSerializedRuntimeConfig(apibara: Apibara) {
|
|
99
|
+
try {
|
|
100
|
+
return JSON.stringify({
|
|
101
|
+
runtimeConfig: apibara.options.runtimeConfig,
|
|
102
|
+
preset: apibara.options.preset,
|
|
103
|
+
presets: apibara.options.presets,
|
|
104
|
+
});
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
"Failed to serialize runtime config. Please ensure all values in your runtime configuration are JSON serializable.",
|
|
108
|
+
{ cause: error },
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|