apibara 2.0.0-beta.40 → 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.
- package/dist/chunks/add.mjs +44 -0
- package/dist/chunks/init.mjs +41 -0
- package/dist/cli/index.mjs +3 -1
- package/dist/core/index.mjs +0 -1
- package/dist/create/index.d.mts +17 -0
- package/dist/create/index.d.ts +17 -0
- package/dist/create/index.mjs +958 -0
- package/dist/rollup/index.d.mts +1 -0
- package/dist/rollup/index.d.ts +1 -0
- package/package.json +12 -4
- package/src/cli/commands/add.ts +44 -0
- package/src/cli/commands/init.ts +40 -0
- package/src/cli/index.ts +2 -0
- package/src/core/build/error.ts +0 -1
- package/src/create/add.ts +225 -0
- package/src/create/colors.ts +15 -0
- package/src/create/constants.ts +98 -0
- package/src/create/index.ts +2 -0
- package/src/create/init.ts +164 -0
- package/src/create/templates.ts +462 -0
- package/src/create/types.ts +34 -0
- package/src/create/utils.ts +412 -0
- package/src/rollup/index.ts +1 -0
package/dist/rollup/index.d.mts
CHANGED
package/dist/rollup/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apibara",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/core/index.mjs",
|
|
6
6
|
"exports": {
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
"types": "./dist/runtime/index.d.ts",
|
|
37
37
|
"import": "./dist/runtime/index.mjs"
|
|
38
38
|
},
|
|
39
|
+
"./create": {
|
|
40
|
+
"types": "./dist/create/index.d.ts",
|
|
41
|
+
"import": "./dist/create/index.mjs"
|
|
42
|
+
},
|
|
39
43
|
"./runtime/meta": {
|
|
40
44
|
"types": "./runtime-meta.d.ts",
|
|
41
45
|
"import": "./runtime-meta.mjs"
|
|
@@ -72,9 +76,10 @@
|
|
|
72
76
|
"playground:start": "pnpm playground start --dir playground --indexer starknet"
|
|
73
77
|
},
|
|
74
78
|
"devDependencies": {
|
|
75
|
-
"@apibara/starknet": "2.0.0-beta.
|
|
79
|
+
"@apibara/starknet": "2.0.0-beta.41",
|
|
76
80
|
"@types/fs-extra": "^11.0.4",
|
|
77
81
|
"@types/node": "^20.14.0",
|
|
82
|
+
"@types/prompts": "^2.4.9",
|
|
78
83
|
"jiti": "^1.21.0",
|
|
79
84
|
"starknet": "^6.11.0",
|
|
80
85
|
"unbuild": "^2.0.0",
|
|
@@ -82,8 +87,8 @@
|
|
|
82
87
|
"vitest": "^1.6.0"
|
|
83
88
|
},
|
|
84
89
|
"dependencies": {
|
|
85
|
-
"@apibara/indexer": "2.0.0-beta.
|
|
86
|
-
"@apibara/protocol": "2.0.0-beta.
|
|
90
|
+
"@apibara/indexer": "2.0.0-beta.41",
|
|
91
|
+
"@apibara/protocol": "2.0.0-beta.41",
|
|
87
92
|
"@rollup/plugin-commonjs": "^26.0.1",
|
|
88
93
|
"@rollup/plugin-json": "^6.1.0",
|
|
89
94
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
@@ -102,9 +107,12 @@
|
|
|
102
107
|
"ohash": "^1.1.4",
|
|
103
108
|
"pathe": "^1.1.2",
|
|
104
109
|
"perfect-debounce": "^1.0.0",
|
|
110
|
+
"picocolors": "^1.1.1",
|
|
105
111
|
"pkg-types": "^1.1.3",
|
|
112
|
+
"prompts": "^2.4.2",
|
|
106
113
|
"rollup": "^4.18.1",
|
|
107
114
|
"rollup-plugin-esbuild": "^6.1.1",
|
|
115
|
+
"ts-morph": "^25.0.1",
|
|
108
116
|
"tslib": "^2.6.3",
|
|
109
117
|
"untyped": "^1.4.2"
|
|
110
118
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { addIndexer } from "apibara/create";
|
|
2
|
+
import { defineCommand } from "citty";
|
|
3
|
+
|
|
4
|
+
export default defineCommand({
|
|
5
|
+
meta: {
|
|
6
|
+
name: "add",
|
|
7
|
+
description:
|
|
8
|
+
"apibara add helps you add a new indexer to your project with sensible defaults.",
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
indexerId: {
|
|
12
|
+
type: "positional",
|
|
13
|
+
description: "Indexer ID",
|
|
14
|
+
required: false,
|
|
15
|
+
},
|
|
16
|
+
chain: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "Chain",
|
|
19
|
+
},
|
|
20
|
+
network: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Network",
|
|
23
|
+
},
|
|
24
|
+
storage: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Storage",
|
|
27
|
+
},
|
|
28
|
+
dnaUrl: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "DNA URL",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
async run({ args }) {
|
|
34
|
+
const { indexerId, chain, network, storage, dnaUrl } = args;
|
|
35
|
+
|
|
36
|
+
await addIndexer({
|
|
37
|
+
argIndexerId: indexerId,
|
|
38
|
+
argChain: chain,
|
|
39
|
+
argNetwork: network,
|
|
40
|
+
argStorage: storage,
|
|
41
|
+
argDnaUrl: dnaUrl,
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { initializeProject } from "apibara/create";
|
|
2
|
+
import { defineCommand } from "citty";
|
|
3
|
+
|
|
4
|
+
export default 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
|
+
|
|
34
|
+
await initializeProject({
|
|
35
|
+
argTargetDir: targetDir,
|
|
36
|
+
argLanguage: language,
|
|
37
|
+
argNoCreateIndexer: noCreateIndexer,
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
});
|
package/src/cli/index.ts
CHANGED
|
@@ -11,6 +11,8 @@ export const mainCli = defineCommand({
|
|
|
11
11
|
build: () => import("./commands/build").then((r) => r.default),
|
|
12
12
|
start: () => import("./commands/start").then((r) => r.default),
|
|
13
13
|
prepare: () => import("./commands/prepare").then((r) => r.default),
|
|
14
|
+
init: () => import("./commands/init").then((r) => r.default),
|
|
15
|
+
add: () => import("./commands/add").then((r) => r.default),
|
|
14
16
|
},
|
|
15
17
|
});
|
|
16
18
|
|
package/src/core/build/error.ts
CHANGED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import consola from "consola";
|
|
2
|
+
import prompts from "prompts";
|
|
3
|
+
import { cyan, red, reset } from "./colors";
|
|
4
|
+
import {
|
|
5
|
+
type ChainDataType,
|
|
6
|
+
type NetworkDataType,
|
|
7
|
+
type StorageDataType,
|
|
8
|
+
chains,
|
|
9
|
+
storages,
|
|
10
|
+
} from "./constants";
|
|
11
|
+
import { initializeProject } from "./init";
|
|
12
|
+
import {
|
|
13
|
+
createIndexerFile,
|
|
14
|
+
createStorageRelatedFiles,
|
|
15
|
+
updateApibaraConfigFile,
|
|
16
|
+
updatePackageJson,
|
|
17
|
+
} from "./templates";
|
|
18
|
+
import type { Chain, IndexerOptions, Network, Storage } from "./types";
|
|
19
|
+
import {
|
|
20
|
+
cancelOperation,
|
|
21
|
+
convertKebabToCamelCase,
|
|
22
|
+
getApibaraConfigLanguage,
|
|
23
|
+
getPackageManager,
|
|
24
|
+
hasApibaraConfig,
|
|
25
|
+
validateChain,
|
|
26
|
+
validateDnaUrl,
|
|
27
|
+
validateIndexerId,
|
|
28
|
+
validateNetwork,
|
|
29
|
+
validateStorage,
|
|
30
|
+
} from "./utils";
|
|
31
|
+
|
|
32
|
+
type Options = {
|
|
33
|
+
argIndexerId?: string;
|
|
34
|
+
argChain?: string;
|
|
35
|
+
argNetwork?: string;
|
|
36
|
+
argStorage?: string;
|
|
37
|
+
argDnaUrl?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export async function addIndexer({
|
|
41
|
+
argIndexerId,
|
|
42
|
+
argChain,
|
|
43
|
+
argNetwork,
|
|
44
|
+
argStorage,
|
|
45
|
+
argDnaUrl,
|
|
46
|
+
}: Options) {
|
|
47
|
+
const configExists = hasApibaraConfig(process.cwd());
|
|
48
|
+
|
|
49
|
+
if (!configExists) {
|
|
50
|
+
consola.error("No apibara.config found in the current directory.");
|
|
51
|
+
|
|
52
|
+
const prompt_initialize = await prompts({
|
|
53
|
+
type: "confirm",
|
|
54
|
+
name: "prompt_initialize",
|
|
55
|
+
message: reset(
|
|
56
|
+
"Do you want to initialize a apibara project here before adding an indexer?",
|
|
57
|
+
),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (prompt_initialize.prompt_initialize) {
|
|
61
|
+
await initializeProject({
|
|
62
|
+
argTargetDir: process.cwd(),
|
|
63
|
+
argNoCreateIndexer: true,
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
consola.info(
|
|
67
|
+
`Initialize a project with ${cyan("apibara init")} before adding an indexer`,
|
|
68
|
+
);
|
|
69
|
+
throw new Error(
|
|
70
|
+
red("✖") + " Operation cancelled: No apibara.config found",
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const language = getApibaraConfigLanguage(process.cwd());
|
|
76
|
+
|
|
77
|
+
validateIndexerId(argIndexerId, true);
|
|
78
|
+
validateChain(argChain, true);
|
|
79
|
+
validateNetwork(argChain, argNetwork, true);
|
|
80
|
+
validateStorage(argStorage, true);
|
|
81
|
+
validateDnaUrl(argDnaUrl, true);
|
|
82
|
+
|
|
83
|
+
const result = await prompts(
|
|
84
|
+
[
|
|
85
|
+
{
|
|
86
|
+
type: argIndexerId ? null : "text",
|
|
87
|
+
name: "prompt_indexerId",
|
|
88
|
+
message: reset("Indexer ID:"),
|
|
89
|
+
initial: argIndexerId ?? "my-indexer",
|
|
90
|
+
validate: (id) =>
|
|
91
|
+
validateIndexerId(id) ||
|
|
92
|
+
"Invalid indexer ID cannot be empty and must be in kebab-case format",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
type: argChain ? null : "select",
|
|
96
|
+
name: "prompt_chain",
|
|
97
|
+
message: reset("Select a chain:"),
|
|
98
|
+
choices: chains.map((chain) => ({
|
|
99
|
+
title: chain.color(chain.display),
|
|
100
|
+
value: chain,
|
|
101
|
+
})),
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
type: argNetwork ? null : "select",
|
|
105
|
+
name: "prompt_network",
|
|
106
|
+
message: reset("Select a network:"),
|
|
107
|
+
choices: (chain: ChainDataType | undefined) => [
|
|
108
|
+
...(
|
|
109
|
+
chain?.networks ??
|
|
110
|
+
chains.find((c) => c.name === argChain)?.networks ??
|
|
111
|
+
[]
|
|
112
|
+
).map((network) => ({
|
|
113
|
+
title: network.color(network.display),
|
|
114
|
+
value: network,
|
|
115
|
+
})),
|
|
116
|
+
{
|
|
117
|
+
title: cyan("Other"),
|
|
118
|
+
value: {
|
|
119
|
+
color: cyan,
|
|
120
|
+
display: "Other",
|
|
121
|
+
name: "other",
|
|
122
|
+
} as NetworkDataType,
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
type: (network: NetworkDataType | undefined) => {
|
|
128
|
+
if (network || argNetwork) {
|
|
129
|
+
return network?.name === "other" || argNetwork === "other"
|
|
130
|
+
? "text"
|
|
131
|
+
: null;
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
},
|
|
135
|
+
name: "prompt_dnaUrl",
|
|
136
|
+
message: reset("Enter a DNA URL:"),
|
|
137
|
+
validate: (url) => validateDnaUrl(url) || "Provide a valid DNA Url",
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: argStorage ? null : "select",
|
|
141
|
+
name: "prompt_storage",
|
|
142
|
+
message: reset("Select a storage:"),
|
|
143
|
+
choices: storages.map((storage) => ({
|
|
144
|
+
title: storage.color(storage.display),
|
|
145
|
+
value: storage,
|
|
146
|
+
})),
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
{
|
|
150
|
+
onCancel: () => {
|
|
151
|
+
cancelOperation();
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
const {
|
|
157
|
+
prompt_indexerId,
|
|
158
|
+
prompt_chain,
|
|
159
|
+
prompt_network,
|
|
160
|
+
prompt_storage,
|
|
161
|
+
prompt_dnaUrl,
|
|
162
|
+
} = result as {
|
|
163
|
+
prompt_indexerId: string | undefined;
|
|
164
|
+
prompt_chain: ChainDataType | undefined;
|
|
165
|
+
prompt_network: NetworkDataType | undefined;
|
|
166
|
+
prompt_storage: StorageDataType | undefined;
|
|
167
|
+
prompt_dnaUrl: string | undefined;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
if (!argIndexerId && !prompt_indexerId) {
|
|
171
|
+
throw new Error(red("✖") + " Indexer ID is required");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!argChain && !prompt_chain) {
|
|
175
|
+
throw new Error(red("✖") + " Chain is required");
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!argNetwork && !prompt_network) {
|
|
179
|
+
throw new Error(red("✖") + " Network is required");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const indexerFileId = argIndexerId! ?? prompt_indexerId!;
|
|
183
|
+
|
|
184
|
+
const pkgManager = getPackageManager();
|
|
185
|
+
|
|
186
|
+
const options: IndexerOptions = {
|
|
187
|
+
cwd: process.cwd(),
|
|
188
|
+
indexerFileId,
|
|
189
|
+
indexerId: convertKebabToCamelCase(indexerFileId),
|
|
190
|
+
chain: (argChain as Chain) ?? prompt_chain?.name!,
|
|
191
|
+
network: (argNetwork as Network) ?? prompt_network?.name!,
|
|
192
|
+
storage: (argStorage as Storage) ?? prompt_storage?.name!,
|
|
193
|
+
dnaUrl: argDnaUrl ?? prompt_dnaUrl,
|
|
194
|
+
language,
|
|
195
|
+
packageManager: pkgManager.name,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
updateApibaraConfigFile(options);
|
|
199
|
+
|
|
200
|
+
consola.success(
|
|
201
|
+
`Updated ${cyan("apibara.config." + (language === "typescript" ? "ts" : "js"))}`,
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
updatePackageJson(options);
|
|
205
|
+
|
|
206
|
+
consola.success(`Updated ${cyan("package.json")}`);
|
|
207
|
+
|
|
208
|
+
await createIndexerFile(options);
|
|
209
|
+
|
|
210
|
+
consola.success(
|
|
211
|
+
`Created ${cyan(`${indexerFileId}.indexer.${language === "typescript" ? "ts" : "js"}`)}`,
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
await createStorageRelatedFiles(options);
|
|
215
|
+
|
|
216
|
+
console.log();
|
|
217
|
+
|
|
218
|
+
consola.info(
|
|
219
|
+
`Before running the indexer, run ${cyan(`${options.packageManager} run install`)}${
|
|
220
|
+
language === "typescript"
|
|
221
|
+
? " & " + cyan(`${options.packageManager} run prepare`)
|
|
222
|
+
: ""
|
|
223
|
+
}`,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { blue, green, red, yellow } from "./colors";
|
|
2
|
+
import type { Chain, ColorFunc, Network } from "./types";
|
|
3
|
+
|
|
4
|
+
export type ChainDataType = {
|
|
5
|
+
name: Chain;
|
|
6
|
+
display: string;
|
|
7
|
+
color: ColorFunc;
|
|
8
|
+
networks: NetworkDataType[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type NetworkDataType = {
|
|
12
|
+
name: Network;
|
|
13
|
+
display: string;
|
|
14
|
+
color: ColorFunc;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type LanguageDataType = {
|
|
18
|
+
name: "typescript" | "javascript";
|
|
19
|
+
display: string;
|
|
20
|
+
color: ColorFunc;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type StorageDataType = {
|
|
24
|
+
name: "postgres" | "none";
|
|
25
|
+
display: string;
|
|
26
|
+
color: ColorFunc;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const chains: ChainDataType[] = [
|
|
30
|
+
{
|
|
31
|
+
name: "starknet",
|
|
32
|
+
display: "Starknet",
|
|
33
|
+
color: blue,
|
|
34
|
+
networks: [
|
|
35
|
+
{ name: "mainnet", display: "Mainnet", color: blue },
|
|
36
|
+
{ name: "sepolia", display: "Sepolia", color: yellow },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "ethereum",
|
|
41
|
+
display: "Ethereum",
|
|
42
|
+
color: green,
|
|
43
|
+
networks: [
|
|
44
|
+
{ name: "mainnet", display: "Mainnet", color: blue },
|
|
45
|
+
{ name: "sepolia", display: "Sepolia", color: yellow },
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "beaconchain",
|
|
50
|
+
display: "Beacon Chain",
|
|
51
|
+
color: yellow,
|
|
52
|
+
networks: [{ name: "mainnet", display: "Mainnet", color: yellow }],
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
export const networks: NetworkDataType[] = [
|
|
57
|
+
{ name: "mainnet", display: "Mainnet", color: blue },
|
|
58
|
+
{ name: "sepolia", display: "Sepolia", color: green },
|
|
59
|
+
{ name: "other", display: "Other", color: red },
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
export const storages: StorageDataType[] = [
|
|
63
|
+
{ name: "postgres", display: "Postgres", color: green },
|
|
64
|
+
{ name: "none", display: "None", color: red },
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
export const packageVersions = {
|
|
68
|
+
// Required Dependencies
|
|
69
|
+
apibara: "^2.0.0-beta.40",
|
|
70
|
+
"@apibara/indexer": "^2.0.0-beta.40",
|
|
71
|
+
"@apibara/protocol": "^2.0.0-beta.40",
|
|
72
|
+
// Chain Dependencies
|
|
73
|
+
"@apibara/evm": "^2.0.0-beta.40",
|
|
74
|
+
"@apibara/beaconchain": "^2.0.0-beta.40",
|
|
75
|
+
"@apibara/starknet": "^2.0.0-beta.40",
|
|
76
|
+
// Storage Dependencies
|
|
77
|
+
"@apibara/plugin-drizzle": "^2.0.0-beta.40",
|
|
78
|
+
"@apibara/plugin-mongo": "^2.0.0-beta.40",
|
|
79
|
+
"@apibara/plugin-sqlite": "^2.0.0-beta.40",
|
|
80
|
+
// Postgres Dependencies
|
|
81
|
+
"@electric-sql/pglite": "^0.2.14",
|
|
82
|
+
"drizzle-orm": "^0.37.0",
|
|
83
|
+
pg: "^8.13.1",
|
|
84
|
+
"@types/pg": "^8.11.10",
|
|
85
|
+
"drizzle-kit": "^0.29.0",
|
|
86
|
+
// Typescript Dependencies
|
|
87
|
+
typescript: "^5.6.2",
|
|
88
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
89
|
+
"@types/node": "^20.5.2",
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const dnaUrls = {
|
|
93
|
+
ethereum: "https://ethereum.preview.apibara.org",
|
|
94
|
+
ethereumSepolia: "https://ethereum-sepolia.preview.apibara.org",
|
|
95
|
+
beaconchain: "https://beaconchain.preview.apibara.org",
|
|
96
|
+
starknet: "https://starknet.preview.apibara.org",
|
|
97
|
+
starknetSepolia: "https://starknet-sepolia.preview.apibara.org",
|
|
98
|
+
};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import consola from "consola";
|
|
4
|
+
import prompts from "prompts";
|
|
5
|
+
import { addIndexer } from "./add";
|
|
6
|
+
import { cyan, green } from "./colors";
|
|
7
|
+
import {
|
|
8
|
+
generateApibaraConfig,
|
|
9
|
+
generatePackageJson,
|
|
10
|
+
generateTsConfig,
|
|
11
|
+
} from "./templates";
|
|
12
|
+
import type { Language } from "./types";
|
|
13
|
+
import {
|
|
14
|
+
cancelOperation,
|
|
15
|
+
emptyDir,
|
|
16
|
+
getLanguageFromAlias,
|
|
17
|
+
getPackageManager,
|
|
18
|
+
isEmpty,
|
|
19
|
+
validateLanguage,
|
|
20
|
+
} from "./utils";
|
|
21
|
+
|
|
22
|
+
type Options = {
|
|
23
|
+
argTargetDir: string;
|
|
24
|
+
argLanguage?: string;
|
|
25
|
+
argNoCreateIndexer?: boolean;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export async function initializeProject({
|
|
29
|
+
argTargetDir,
|
|
30
|
+
argLanguage,
|
|
31
|
+
argNoCreateIndexer,
|
|
32
|
+
}: Options) {
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
validateLanguage(argLanguage, true);
|
|
35
|
+
|
|
36
|
+
console.log();
|
|
37
|
+
|
|
38
|
+
const result = await prompts(
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
type: () =>
|
|
42
|
+
argTargetDir &&
|
|
43
|
+
(!fs.existsSync(argTargetDir) || isEmpty(argTargetDir))
|
|
44
|
+
? null
|
|
45
|
+
: "select",
|
|
46
|
+
name: "overwrite",
|
|
47
|
+
message: () =>
|
|
48
|
+
(argTargetDir === "."
|
|
49
|
+
? "Current directory"
|
|
50
|
+
: `Target directory "${argTargetDir}"`) +
|
|
51
|
+
" is not empty. Please choose how to proceed:",
|
|
52
|
+
initial: 0,
|
|
53
|
+
choices: [
|
|
54
|
+
{
|
|
55
|
+
title: "Cancel operation",
|
|
56
|
+
value: "no",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
title: "Remove existing files and continue",
|
|
60
|
+
value: "yes",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
title: "Ignore files and continue",
|
|
64
|
+
value: "ignore",
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
hint: "\nCurrent Working Directory: " + cwd,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: (_, { overwrite }: { overwrite?: string }) => {
|
|
71
|
+
if (overwrite === "no") {
|
|
72
|
+
cancelOperation();
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
},
|
|
76
|
+
name: "overwriteChecker",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: argLanguage ? null : "select",
|
|
80
|
+
name: "prompt_language",
|
|
81
|
+
message: "Select a language:",
|
|
82
|
+
choices: [
|
|
83
|
+
{
|
|
84
|
+
title: "Typescript",
|
|
85
|
+
value: "typescript",
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
title: "Javascript",
|
|
89
|
+
value: "javascript",
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
{
|
|
95
|
+
onCancel: () => {
|
|
96
|
+
cancelOperation();
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const { overwrite, prompt_language } = result as {
|
|
102
|
+
overwrite: "no" | "yes" | "ignore";
|
|
103
|
+
prompt_language: "typescript" | "javascript";
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const root = path.join(cwd, argTargetDir);
|
|
107
|
+
if (overwrite === "yes") {
|
|
108
|
+
emptyDir(root);
|
|
109
|
+
} else if (!fs.existsSync(root)) {
|
|
110
|
+
fs.mkdirSync(root, { recursive: true });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const lang: Language = argLanguage
|
|
114
|
+
? getLanguageFromAlias(argLanguage)
|
|
115
|
+
: prompt_language;
|
|
116
|
+
|
|
117
|
+
const isTs = lang === "typescript";
|
|
118
|
+
const configExt = isTs ? "ts" : "js";
|
|
119
|
+
|
|
120
|
+
console.log("\n");
|
|
121
|
+
consola.info(`Initializing project in ${argTargetDir}\n\n`);
|
|
122
|
+
|
|
123
|
+
// Generate package.json
|
|
124
|
+
const packageJson = generatePackageJson(isTs);
|
|
125
|
+
fs.writeFileSync(
|
|
126
|
+
path.join(root, "package.json"),
|
|
127
|
+
JSON.stringify(packageJson, null, 2) + "\n",
|
|
128
|
+
);
|
|
129
|
+
consola.success("Created ", cyan("package.json"));
|
|
130
|
+
|
|
131
|
+
// Generate tsconfig.json if TypeScript
|
|
132
|
+
if (isTs) {
|
|
133
|
+
const tsConfig = generateTsConfig();
|
|
134
|
+
fs.writeFileSync(
|
|
135
|
+
path.join(root, "tsconfig.json"),
|
|
136
|
+
JSON.stringify(tsConfig, null, 2) + "\n",
|
|
137
|
+
);
|
|
138
|
+
consola.success("Created ", cyan("tsconfig.json"));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Generate apibara.config
|
|
142
|
+
const apibaraConfig = generateApibaraConfig(isTs);
|
|
143
|
+
fs.writeFileSync(
|
|
144
|
+
path.join(root, `apibara.config.${configExt}`),
|
|
145
|
+
apibaraConfig,
|
|
146
|
+
);
|
|
147
|
+
consola.success("Created ", cyan(`apibara.config.${configExt}`), "\n\n");
|
|
148
|
+
consola.ready(green("Project initialized successfully"));
|
|
149
|
+
|
|
150
|
+
console.log();
|
|
151
|
+
|
|
152
|
+
if (!argNoCreateIndexer) {
|
|
153
|
+
consola.info("Let's create an indexer\n");
|
|
154
|
+
|
|
155
|
+
await addIndexer({});
|
|
156
|
+
} else {
|
|
157
|
+
const pkgManager = getPackageManager();
|
|
158
|
+
consola.info(
|
|
159
|
+
"Run ",
|
|
160
|
+
green(`${pkgManager.name} run install`),
|
|
161
|
+
" to install all dependencies",
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|