arri 0.44.0 → 0.45.1
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/README.md +66 -542
- package/dist/cli.cjs +75 -396
- package/dist/cli.mjs +30 -339
- package/dist/index.cjs +25 -44
- package/dist/index.d.cts +8 -278
- package/dist/index.d.mts +8 -278
- package/dist/index.d.ts +8 -278
- package/dist/index.mjs +15 -9
- package/dist/shared/arri.547ce62e.cjs +436 -0
- package/dist/shared/arri.e5993636.mjs +403 -0
- package/package.json +17 -27
- package/dist/codegen.cjs +0 -13
- package/dist/codegen.d.cts +0 -4
- package/dist/codegen.d.mts +0 -4
- package/dist/codegen.d.ts +0 -4
- package/dist/codegen.mjs +0 -4
- package/dist/shared/arri.0628c07d.cjs +0 -1285
- package/dist/shared/arri.c3a553fc.mjs +0 -1250
package/dist/cli.cjs
CHANGED
|
@@ -5,182 +5,29 @@ const citty = require('citty');
|
|
|
5
5
|
const node_child_process = require('node:child_process');
|
|
6
6
|
const fs = require('node:fs');
|
|
7
7
|
const fs$1 = require('node:fs/promises');
|
|
8
|
-
const
|
|
8
|
+
const codegenUtils = require('@arrirpc/codegen-utils');
|
|
9
9
|
const c12 = require('c12');
|
|
10
10
|
const esbuild = require('esbuild');
|
|
11
11
|
const esbuildPluginReplace = require('esbuild-plugin-replace');
|
|
12
12
|
const path = require('pathe');
|
|
13
13
|
const prettier = require('prettier');
|
|
14
|
-
const
|
|
15
|
-
const consola = require('consola');
|
|
16
|
-
const globby = require('globby');
|
|
17
|
-
const scule = require('scule');
|
|
14
|
+
const dev = require('./shared/arri.547ce62e.cjs');
|
|
18
15
|
const ofetch = require('ofetch');
|
|
19
|
-
const listhen = require('@joshmossas/listhen');
|
|
20
16
|
const Degit = require('degit');
|
|
21
17
|
const enquirer = require('enquirer');
|
|
22
|
-
require('
|
|
23
|
-
require('
|
|
24
|
-
require('
|
|
18
|
+
const scule = require('scule');
|
|
19
|
+
require('@joshmossas/listhen');
|
|
20
|
+
require('consola');
|
|
25
21
|
|
|
26
22
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
27
23
|
|
|
28
|
-
function _interopNamespaceCompat(e) {
|
|
29
|
-
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
30
|
-
const n = Object.create(null);
|
|
31
|
-
if (e) {
|
|
32
|
-
for (const k in e) {
|
|
33
|
-
n[k] = e[k];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
n.default = e;
|
|
37
|
-
return n;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
24
|
const fs__default$1 = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
41
25
|
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs$1);
|
|
42
|
-
const esbuild__namespace = /*#__PURE__*/_interopNamespaceCompat(esbuild);
|
|
43
26
|
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
44
27
|
const prettier__default = /*#__PURE__*/_interopDefaultCompat(prettier);
|
|
45
28
|
const Degit__default = /*#__PURE__*/_interopDefaultCompat(Degit);
|
|
46
29
|
const enquirer__default = /*#__PURE__*/_interopDefaultCompat(enquirer);
|
|
47
30
|
|
|
48
|
-
const logger = consola.createConsola().withTag("arri");
|
|
49
|
-
const GEN_APP_FILE = "__arri_app.ts";
|
|
50
|
-
const GEN_SERVER_ENTRY_FILE = "__arri_server.ts";
|
|
51
|
-
const OUT_APP_FILE = "app.mjs";
|
|
52
|
-
const OUT_SERVER_ENTRY = "server.mjs";
|
|
53
|
-
const OUT_CODEGEN = "codegen.mjs";
|
|
54
|
-
async function setupWorkingDir(config) {
|
|
55
|
-
const arriDir = path__default.resolve(config.rootDir, config.buildDir);
|
|
56
|
-
const outDir = path__default.resolve(config.rootDir, ".output");
|
|
57
|
-
if (fs.existsSync(arriDir)) {
|
|
58
|
-
await fs__default.rm(arriDir, { recursive: true, force: true });
|
|
59
|
-
}
|
|
60
|
-
if (fs.existsSync(outDir)) {
|
|
61
|
-
await fs__default.rm(outDir, { recursive: true, force: true });
|
|
62
|
-
}
|
|
63
|
-
await fs__default.mkdir(arriDir);
|
|
64
|
-
await fs__default.mkdir(outDir);
|
|
65
|
-
}
|
|
66
|
-
async function createAppWithRoutesModule(config) {
|
|
67
|
-
const appModule = path__default.resolve(config.rootDir, config.srcDir, config.entry);
|
|
68
|
-
const appImportParts = path__default.relative(path__default.resolve(config.rootDir, config.buildDir), appModule).split(".");
|
|
69
|
-
appImportParts.pop();
|
|
70
|
-
const routes = [];
|
|
71
|
-
const existingRoutes = [];
|
|
72
|
-
await Promise.all(
|
|
73
|
-
config.procedureGlobPatterns.map(async (pattern) => {
|
|
74
|
-
const results = await getFsRouteBatch(pattern, config);
|
|
75
|
-
for (const result of results) {
|
|
76
|
-
if (!existingRoutes.includes(result.name)) {
|
|
77
|
-
routes.push(result);
|
|
78
|
-
existingRoutes.push(result.name);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
);
|
|
83
|
-
routes.sort((a, b) => a.name < b.name ? -1 : 1);
|
|
84
|
-
const module = await prettier__default.format(
|
|
85
|
-
`import sourceMapSupport from 'source-map-support';
|
|
86
|
-
sourceMapSupport.install();
|
|
87
|
-
import app from '${appImportParts.join(".")}';
|
|
88
|
-
${routes.map(
|
|
89
|
-
(route) => `import ${route.importName} from '${route.importPath}';`
|
|
90
|
-
).join("\n")}
|
|
91
|
-
const routes: {id: string; route: any}[] = [${routes.map(
|
|
92
|
-
(route) => `{ id: '${route.name}', route: ${route.importName} }`
|
|
93
|
-
).join(",\n")}
|
|
94
|
-
];
|
|
95
|
-
for(const route of routes) {
|
|
96
|
-
if(route.route.transport === 'http') {
|
|
97
|
-
app.rpc({
|
|
98
|
-
name: route.id,
|
|
99
|
-
...route.route,
|
|
100
|
-
});
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (route.route.transport === 'ws') {
|
|
104
|
-
app.wsRpc({
|
|
105
|
-
name: route.id,
|
|
106
|
-
...route.route,
|
|
107
|
-
});
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
export default app`,
|
|
112
|
-
{ parser: "typescript", tabWidth: 4 }
|
|
113
|
-
);
|
|
114
|
-
await fs__default.writeFile(
|
|
115
|
-
path__default.resolve(config.rootDir, config.buildDir, GEN_APP_FILE),
|
|
116
|
-
module
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
async function getFsRouteBatch(globPattern, config) {
|
|
120
|
-
if (!config.procedureDir) {
|
|
121
|
-
return [];
|
|
122
|
-
}
|
|
123
|
-
const target = `${config.rootDir}/${config.srcDir}/${config.procedureDir}/${globPattern}`.split("//").join("/").split("//").join("/");
|
|
124
|
-
const files = await globby.globby(target, {
|
|
125
|
-
onlyFiles: true
|
|
126
|
-
});
|
|
127
|
-
const routes = [];
|
|
128
|
-
for (const file of files) {
|
|
129
|
-
const meta = getRpcMetaFromPath(config, file);
|
|
130
|
-
if (meta) {
|
|
131
|
-
const importParts = path__default.relative(path__default.resolve(config.rootDir, config.buildDir), file).split(".");
|
|
132
|
-
importParts.pop();
|
|
133
|
-
importParts.push("js");
|
|
134
|
-
routes.push({
|
|
135
|
-
name: meta.id,
|
|
136
|
-
importName: scule.camelCase(meta.id.split(".").join("_")),
|
|
137
|
-
importPath: `./${importParts.join(".")}`
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return routes;
|
|
142
|
-
}
|
|
143
|
-
const disallowedNameChars = "~`!@#$%^&*()-+=[]{}\\|:;\"'<>,./";
|
|
144
|
-
const getRpcMetaFromPath = (config, filePath) => {
|
|
145
|
-
if (!config.procedureDir) {
|
|
146
|
-
return void 0;
|
|
147
|
-
}
|
|
148
|
-
const resolvedFilePath = filePath.split("./").join("/");
|
|
149
|
-
const parts = resolvedFilePath.split("/");
|
|
150
|
-
const reversedParts = [...parts].reverse();
|
|
151
|
-
const nameParts = [];
|
|
152
|
-
for (const part of reversedParts) {
|
|
153
|
-
if (part === config.procedureDir) {
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
nameParts.push(part);
|
|
157
|
-
}
|
|
158
|
-
const fileName = nameParts.reverse().pop() ?? "";
|
|
159
|
-
const serviceParts = nameParts.filter((part) => part.trim().length > 0).map((part) => arriCodegenUtils.removeDisallowedChars(part, disallowedNameChars));
|
|
160
|
-
const fileNameParts = fileName.split(".");
|
|
161
|
-
if (!fileNameParts.length) {
|
|
162
|
-
return void 0;
|
|
163
|
-
}
|
|
164
|
-
const rpcName = arriCodegenUtils.removeDisallowedChars(
|
|
165
|
-
fileNameParts[0],
|
|
166
|
-
disallowedNameChars
|
|
167
|
-
);
|
|
168
|
-
const httpParts = [
|
|
169
|
-
...serviceParts.map((part) => scule.kebabCase(part)),
|
|
170
|
-
scule.kebabCase(rpcName)
|
|
171
|
-
];
|
|
172
|
-
return {
|
|
173
|
-
id: [...serviceParts, rpcName].join("."),
|
|
174
|
-
httpPath: `/${httpParts.join("/")}`
|
|
175
|
-
};
|
|
176
|
-
};
|
|
177
|
-
function isInsideDir(dir, parentDir) {
|
|
178
|
-
if (path__default.resolve(dir).startsWith(path__default.resolve(parentDir))) {
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
31
|
const build = citty.defineCommand({
|
|
185
32
|
args: {
|
|
186
33
|
config: {
|
|
@@ -195,43 +42,43 @@ const build = citty.defineCommand({
|
|
|
195
42
|
}
|
|
196
43
|
},
|
|
197
44
|
async run({ args }) {
|
|
198
|
-
const { config
|
|
45
|
+
const { config } = await c12.loadConfig({
|
|
199
46
|
configFile: args.config,
|
|
200
|
-
defaultConfig:
|
|
47
|
+
defaultConfig: dev.defaultConfig
|
|
201
48
|
});
|
|
202
|
-
if (!config
|
|
49
|
+
if (!config) {
|
|
203
50
|
throw new Error("Unable to find arri config");
|
|
204
51
|
}
|
|
205
52
|
const appEntry = path__default.resolve(
|
|
206
|
-
config
|
|
207
|
-
config
|
|
208
|
-
config
|
|
53
|
+
config.rootDir,
|
|
54
|
+
config.srcDir,
|
|
55
|
+
config.entry
|
|
209
56
|
);
|
|
210
57
|
if (!fs.existsSync(appEntry)) {
|
|
211
58
|
throw new Error(`Unable to find entry at ${appEntry}`);
|
|
212
59
|
}
|
|
213
|
-
await startBuild(config
|
|
60
|
+
await startBuild(config, args.skipCodegen);
|
|
214
61
|
}
|
|
215
62
|
});
|
|
216
63
|
async function startBuild(config, skipCodeGen = false) {
|
|
217
|
-
logger.log("Bundling server....");
|
|
64
|
+
dev.logger.log("Bundling server....");
|
|
218
65
|
const appEntry = path__default.resolve(config.rootDir, config.srcDir, config.entry);
|
|
219
66
|
if (!fs.existsSync(path__default.resolve(config.rootDir, config.srcDir, config.entry))) {
|
|
220
|
-
logger.error(`Unabled to find entry at ${appEntry}`);
|
|
67
|
+
dev.logger.error(`Unabled to find entry at ${appEntry}`);
|
|
221
68
|
process.exit(1);
|
|
222
69
|
}
|
|
223
|
-
await setupWorkingDir(config);
|
|
70
|
+
await dev.setupWorkingDir(config);
|
|
224
71
|
await Promise.all([
|
|
225
|
-
createAppWithRoutesModule(config),
|
|
72
|
+
dev.createAppWithRoutesModule(config),
|
|
226
73
|
createServerEntryFile(config),
|
|
227
74
|
createCodegenEntryFile(config)
|
|
228
75
|
]);
|
|
229
76
|
await bundleAppEntry(config);
|
|
230
|
-
logger.log("Finished bundling");
|
|
77
|
+
dev.logger.log("Finished bundling");
|
|
231
78
|
const clientCount = config.generators.length;
|
|
232
|
-
const codegenModule = path__default.resolve(config.rootDir, ".output", OUT_CODEGEN);
|
|
79
|
+
const codegenModule = path__default.resolve(config.rootDir, ".output", dev.OUT_CODEGEN);
|
|
233
80
|
if (!skipCodeGen) {
|
|
234
|
-
logger.log("Generating Arri app definition (__definition.json)");
|
|
81
|
+
dev.logger.log("Generating Arri app definition (__definition.json)");
|
|
235
82
|
node_child_process.execSync(`node ${codegenModule}`, { env: process.env });
|
|
236
83
|
const defJson = path__default.resolve(
|
|
237
84
|
config.rootDir,
|
|
@@ -239,31 +86,31 @@ async function startBuild(config, skipCodeGen = false) {
|
|
|
239
86
|
"__definition.json"
|
|
240
87
|
);
|
|
241
88
|
const def = JSON.parse(fs.readFileSync(defJson, { encoding: "utf-8" }));
|
|
242
|
-
if (
|
|
243
|
-
logger.log(`Generating ${clientCount} clients`);
|
|
89
|
+
if (codegenUtils.isAppDefinition(def) && clientCount > 0) {
|
|
90
|
+
dev.logger.log(`Generating ${clientCount} clients`);
|
|
244
91
|
await Promise.all(
|
|
245
92
|
config.generators.map((plugin) => plugin.generator(def))
|
|
246
93
|
);
|
|
247
|
-
logger.log(`${clientCount} clients generated`);
|
|
94
|
+
dev.logger.log(`${clientCount} clients generated`);
|
|
248
95
|
} else {
|
|
249
|
-
logger.warn(
|
|
96
|
+
dev.logger.warn(
|
|
250
97
|
"No client generators specified. Skipping client codegen."
|
|
251
98
|
);
|
|
252
99
|
}
|
|
253
100
|
} else {
|
|
254
|
-
logger.log("Skipping codegen");
|
|
101
|
+
dev.logger.log("Skipping codegen");
|
|
255
102
|
}
|
|
256
|
-
logger.log("Cleaning up files");
|
|
103
|
+
dev.logger.log("Cleaning up files");
|
|
257
104
|
await fs__default.rm(codegenModule);
|
|
258
|
-
logger.success(
|
|
259
|
-
`Build finished! You can start your server by running "node .output/${OUT_SERVER_ENTRY}"`
|
|
105
|
+
dev.logger.success(
|
|
106
|
+
`Build finished! You can start your server by running "node .output/${dev.OUT_SERVER_ENTRY}"`
|
|
260
107
|
);
|
|
261
108
|
}
|
|
262
109
|
async function bundleAppEntry(config, allowCodegen = true) {
|
|
263
110
|
const appEntry = path__default.resolve(
|
|
264
111
|
config.rootDir,
|
|
265
112
|
config.buildDir,
|
|
266
|
-
GEN_APP_FILE
|
|
113
|
+
dev.GEN_APP_FILE
|
|
267
114
|
);
|
|
268
115
|
await esbuild.build({
|
|
269
116
|
...config.esbuild,
|
|
@@ -280,7 +127,7 @@ async function bundleAppEntry(config, allowCodegen = true) {
|
|
|
280
127
|
const require = topLevelCreateRequire(import.meta.url);`
|
|
281
128
|
},
|
|
282
129
|
allowOverwrite: true,
|
|
283
|
-
outfile: path__default.resolve(config.rootDir, ".output", OUT_APP_FILE)
|
|
130
|
+
outfile: path__default.resolve(config.rootDir, ".output", dev.OUT_APP_FILE)
|
|
284
131
|
});
|
|
285
132
|
}
|
|
286
133
|
async function createServerEntryFile(config) {
|
|
@@ -306,7 +153,7 @@ const require = topLevelCreateRequire(import.meta.url);`
|
|
|
306
153
|
},
|
|
307
154
|
plugins: [esbuildPluginReplace.replace({ "virtual:arri/app": "./app.mjs" })],
|
|
308
155
|
allowOverwrite: true,
|
|
309
|
-
outfile: path__default.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY)
|
|
156
|
+
outfile: path__default.resolve(config.rootDir, ".output", dev.OUT_SERVER_ENTRY)
|
|
310
157
|
});
|
|
311
158
|
return;
|
|
312
159
|
}
|
|
@@ -321,7 +168,7 @@ const require = topLevelCreateRequire(import.meta.url);`
|
|
|
321
168
|
}
|
|
322
169
|
const virtualEntry = `import { toNodeListener } from 'arri';
|
|
323
170
|
import { listen } from '@joshmossas/listhen';
|
|
324
|
-
import app from './${OUT_APP_FILE}';
|
|
171
|
+
import app from './${dev.OUT_APP_FILE}';
|
|
325
172
|
|
|
326
173
|
void listen(toNodeListener(app.h3App), {
|
|
327
174
|
port: process.env.PORT ?? ${config.port},
|
|
@@ -338,7 +185,7 @@ void listen(toNodeListener(app.h3App), {
|
|
|
338
185
|
${httpsString}
|
|
339
186
|
});`;
|
|
340
187
|
await fs__default.writeFile(
|
|
341
|
-
path__default.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY),
|
|
188
|
+
path__default.resolve(config.rootDir, ".output", dev.OUT_SERVER_ENTRY),
|
|
342
189
|
virtualEntry
|
|
343
190
|
);
|
|
344
191
|
}
|
|
@@ -350,7 +197,7 @@ async function createCodegenEntryFile(config) {
|
|
|
350
197
|
`
|
|
351
198
|
import { writeFileSync } from 'node:fs';
|
|
352
199
|
import path from 'pathe';
|
|
353
|
-
import app from './${OUT_APP_FILE}';
|
|
200
|
+
import app from './${dev.OUT_APP_FILE}';
|
|
354
201
|
|
|
355
202
|
const __dirname = new URL(".", import.meta.url).pathname;
|
|
356
203
|
const def = app.getAppDefinition();
|
|
@@ -361,7 +208,7 @@ async function createCodegenEntryFile(config) {
|
|
|
361
208
|
{ tabWidth: 4, parser: "typescript" }
|
|
362
209
|
);
|
|
363
210
|
await fs__default.writeFile(
|
|
364
|
-
path__default.resolve(config.rootDir, ".output", OUT_CODEGEN),
|
|
211
|
+
path__default.resolve(config.rootDir, ".output", dev.OUT_CODEGEN),
|
|
365
212
|
virtualModule
|
|
366
213
|
);
|
|
367
214
|
}
|
|
@@ -386,7 +233,7 @@ const codegen = citty.defineCommand({
|
|
|
386
233
|
let def;
|
|
387
234
|
if (isUrl) {
|
|
388
235
|
const result = await ofetch.ofetch(args.schema);
|
|
389
|
-
if (!
|
|
236
|
+
if (!codegenUtils.isAppDefinition(result)) {
|
|
390
237
|
throw new Error(`Invalid App Definition at ${args.schema}`);
|
|
391
238
|
}
|
|
392
239
|
def = result;
|
|
@@ -398,7 +245,7 @@ const codegen = citty.defineCommand({
|
|
|
398
245
|
const schemaResult = await c12.loadConfig({
|
|
399
246
|
configFile: args.schema
|
|
400
247
|
});
|
|
401
|
-
if (!
|
|
248
|
+
if (!codegenUtils.isAppDefinition(schemaResult.config)) {
|
|
402
249
|
throw new Error(`Invalid App Definition at ${args.schema}`);
|
|
403
250
|
}
|
|
404
251
|
def = schemaResult.config;
|
|
@@ -406,7 +253,7 @@ const codegen = citty.defineCommand({
|
|
|
406
253
|
const jsonString = JSON.parse(
|
|
407
254
|
fs__default$1.readFileSync(args.schema, { encoding: "utf-8" })
|
|
408
255
|
);
|
|
409
|
-
if (!
|
|
256
|
+
if (!codegenUtils.isAppDefinition(jsonString)) {
|
|
410
257
|
throw new Error(`Invalid App Definition at ${args.schema}`);
|
|
411
258
|
}
|
|
412
259
|
def = jsonString;
|
|
@@ -421,23 +268,23 @@ const codegen = citty.defineCommand({
|
|
|
421
268
|
);
|
|
422
269
|
}
|
|
423
270
|
const configPath = path__default.resolve(args.config);
|
|
424
|
-
const { config
|
|
425
|
-
if (!
|
|
271
|
+
const { config } = await c12.loadConfig({ configFile: configPath });
|
|
272
|
+
if (!dev.isArriConfig(config)) {
|
|
426
273
|
throw new Error(`Invalid arri config at ${args.config}`);
|
|
427
274
|
}
|
|
428
|
-
if (!config
|
|
429
|
-
logger.warn(`No generators specified in ${args.config}`);
|
|
275
|
+
if (!config.generators?.length) {
|
|
276
|
+
dev.logger.warn(`No generators specified in ${args.config}`);
|
|
430
277
|
process.exit(1);
|
|
431
278
|
}
|
|
432
|
-
logger.info(`Generating ${config
|
|
279
|
+
dev.logger.info(`Generating ${config.generators?.length} client(s)`);
|
|
433
280
|
await Promise.allSettled(
|
|
434
281
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
435
|
-
config
|
|
282
|
+
config.generators.map(
|
|
436
283
|
(gen) => gen.generator(
|
|
437
284
|
def ?? {
|
|
438
285
|
arriSchemaVersion: "0.0.4",
|
|
439
286
|
procedures: {},
|
|
440
|
-
|
|
287
|
+
definitions: {}
|
|
441
288
|
}
|
|
442
289
|
)
|
|
443
290
|
)
|
|
@@ -446,195 +293,6 @@ const codegen = citty.defineCommand({
|
|
|
446
293
|
}
|
|
447
294
|
});
|
|
448
295
|
|
|
449
|
-
const dev = citty.defineCommand({
|
|
450
|
-
meta: {
|
|
451
|
-
name: "dev",
|
|
452
|
-
description: "Start the arri dev server"
|
|
453
|
-
},
|
|
454
|
-
args: {
|
|
455
|
-
config: {
|
|
456
|
-
type: "string",
|
|
457
|
-
description: "Path to the arri config file",
|
|
458
|
-
alias: "c",
|
|
459
|
-
default: "./arri.config.ts"
|
|
460
|
-
}
|
|
461
|
-
},
|
|
462
|
-
async run({ args }) {
|
|
463
|
-
process.env.ARRI_DEV_MODE = "true";
|
|
464
|
-
const { config: config$1 } = await c12.loadConfig({
|
|
465
|
-
configFile: path__default.resolve(args.config)
|
|
466
|
-
});
|
|
467
|
-
if (!config.isResolvedArriConfig(config$1)) {
|
|
468
|
-
throw new Error("Unable to find config");
|
|
469
|
-
}
|
|
470
|
-
const appEntry = path__default.resolve(
|
|
471
|
-
config$1.rootDir,
|
|
472
|
-
config$1.srcDir,
|
|
473
|
-
config$1.entry
|
|
474
|
-
);
|
|
475
|
-
if (!fs.existsSync(appEntry)) {
|
|
476
|
-
throw new Error(`Unable to find entry at ${appEntry}`);
|
|
477
|
-
}
|
|
478
|
-
await startDevServer(config$1);
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
const startListener = (config, showQr = false) => listhen.listenAndWatch(path__default.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY), {
|
|
482
|
-
public: true,
|
|
483
|
-
port: config.port,
|
|
484
|
-
logger,
|
|
485
|
-
qr: showQr,
|
|
486
|
-
https: config.https,
|
|
487
|
-
http2: config.http2,
|
|
488
|
-
ws: true
|
|
489
|
-
});
|
|
490
|
-
async function bundleFilesContext(config) {
|
|
491
|
-
const serverContent = `import app from './${OUT_APP_FILE}';
|
|
492
|
-
|
|
493
|
-
export default app.h3App;`;
|
|
494
|
-
await fs__default.writeFile(
|
|
495
|
-
path__default.resolve(config.rootDir, ".output", OUT_SERVER_ENTRY),
|
|
496
|
-
serverContent
|
|
497
|
-
);
|
|
498
|
-
return await esbuild__namespace.context({
|
|
499
|
-
...config.esbuild,
|
|
500
|
-
entryPoints: [
|
|
501
|
-
path__default.resolve(config.rootDir, config.buildDir, GEN_APP_FILE)
|
|
502
|
-
],
|
|
503
|
-
outfile: path__default.resolve(config.rootDir, ".output", OUT_APP_FILE),
|
|
504
|
-
format: "esm",
|
|
505
|
-
bundle: true,
|
|
506
|
-
packages: "external",
|
|
507
|
-
sourcemap: config.esbuild.sourcemap ?? true,
|
|
508
|
-
target: config.esbuild.target ?? "node20",
|
|
509
|
-
platform: config.esbuild.platform ?? "node"
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
async function startDevServer(config) {
|
|
513
|
-
await setupWorkingDir(config);
|
|
514
|
-
const watcher = await import('chokidar');
|
|
515
|
-
let fileWatcher;
|
|
516
|
-
await Promise.all([
|
|
517
|
-
createEntryModule(config),
|
|
518
|
-
createAppWithRoutesModule(config)
|
|
519
|
-
]);
|
|
520
|
-
const context = await bundleFilesContext(config);
|
|
521
|
-
await context.rebuild();
|
|
522
|
-
const listener = await startListener(config, true);
|
|
523
|
-
setTimeout(async () => {
|
|
524
|
-
await generateClients(config);
|
|
525
|
-
}, 1e3);
|
|
526
|
-
const cleanExit = async () => {
|
|
527
|
-
process.exit();
|
|
528
|
-
};
|
|
529
|
-
process.on("exit", async () => {
|
|
530
|
-
await Promise.allSettled([
|
|
531
|
-
listener.close(),
|
|
532
|
-
fileWatcher?.close(),
|
|
533
|
-
context.dispose()
|
|
534
|
-
]);
|
|
535
|
-
});
|
|
536
|
-
process.on("SIGINT", cleanExit);
|
|
537
|
-
process.on("SIGTERM", cleanExit);
|
|
538
|
-
async function load(isRestart, reason) {
|
|
539
|
-
if (fileWatcher) {
|
|
540
|
-
await fileWatcher.close();
|
|
541
|
-
}
|
|
542
|
-
const srcDir = path__default.resolve(config.rootDir ?? "", config.srcDir);
|
|
543
|
-
const dirsToWatch = [srcDir];
|
|
544
|
-
if (config.esbuild.alias) {
|
|
545
|
-
for (const key of Object.keys(config.esbuild.alias)) {
|
|
546
|
-
const alias = config.esbuild.alias[key];
|
|
547
|
-
if (alias) {
|
|
548
|
-
if (!isInsideDir(alias, srcDir)) {
|
|
549
|
-
dirsToWatch.push(alias);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
if (config.devServer.additionalWatchDirs?.length) {
|
|
555
|
-
for (const dir of config.devServer.additionalWatchDirs) {
|
|
556
|
-
dirsToWatch.push(dir);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
const buildDir = path__default.resolve(config.rootDir, config.buildDir);
|
|
560
|
-
const outDir = path__default.resolve(config.rootDir, ".output");
|
|
561
|
-
fileWatcher = watcher.watch(dirsToWatch, {
|
|
562
|
-
ignoreInitial: true,
|
|
563
|
-
ignored: [
|
|
564
|
-
buildDir,
|
|
565
|
-
outDir,
|
|
566
|
-
"**/.output",
|
|
567
|
-
"**/dist/**",
|
|
568
|
-
"**/node_modules/**",
|
|
569
|
-
"**/.git/**"
|
|
570
|
-
]
|
|
571
|
-
});
|
|
572
|
-
fileWatcher.on("all", async (eventName, path2) => {
|
|
573
|
-
if (eventName === "addDir" || eventName === "add") {
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
await createAppWithRoutesModule(config);
|
|
577
|
-
let bundleCreated = false;
|
|
578
|
-
try {
|
|
579
|
-
logger.log(
|
|
580
|
-
"Change detected. Bundling files and restarting server...."
|
|
581
|
-
);
|
|
582
|
-
await context.rebuild();
|
|
583
|
-
bundleCreated = true;
|
|
584
|
-
} catch (err) {
|
|
585
|
-
logger.error("ERROR", err);
|
|
586
|
-
bundleCreated = false;
|
|
587
|
-
}
|
|
588
|
-
if (bundleCreated && config.generators.length) {
|
|
589
|
-
setTimeout(async () => {
|
|
590
|
-
await generateClients(config);
|
|
591
|
-
bundleCreated = false;
|
|
592
|
-
}, 1e3);
|
|
593
|
-
}
|
|
594
|
-
});
|
|
595
|
-
}
|
|
596
|
-
await load();
|
|
597
|
-
}
|
|
598
|
-
async function generateClients(config$1) {
|
|
599
|
-
try {
|
|
600
|
-
const protocol = config$1.https === true || typeof config$1.https === "object" ? "https" : "http";
|
|
601
|
-
if (protocol === "https") {
|
|
602
|
-
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
603
|
-
}
|
|
604
|
-
const result = await ofetch.ofetch(
|
|
605
|
-
`${protocol}://127.0.0.1:${config$1.port}${config.DEV_DEFINITION_ENDPOINT}`
|
|
606
|
-
);
|
|
607
|
-
if (!arriCodegenUtils.isAppDefinition(result)) {
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
logger.log(`Generating client code...`);
|
|
611
|
-
const clientCount = config$1.generators.length;
|
|
612
|
-
await Promise.allSettled(
|
|
613
|
-
config$1.generators.map(
|
|
614
|
-
(generator) => generator.generator(result, true)
|
|
615
|
-
)
|
|
616
|
-
);
|
|
617
|
-
logger.success(
|
|
618
|
-
`Generated ${clientCount} client${clientCount === 1 ? "" : "s"}`
|
|
619
|
-
);
|
|
620
|
-
} catch (err) {
|
|
621
|
-
logger.error(err);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
async function createEntryModule(config) {
|
|
625
|
-
const appModule = path__default.resolve(config.rootDir, config.srcDir, config.entry);
|
|
626
|
-
const appImportParts = path__default.relative(path__default.resolve(config.rootDir, config.srcDir), appModule).split(".");
|
|
627
|
-
appImportParts.pop();
|
|
628
|
-
const virtualEntry = `import { toNodeListener } from 'h3';
|
|
629
|
-
import app from './${GEN_APP_FILE}';
|
|
630
|
-
|
|
631
|
-
export default app.h3App;`;
|
|
632
|
-
await fs__default.writeFile(
|
|
633
|
-
path__default.resolve(config.rootDir, config.buildDir, GEN_SERVER_ENTRY_FILE),
|
|
634
|
-
virtualEntry
|
|
635
|
-
);
|
|
636
|
-
}
|
|
637
|
-
|
|
638
296
|
const init = citty.defineCommand({
|
|
639
297
|
meta: {
|
|
640
298
|
name: "Init",
|
|
@@ -695,7 +353,7 @@ const init = citty.defineCommand({
|
|
|
695
353
|
}
|
|
696
354
|
const dirFiles = fs__default$1.readdirSync(dir);
|
|
697
355
|
if (dirFiles.length && !context.args.force) {
|
|
698
|
-
logger.error(
|
|
356
|
+
dev.logger.error(
|
|
699
357
|
`"${context.args.dir}" is a non-empty directory. To continue with this operation rerun "arri init" with the --force flag.`
|
|
700
358
|
);
|
|
701
359
|
process.exit(1);
|
|
@@ -708,14 +366,23 @@ const init = citty.defineCommand({
|
|
|
708
366
|
await initPlugin(context.args.dir, context.args.force);
|
|
709
367
|
break;
|
|
710
368
|
default:
|
|
711
|
-
logger.error(`Unknown app type: '${type}'"`);
|
|
369
|
+
dev.logger.error(`Unknown app type: '${type}'"`);
|
|
712
370
|
break;
|
|
713
371
|
}
|
|
714
372
|
process.exit(0);
|
|
715
373
|
}
|
|
716
374
|
});
|
|
717
375
|
async function initApp(dir, force) {
|
|
718
|
-
const
|
|
376
|
+
const { eslint } = await enquirer__default.prompt([
|
|
377
|
+
{
|
|
378
|
+
name: "eslint",
|
|
379
|
+
type: "confirm",
|
|
380
|
+
message: "Do you want to setup Eslint?",
|
|
381
|
+
initial: true
|
|
382
|
+
}
|
|
383
|
+
]);
|
|
384
|
+
const repo = eslint ? "modiimedia/arri-starters/app-starter-ts-with-eslint" : "modiimedia/arri-starters/app-starter-ts";
|
|
385
|
+
const degit = Degit__default(repo, {
|
|
719
386
|
force
|
|
720
387
|
});
|
|
721
388
|
await degit.clone(dir);
|
|
@@ -732,18 +399,19 @@ async function initApp(dir, force) {
|
|
|
732
399
|
delete packageJson.main;
|
|
733
400
|
delete packageJson.author;
|
|
734
401
|
delete packageJson.tags;
|
|
402
|
+
delete packageJson.packageManager;
|
|
735
403
|
fs.writeFileSync(
|
|
736
404
|
path__default.resolve(dir, "package.json"),
|
|
737
405
|
await prettier__default.format(JSON.stringify(packageJson), {
|
|
738
406
|
parser: "json",
|
|
739
|
-
tabWidth:
|
|
407
|
+
tabWidth: 2,
|
|
740
408
|
semi: true,
|
|
741
409
|
endOfLine: "lf",
|
|
742
410
|
trailingComma: "all"
|
|
743
411
|
})
|
|
744
412
|
);
|
|
745
|
-
logger.success(`Project initialized in ${dir}!`);
|
|
746
|
-
logger.info(`To get started:
|
|
413
|
+
dev.logger.success(`Project initialized in ${dir}!`);
|
|
414
|
+
dev.logger.info(`To get started:
|
|
747
415
|
- cd ${dir}
|
|
748
416
|
- pnpm install
|
|
749
417
|
- pnpm run dev`);
|
|
@@ -759,9 +427,20 @@ async function initPlugin(dir, force) {
|
|
|
759
427
|
encoding: "utf8"
|
|
760
428
|
});
|
|
761
429
|
packageJson = packageJson.replace(`"arri-generator-name"`, `"${name}"`);
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
430
|
+
const parsedPackageJson = JSON.parse(packageJson);
|
|
431
|
+
delete parsedPackageJson.packageManager;
|
|
432
|
+
fs.writeFileSync(
|
|
433
|
+
path__default.resolve(dir, "package.json"),
|
|
434
|
+
await prettier__default.format(JSON.stringify(parsedPackageJson), {
|
|
435
|
+
parser: "json",
|
|
436
|
+
tabWidth: 2,
|
|
437
|
+
semi: true,
|
|
438
|
+
endOfLine: "lf",
|
|
439
|
+
trailingComma: "all"
|
|
440
|
+
})
|
|
441
|
+
);
|
|
442
|
+
dev.logger.success(`Project initialized in ${dir}!`);
|
|
443
|
+
dev.logger.info(`To get started:
|
|
765
444
|
- cd ${dir}
|
|
766
445
|
- pnpm install`);
|
|
767
446
|
}
|
|
@@ -769,7 +448,7 @@ async function initPlugin(dir, force) {
|
|
|
769
448
|
const main = citty.defineCommand({
|
|
770
449
|
subCommands: {
|
|
771
450
|
build,
|
|
772
|
-
dev,
|
|
451
|
+
dev: dev.dev,
|
|
773
452
|
codegen,
|
|
774
453
|
init
|
|
775
454
|
}
|