@holo-js/cli 0.2.5 → 0.3.0
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/{agent-skills-MSEMQUXT.mjs → agent-skills-CHAXS2YN.mjs} +13 -6
- package/dist/bin/holo.mjs +436 -109
- package/dist/{broadcast-5MJ3GJK7.mjs → broadcast-5VZM5SGQ.mjs} +13 -10
- package/dist/{broadcast-MRJGFCFH.mjs → broadcast-AABT52BK.mjs} +13 -10
- package/dist/cache-A42JSVYA.mjs +138 -0
- package/dist/cache-DUVBBOZU.mjs +138 -0
- package/dist/{cache-migrations-CPYQC7T6.mjs → cache-migrations-4WKSEN2Q.mjs} +12 -10
- package/dist/{cache-migrations-APDFSFEX.mjs → cache-migrations-PD2T5AV4.mjs} +14 -12
- package/dist/chunk-3RFRE7XG.mjs +491 -0
- package/dist/{chunk-PT72AMV7.mjs → chunk-6BHJLCAO.mjs} +256 -392
- package/dist/{chunk-KS5TWO75.mjs → chunk-EQUFFLRG.mjs} +7 -7
- package/dist/chunk-HX6MOYBO.mjs +2 -0
- package/dist/{chunk-YEFJBN56.mjs → chunk-JVLZ3SOW.mjs} +11 -8
- package/dist/{chunk-UPXQONEH.mjs → chunk-KRADH7PK.mjs} +55 -51
- package/dist/chunk-LALDNNPH.mjs +428 -0
- package/dist/chunk-LHK5YUR4.mjs +156 -0
- package/dist/{chunk-LBJAJLKU.mjs → chunk-M3IPUCTM.mjs} +1 -1
- package/dist/{chunk-TWITVSFZ.mjs → chunk-OI54DOHK.mjs} +256 -392
- package/dist/{chunk-LXGQCG56.mjs → chunk-OLZEMIDQ.mjs} +1 -1
- package/dist/{chunk-VP2E62DF.mjs → chunk-QSVMXMTQ.mjs} +49 -349
- package/dist/{chunk-J76GH2DR.mjs → chunk-R4ZYMEDU.mjs} +129 -86
- package/dist/{chunk-XDRCZ3Z5.mjs → chunk-TH5YCOZB.mjs} +57 -53
- package/dist/chunk-TRYHX5S4.mjs +360 -0
- package/dist/chunk-XBOVM6LO.mjs +41 -0
- package/dist/{chunk-ILU426CF.mjs → chunk-YACY2572.mjs} +482 -2
- package/dist/{config-MD27U4FM.mjs → config-BZHQK532.mjs} +3 -3
- package/dist/{dev-CT4DRTLN.mjs → dev-7KGRV56X.mjs} +10 -8
- package/dist/{dev-QDLR6C7K.mjs → dev-GQT37XJU.mjs} +10 -8
- package/dist/{discovery-GWTBF5RZ.mjs → discovery-HNH3BLDL.mjs} +8 -6
- package/dist/{generators-PUN5TFP5.mjs → generators-3FVW4AEJ.mjs} +18 -15
- package/dist/{generators-WQHI7DBW.mjs → generators-JWVNGUUE.mjs} +14 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +434 -107
- package/dist/{media-migrations-D3CDNMPT.mjs → media-migrations-EG34NYAG.mjs} +13 -11
- package/dist/{media-migrations-IWCSCKSA.mjs → media-migrations-LGI7R7AR.mjs} +11 -9
- package/dist/plugins-ZGLB6JO6.mjs +24 -0
- package/dist/{queue-O3OSLGOV.mjs → queue-BEZDCZCY.mjs} +54 -16
- package/dist/{queue-GRB2IH5M.mjs → queue-R54DUUYA.mjs} +54 -16
- package/dist/{queue-migrations-7T42S4FX.mjs → queue-migrations-AM3AKT76.mjs} +16 -11
- package/dist/{queue-migrations-HFZB64OG.mjs → queue-migrations-U477YSFD.mjs} +18 -13
- package/dist/{runtime-TTRP2DGL.mjs → runtime-4TJYZLQV.mjs} +10 -8
- package/dist/{runtime-M3G5OKQV.mjs → runtime-MSRQD5W5.mjs} +10 -8
- package/dist/{runtime-GSXF4NB3.mjs → runtime-VR5BDPYQ.mjs} +1 -1
- package/dist/runtime-worker.mjs +7 -1
- package/dist/{scaffold-5BOVJYF3.mjs → scaffold-ASEX5LEX.mjs} +8 -4
- package/dist/{scaffold-NY3MWUZF.mjs → scaffold-ZAD3XUSD.mjs} +8 -4
- package/dist/{security-ST6ED7EK.mjs → security-4QLV7QCH.mjs} +8 -6
- package/dist/{security-H7AGDFBX.mjs → security-KYTLP4DF.mjs} +8 -6
- package/package.json +35 -8
- package/dist/cache-KVRYC7FB.mjs +0 -66
- package/dist/cache-WWE4Q4YE.mjs +0 -66
- package/dist/chunk-D7O4SU6N.mjs +0 -2
- package/dist/chunk-FGQ2I2YH.mjs +0 -22
package/dist/index.mjs
CHANGED
|
@@ -17,24 +17,30 @@ import {
|
|
|
17
17
|
splitCsv
|
|
18
18
|
} from "./chunk-VRGB6DIS.mjs";
|
|
19
19
|
import {
|
|
20
|
-
hasProjectDependency
|
|
21
|
-
|
|
20
|
+
hasProjectDependency,
|
|
21
|
+
pinProjectDependencyVersions,
|
|
22
|
+
removeProjectDependency,
|
|
23
|
+
upsertProjectDependency
|
|
24
|
+
} from "./chunk-LHK5YUR4.mjs";
|
|
22
25
|
import {
|
|
23
26
|
fileExists
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-M3IPUCTM.mjs";
|
|
25
28
|
import {
|
|
26
29
|
runWithSpinner,
|
|
27
30
|
supportsSpinner,
|
|
28
31
|
writeLine
|
|
29
32
|
} from "./chunk-I7QBCEV7.mjs";
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import "./chunk-
|
|
34
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-HX6MOYBO.mjs";
|
|
34
|
+
import "./chunk-6BHJLCAO.mjs";
|
|
35
|
+
import "./chunk-JVLZ3SOW.mjs";
|
|
36
|
+
import "./chunk-QSVMXMTQ.mjs";
|
|
37
|
+
import "./chunk-R4ZYMEDU.mjs";
|
|
38
|
+
import "./chunk-3RFRE7XG.mjs";
|
|
39
|
+
import "./chunk-TRYHX5S4.mjs";
|
|
35
40
|
import {
|
|
41
|
+
APP_CONFIG_FILE_NAMES,
|
|
36
42
|
SUPPORTED_AUTH_SOCIAL_PROVIDERS
|
|
37
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-YACY2572.mjs";
|
|
38
44
|
|
|
39
45
|
// src/types.ts
|
|
40
46
|
function defineCommand(command) {
|
|
@@ -42,6 +48,8 @@ function defineCommand(command) {
|
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
// src/cli.ts
|
|
51
|
+
import { cp, mkdtemp, readFile as readFile2, rm, writeFile as writeFile2 } from "fs/promises";
|
|
52
|
+
import { tmpdir } from "os";
|
|
45
53
|
import { resolve as resolve2 } from "path";
|
|
46
54
|
import { clearConfigCache, resolveConfigCachePath } from "@holo-js/config";
|
|
47
55
|
|
|
@@ -111,12 +119,7 @@ async function generateProjectAppKey(projectRoot) {
|
|
|
111
119
|
};
|
|
112
120
|
}
|
|
113
121
|
|
|
114
|
-
// src/
|
|
115
|
-
var AUTH_INSTALL_FEATURES = ["social", "workos", "clerk"];
|
|
116
|
-
var AUTH_SOCIAL_PROVIDER_MODES = ["default", "specific"];
|
|
117
|
-
var EVENTS_QUEUE_ACTIONS = ["skip", "enable"];
|
|
118
|
-
var MODEL_GENERATOR_OPTIONS = ["migration", "observer", "seeder", "factory"];
|
|
119
|
-
var COMMAND_LIST_DESCRIPTION_COLUMN = 32;
|
|
122
|
+
// src/command-executors.ts
|
|
120
123
|
var runtimeModulePromise;
|
|
121
124
|
var queueModulePromise;
|
|
122
125
|
var cacheModulePromise;
|
|
@@ -129,127 +132,110 @@ var securityModulePromise;
|
|
|
129
132
|
var devModulePromise;
|
|
130
133
|
var projectConfigModulePromise;
|
|
131
134
|
var projectDiscoveryModulePromise;
|
|
135
|
+
var projectPluginsModulePromise;
|
|
132
136
|
var projectRuntimeModulePromise;
|
|
133
137
|
var projectScaffoldModulePromise;
|
|
134
138
|
var agentSkillsModulePromise;
|
|
135
139
|
function loadRuntimeModule() {
|
|
136
|
-
runtimeModulePromise ??= import("./runtime-
|
|
140
|
+
runtimeModulePromise ??= import("./runtime-4TJYZLQV.mjs");
|
|
137
141
|
return runtimeModulePromise;
|
|
138
142
|
}
|
|
139
|
-
function loadQueueModule() {
|
|
140
|
-
queueModulePromise ??= import("./queue-O3OSLGOV.mjs");
|
|
141
|
-
return queueModulePromise;
|
|
142
|
-
}
|
|
143
|
-
function loadCacheModule() {
|
|
144
|
-
cacheModulePromise ??= import("./cache-KVRYC7FB.mjs");
|
|
145
|
-
return cacheModulePromise;
|
|
146
|
-
}
|
|
147
|
-
function loadQueueMigrationsModule() {
|
|
148
|
-
queueMigrationsModulePromise ??= import("./queue-migrations-7T42S4FX.mjs");
|
|
149
|
-
return queueMigrationsModulePromise;
|
|
150
|
-
}
|
|
151
|
-
function loadCacheMigrationsModule() {
|
|
152
|
-
cacheMigrationsModulePromise ??= import("./cache-migrations-APDFSFEX.mjs");
|
|
153
|
-
return cacheMigrationsModulePromise;
|
|
154
|
-
}
|
|
155
|
-
function loadMediaMigrationsModule() {
|
|
156
|
-
mediaMigrationsModulePromise ??= import("./media-migrations-IWCSCKSA.mjs");
|
|
157
|
-
return mediaMigrationsModulePromise;
|
|
158
|
-
}
|
|
159
|
-
function loadGeneratorsModule() {
|
|
160
|
-
generatorsModulePromise ??= import("./generators-WQHI7DBW.mjs");
|
|
161
|
-
return generatorsModulePromise;
|
|
162
|
-
}
|
|
163
|
-
function loadBroadcastModule() {
|
|
164
|
-
broadcastModulePromise ??= import("./broadcast-5MJ3GJK7.mjs");
|
|
165
|
-
return broadcastModulePromise;
|
|
166
|
-
}
|
|
167
143
|
function loadSecurityModule() {
|
|
168
|
-
securityModulePromise ??= import("./security-
|
|
144
|
+
securityModulePromise ??= import("./security-KYTLP4DF.mjs");
|
|
169
145
|
return securityModulePromise;
|
|
170
146
|
}
|
|
171
|
-
function loadDevModule() {
|
|
172
|
-
devModulePromise ??= import("./dev-CT4DRTLN.mjs");
|
|
173
|
-
return devModulePromise;
|
|
174
|
-
}
|
|
175
147
|
function loadProjectConfigModule() {
|
|
176
|
-
projectConfigModulePromise ??= import("./config-
|
|
148
|
+
projectConfigModulePromise ??= import("./config-BZHQK532.mjs");
|
|
177
149
|
return projectConfigModulePromise;
|
|
178
150
|
}
|
|
179
151
|
function loadProjectDiscoveryModule() {
|
|
180
|
-
projectDiscoveryModulePromise ??= import("./discovery-
|
|
152
|
+
projectDiscoveryModulePromise ??= import("./discovery-HNH3BLDL.mjs");
|
|
181
153
|
return projectDiscoveryModulePromise;
|
|
182
154
|
}
|
|
155
|
+
function loadProjectPluginsModule() {
|
|
156
|
+
projectPluginsModulePromise ??= import("./plugins-ZGLB6JO6.mjs");
|
|
157
|
+
return projectPluginsModulePromise;
|
|
158
|
+
}
|
|
183
159
|
function loadProjectRuntimeModule() {
|
|
184
|
-
projectRuntimeModulePromise ??= import("./runtime-
|
|
160
|
+
projectRuntimeModulePromise ??= import("./runtime-VR5BDPYQ.mjs");
|
|
185
161
|
return projectRuntimeModulePromise;
|
|
186
162
|
}
|
|
187
163
|
function loadProjectScaffoldModule() {
|
|
188
|
-
projectScaffoldModulePromise ??= import("./scaffold-
|
|
164
|
+
projectScaffoldModulePromise ??= import("./scaffold-ASEX5LEX.mjs");
|
|
189
165
|
return projectScaffoldModulePromise;
|
|
190
166
|
}
|
|
191
167
|
function loadAgentSkillsModule() {
|
|
192
|
-
agentSkillsModulePromise ??= import("./agent-skills-
|
|
168
|
+
agentSkillsModulePromise ??= import("./agent-skills-CHAXS2YN.mjs");
|
|
193
169
|
return agentSkillsModulePromise;
|
|
194
170
|
}
|
|
195
171
|
async function resolveRuntimeExecutor(runtimeExecutor) {
|
|
196
|
-
|
|
172
|
+
runtimeModulePromise ??= import("./runtime-4TJYZLQV.mjs");
|
|
173
|
+
return runtimeExecutor ?? (await runtimeModulePromise).withRuntimeEnvironment;
|
|
197
174
|
}
|
|
198
|
-
|
|
199
|
-
runProjectPrepare: async () => (await loadDevModule()).runProjectPrepare,
|
|
200
|
-
runProjectDevServer: async () => (await loadDevModule()).runProjectDevServer,
|
|
201
|
-
runProjectBuild: async () => (await loadDevModule()).runProjectBuild,
|
|
202
|
-
runProjectStartServer: async () => (await loadDevModule()).runProjectStartServer,
|
|
203
|
-
runProjectDependencyInstall: async () => (await loadDevModule()).runProjectDependencyInstall
|
|
204
|
-
};
|
|
205
|
-
async function resolveExecutor(executors, loaders, key) {
|
|
175
|
+
async function resolveExecutor(executors, loader, key) {
|
|
206
176
|
const existing = executors[key];
|
|
207
|
-
|
|
208
|
-
return existing;
|
|
209
|
-
}
|
|
210
|
-
return await loaders[key]();
|
|
177
|
+
return existing ? existing : await loader();
|
|
211
178
|
}
|
|
212
|
-
async function resolveProjectExecutor(
|
|
213
|
-
|
|
179
|
+
async function resolveProjectExecutor(executors, key) {
|
|
180
|
+
devModulePromise ??= import("./dev-GQT37XJU.mjs");
|
|
181
|
+
return resolveExecutor(executors, async () => (await devModulePromise)[key], key);
|
|
214
182
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
runBroadcastWorkCommand: async () => (await loadBroadcastModule()).runBroadcastWorkCommand
|
|
237
|
-
};
|
|
238
|
-
async function resolveQueueExecutor(queueExecutors, key) {
|
|
239
|
-
return await resolveExecutor(queueExecutors, queueExecutorLoaders, key);
|
|
183
|
+
async function resolveQueueExecutor(executors, key) {
|
|
184
|
+
return resolveExecutor(executors, async () => {
|
|
185
|
+
if (key === "runQueueFailedTableCommand" || key === "runQueueTableCommand") {
|
|
186
|
+
queueMigrationsModulePromise ??= import("./queue-migrations-U477YSFD.mjs");
|
|
187
|
+
const migrations = await queueMigrationsModulePromise;
|
|
188
|
+
return key === "runQueueFailedTableCommand" ? migrations.runQueueFailedTableCommand : migrations.runQueueTableCommand;
|
|
189
|
+
}
|
|
190
|
+
queueModulePromise ??= import("./queue-BEZDCZCY.mjs");
|
|
191
|
+
const queue = await queueModulePromise;
|
|
192
|
+
const resolved = {
|
|
193
|
+
runQueueFailedCommand: queue.runQueueFailedCommand,
|
|
194
|
+
runQueueFlushCommand: queue.runQueueFlushCommand,
|
|
195
|
+
runQueueWorkCommand: queue.runQueueWorkCommand,
|
|
196
|
+
runQueueForgetCommand: queue.runQueueForgetCommand,
|
|
197
|
+
runQueueListen: queue.runQueueListen,
|
|
198
|
+
runQueueRestartCommand: queue.runQueueRestartCommand,
|
|
199
|
+
runQueueRetryCommand: queue.runQueueRetryCommand,
|
|
200
|
+
runQueueClearCommand: queue.runQueueClearCommand
|
|
201
|
+
};
|
|
202
|
+
return resolved[key];
|
|
203
|
+
}, key);
|
|
240
204
|
}
|
|
241
|
-
async function resolveCacheExecutor(
|
|
242
|
-
return
|
|
205
|
+
async function resolveCacheExecutor(executors, key) {
|
|
206
|
+
return resolveExecutor(executors, async () => {
|
|
207
|
+
if (key === "runCacheTableCommand") {
|
|
208
|
+
cacheMigrationsModulePromise ??= import("./cache-migrations-PD2T5AV4.mjs");
|
|
209
|
+
return (await cacheMigrationsModulePromise).runCacheTableCommand;
|
|
210
|
+
}
|
|
211
|
+
cacheModulePromise ??= import("./cache-DUVBBOZU.mjs");
|
|
212
|
+
const cache = await cacheModulePromise;
|
|
213
|
+
const resolved = {
|
|
214
|
+
runCacheClearCommand: cache.runCacheClearCommand,
|
|
215
|
+
runCacheForgetCommand: cache.runCacheForgetCommand
|
|
216
|
+
};
|
|
217
|
+
return resolved[key];
|
|
218
|
+
}, key);
|
|
243
219
|
}
|
|
244
|
-
async function resolveMediaExecutor(
|
|
245
|
-
|
|
220
|
+
async function resolveMediaExecutor(executors, key) {
|
|
221
|
+
mediaMigrationsModulePromise ??= import("./media-migrations-EG34NYAG.mjs");
|
|
222
|
+
return resolveExecutor(executors, async () => (await mediaMigrationsModulePromise)[key], key);
|
|
246
223
|
}
|
|
247
|
-
async function resolveBroadcastExecutor(
|
|
248
|
-
|
|
224
|
+
async function resolveBroadcastExecutor(executors, key) {
|
|
225
|
+
broadcastModulePromise ??= import("./broadcast-5VZM5SGQ.mjs");
|
|
226
|
+
return resolveExecutor(executors, async () => (await broadcastModulePromise)[key], key);
|
|
249
227
|
}
|
|
250
228
|
async function resolveGeneratorCommand(key) {
|
|
251
|
-
|
|
229
|
+
generatorsModulePromise ??= import("./generators-3FVW4AEJ.mjs");
|
|
230
|
+
return (await generatorsModulePromise)[key];
|
|
252
231
|
}
|
|
232
|
+
|
|
233
|
+
// src/cli.ts
|
|
234
|
+
var AUTH_INSTALL_FEATURES = ["social", "workos", "clerk"];
|
|
235
|
+
var AUTH_SOCIAL_PROVIDER_MODES = ["default", "specific"];
|
|
236
|
+
var EVENTS_QUEUE_ACTIONS = ["skip", "enable"];
|
|
237
|
+
var MODEL_GENERATOR_OPTIONS = ["migration", "observer", "seeder", "factory"];
|
|
238
|
+
var COMMAND_LIST_DESCRIPTION_COLUMN = 32;
|
|
253
239
|
function createCommandContext(io, projectRoot, loadProject, input) {
|
|
254
240
|
return {
|
|
255
241
|
cwd: io.cwd,
|
|
@@ -259,6 +245,23 @@ function createCommandContext(io, projectRoot, loadProject, input) {
|
|
|
259
245
|
loadProject
|
|
260
246
|
};
|
|
261
247
|
}
|
|
248
|
+
function serializePassthroughInput(input) {
|
|
249
|
+
const tokens = [...input.args];
|
|
250
|
+
for (const [name, value] of Object.entries(input.flags)) {
|
|
251
|
+
if (value === false) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const flag = name.length === 1 ? `-${name}` : `--${name}`;
|
|
255
|
+
const values = Array.isArray(value) ? value : [value];
|
|
256
|
+
for (const currentValue of values) {
|
|
257
|
+
tokens.push(flag);
|
|
258
|
+
if (currentValue !== true) {
|
|
259
|
+
tokens.push(String(currentValue));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return tokens;
|
|
264
|
+
}
|
|
262
265
|
function printCommandList(io, registry) {
|
|
263
266
|
const internal = registry.filter((command) => command.source === "internal");
|
|
264
267
|
const app = registry.filter((command) => command.source === "app");
|
|
@@ -314,6 +317,130 @@ async function runProjectDependencyInstallForProject(context, projectExecutors,
|
|
|
314
317
|
writeLine(context.stdout, " - installed dependencies");
|
|
315
318
|
}
|
|
316
319
|
}
|
|
320
|
+
function formatPluginLabel(plugin) {
|
|
321
|
+
return plugin.name ? `${plugin.name} (${plugin.id})` : plugin.id;
|
|
322
|
+
}
|
|
323
|
+
function formatPluginContributionLines(plugin) {
|
|
324
|
+
const contributes = plugin.contributes;
|
|
325
|
+
if (!contributes) {
|
|
326
|
+
return [];
|
|
327
|
+
}
|
|
328
|
+
const lines = [];
|
|
329
|
+
if (contributes.framework) {
|
|
330
|
+
lines.push(`framework: ${contributes.framework.displayName}`);
|
|
331
|
+
}
|
|
332
|
+
if (contributes.dependencies?.holo?.length) {
|
|
333
|
+
lines.push(`holo packages: ${contributes.dependencies.holo.join(", ")}`);
|
|
334
|
+
}
|
|
335
|
+
if (contributes.dependencies?.runtime?.length) {
|
|
336
|
+
lines.push(`runtime packages: ${contributes.dependencies.runtime.join(", ")}`);
|
|
337
|
+
}
|
|
338
|
+
if (contributes.config?.files?.length) {
|
|
339
|
+
lines.push(`config files: ${contributes.config.files.join(", ")}`);
|
|
340
|
+
}
|
|
341
|
+
if (contributes.config?.env?.length) {
|
|
342
|
+
lines.push(`env keys: ${contributes.config.env.join(", ")}`);
|
|
343
|
+
}
|
|
344
|
+
if (contributes.broadcast?.drivers) {
|
|
345
|
+
const driverNames = Object.keys(contributes.broadcast.drivers);
|
|
346
|
+
if (driverNames.length > 0) {
|
|
347
|
+
lines.push(`broadcast drivers: ${driverNames.join(", ")}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (contributes.cache?.drivers) {
|
|
351
|
+
const driverNames = Object.keys(contributes.cache.drivers);
|
|
352
|
+
if (driverNames.length > 0) {
|
|
353
|
+
lines.push(`cache drivers: ${driverNames.join(", ")}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (contributes.queue?.drivers) {
|
|
357
|
+
const driverNames = Object.keys(contributes.queue.drivers);
|
|
358
|
+
if (driverNames.length > 0) {
|
|
359
|
+
lines.push(`queue drivers: ${driverNames.join(", ")}`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (contributes.mail?.drivers) {
|
|
363
|
+
const driverNames = Object.keys(contributes.mail.drivers);
|
|
364
|
+
if (driverNames.length > 0) {
|
|
365
|
+
lines.push(`mail drivers: ${driverNames.join(", ")}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (contributes.notifications?.channels) {
|
|
369
|
+
const channelNames = Object.keys(contributes.notifications.channels);
|
|
370
|
+
if (channelNames.length > 0) {
|
|
371
|
+
lines.push(`notification channels: ${channelNames.join(", ")}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (contributes.runtime?.boot) {
|
|
375
|
+
lines.push(`runtime boot: ${contributes.runtime.boot}`);
|
|
376
|
+
}
|
|
377
|
+
if (contributes.cli?.commands) {
|
|
378
|
+
lines.push(`cli commands: ${contributes.cli.commands}`);
|
|
379
|
+
}
|
|
380
|
+
if (contributes.migrations?.publish) {
|
|
381
|
+
lines.push(`migration publisher: ${contributes.migrations.publish}`);
|
|
382
|
+
}
|
|
383
|
+
return lines;
|
|
384
|
+
}
|
|
385
|
+
function writePluginDetails(context, loadedPlugin) {
|
|
386
|
+
writeLine(context.stdout, `Plugin: ${formatPluginLabel(loadedPlugin.definition)}`);
|
|
387
|
+
writeLine(context.stdout, ` - package: ${loadedPlugin.packageName}`);
|
|
388
|
+
if (loadedPlugin.definition.description) {
|
|
389
|
+
writeLine(context.stdout, ` - description: ${loadedPlugin.definition.description}`);
|
|
390
|
+
}
|
|
391
|
+
const contributionLines = formatPluginContributionLines(loadedPlugin.definition);
|
|
392
|
+
if (contributionLines.length === 0) {
|
|
393
|
+
writeLine(context.stdout, " - contributions: none");
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
for (const line of contributionLines) {
|
|
397
|
+
writeLine(context.stdout, ` - ${line}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
async function readPackageJsonSnapshot(projectRoot) {
|
|
401
|
+
return await readFile2(resolve2(projectRoot, "package.json"), "utf8");
|
|
402
|
+
}
|
|
403
|
+
async function restorePackageJsonSnapshot(projectRoot, snapshot) {
|
|
404
|
+
await writeFile2(resolve2(projectRoot, "package.json"), snapshot);
|
|
405
|
+
}
|
|
406
|
+
async function readAppConfigSnapshot(projectRoot) {
|
|
407
|
+
for (const fileName of APP_CONFIG_FILE_NAMES) {
|
|
408
|
+
const path = resolve2(projectRoot, fileName);
|
|
409
|
+
if (await fileExists(path)) {
|
|
410
|
+
return {
|
|
411
|
+
path,
|
|
412
|
+
contents: await readFile2(path, "utf8")
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return void 0;
|
|
417
|
+
}
|
|
418
|
+
async function restoreAppConfigSnapshot(snapshot) {
|
|
419
|
+
if (!snapshot) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
await writeFile2(snapshot.path, snapshot.contents);
|
|
423
|
+
}
|
|
424
|
+
async function readDirectorySnapshot(projectRoot, relativePath) {
|
|
425
|
+
const path = resolve2(projectRoot, relativePath);
|
|
426
|
+
if (!await fileExists(path)) {
|
|
427
|
+
return { path };
|
|
428
|
+
}
|
|
429
|
+
const snapshotPath = await mkdtemp(resolve2(tmpdir(), "holo-cli-plugin-add-"));
|
|
430
|
+
await cp(path, snapshotPath, { recursive: true, force: true });
|
|
431
|
+
return { path, snapshotPath };
|
|
432
|
+
}
|
|
433
|
+
async function restoreDirectorySnapshot(snapshot) {
|
|
434
|
+
await rm(snapshot.path, { recursive: true, force: true });
|
|
435
|
+
if (snapshot.snapshotPath) {
|
|
436
|
+
await cp(snapshot.snapshotPath, snapshot.path, { recursive: true, force: true });
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
async function cleanupDirectorySnapshot(snapshot) {
|
|
440
|
+
if (snapshot.snapshotPath) {
|
|
441
|
+
await rm(snapshot.snapshotPath, { recursive: true, force: true });
|
|
442
|
+
}
|
|
443
|
+
}
|
|
317
444
|
function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, projectExecutors = {}, broadcastExecutors = {}, securityExecutors = {}, cacheExecutors = {}, mediaExecutors = {}) {
|
|
318
445
|
return [
|
|
319
446
|
{
|
|
@@ -738,6 +865,196 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
738
865
|
await runProjectDependencyInstallAfterPackageJsonUpdate(context, projectExecutors, result.updatedPackageJson);
|
|
739
866
|
}
|
|
740
867
|
},
|
|
868
|
+
{
|
|
869
|
+
name: "plugin:add",
|
|
870
|
+
aliases: ["plugins:add"],
|
|
871
|
+
description: "Install and activate a Holo plugin package.",
|
|
872
|
+
usage: "holo plugin:add <package>",
|
|
873
|
+
source: "internal",
|
|
874
|
+
async prepare(input) {
|
|
875
|
+
const packageName = await ensureRequiredArg(context, input, 0, "Plugin package");
|
|
876
|
+
return { args: [packageName], flags: {} };
|
|
877
|
+
},
|
|
878
|
+
async run(commandContext) {
|
|
879
|
+
const packageName = String(commandContext.args[0] ?? "");
|
|
880
|
+
const plugins = await loadProjectPluginsModule();
|
|
881
|
+
const packageJsonSnapshot = await readPackageJsonSnapshot(context.projectRoot);
|
|
882
|
+
const appConfigSnapshot = await readAppConfigSnapshot(context.projectRoot);
|
|
883
|
+
const holoDirectorySnapshot = await readDirectorySnapshot(context.projectRoot, ".holo-js");
|
|
884
|
+
let dependencyInstallSucceeded = false;
|
|
885
|
+
let updatedDependencies = false;
|
|
886
|
+
let updatedPackageJson = false;
|
|
887
|
+
let loadedPlugin;
|
|
888
|
+
let contributedDependencies = [];
|
|
889
|
+
let updatedContributedDependencies = false;
|
|
890
|
+
let activated = false;
|
|
891
|
+
try {
|
|
892
|
+
updatedPackageJson = await upsertProjectDependency(context.projectRoot, packageName);
|
|
893
|
+
updatedDependencies = updatedPackageJson || updatedDependencies;
|
|
894
|
+
if (updatedPackageJson) {
|
|
895
|
+
await runProjectDependencyInstallForProject(context, projectExecutors, context.projectRoot);
|
|
896
|
+
dependencyInstallSucceeded = true;
|
|
897
|
+
await pinProjectDependencyVersions(context.projectRoot, [packageName]);
|
|
898
|
+
}
|
|
899
|
+
loadedPlugin = await plugins.loadHoloPluginFromPackage(context.projectRoot, packageName);
|
|
900
|
+
contributedDependencies = [
|
|
901
|
+
...loadedPlugin.definition.contributes?.dependencies?.holo ?? [],
|
|
902
|
+
...loadedPlugin.definition.contributes?.dependencies?.runtime ?? []
|
|
903
|
+
];
|
|
904
|
+
for (const dependencyName of contributedDependencies) {
|
|
905
|
+
const updatedContributedDependency = await upsertProjectDependency(context.projectRoot, dependencyName);
|
|
906
|
+
updatedContributedDependencies = updatedContributedDependency || updatedContributedDependencies;
|
|
907
|
+
}
|
|
908
|
+
updatedDependencies = updatedContributedDependencies || updatedDependencies;
|
|
909
|
+
if (updatedContributedDependencies) {
|
|
910
|
+
await runProjectDependencyInstallForProject(context, projectExecutors, context.projectRoot);
|
|
911
|
+
dependencyInstallSucceeded = true;
|
|
912
|
+
await pinProjectDependencyVersions(context.projectRoot, contributedDependencies);
|
|
913
|
+
}
|
|
914
|
+
activated = await plugins.activateProjectPlugin(context.projectRoot, packageName);
|
|
915
|
+
if (activated) {
|
|
916
|
+
const runProjectPrepare = await resolveProjectExecutor(projectExecutors, "runProjectPrepare");
|
|
917
|
+
await runProjectPrepare(context.projectRoot, context);
|
|
918
|
+
}
|
|
919
|
+
} catch (error) {
|
|
920
|
+
await restoreAppConfigSnapshot(appConfigSnapshot);
|
|
921
|
+
await restorePackageJsonSnapshot(context.projectRoot, packageJsonSnapshot);
|
|
922
|
+
await restoreDirectorySnapshot(holoDirectorySnapshot);
|
|
923
|
+
if (updatedDependencies && dependencyInstallSucceeded) {
|
|
924
|
+
await runProjectDependencyInstallForProject(context, projectExecutors, context.projectRoot).catch(() => void 0);
|
|
925
|
+
}
|
|
926
|
+
await cleanupDirectorySnapshot(holoDirectorySnapshot);
|
|
927
|
+
throw error;
|
|
928
|
+
}
|
|
929
|
+
writeLine(context.stdout, `Installed Holo plugin: ${formatPluginLabel(loadedPlugin.definition)}`);
|
|
930
|
+
writeLine(context.stdout, ` - package: ${updatedPackageJson ? "added" : "already present"} ${packageName}`);
|
|
931
|
+
if (contributedDependencies.length > 0) {
|
|
932
|
+
writeLine(
|
|
933
|
+
context.stdout,
|
|
934
|
+
` - dependencies: ${updatedContributedDependencies ? "updated" : "already present"} ${contributedDependencies.join(", ")}`
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
writeLine(context.stdout, ` - activation: ${activated ? "updated config/app.ts" : "already active"}`);
|
|
938
|
+
if (activated) {
|
|
939
|
+
writeLine(context.stdout, " - refreshed generated artifacts");
|
|
940
|
+
}
|
|
941
|
+
for (const line of formatPluginContributionLines(loadedPlugin.definition)) {
|
|
942
|
+
writeLine(context.stdout, ` - ${line}`);
|
|
943
|
+
}
|
|
944
|
+
await cleanupDirectorySnapshot(holoDirectorySnapshot);
|
|
945
|
+
}
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
name: "plugin:list",
|
|
949
|
+
aliases: ["plugins:list"],
|
|
950
|
+
description: "List active Holo plugins.",
|
|
951
|
+
usage: "holo plugin:list",
|
|
952
|
+
source: "internal",
|
|
953
|
+
async prepare() {
|
|
954
|
+
return { args: [], flags: {} };
|
|
955
|
+
},
|
|
956
|
+
async run() {
|
|
957
|
+
const plugins = await loadProjectPluginsModule();
|
|
958
|
+
const resolvedPlugins = await plugins.resolveProjectPlugins(context.projectRoot);
|
|
959
|
+
writeLine(context.stdout, "Active Holo plugins:");
|
|
960
|
+
if (resolvedPlugins.length === 0) {
|
|
961
|
+
writeLine(context.stdout, " (none)");
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
for (const resolvedPlugin of resolvedPlugins) {
|
|
965
|
+
if (resolvedPlugin.loaded) {
|
|
966
|
+
writeLine(context.stdout, ` - ${resolvedPlugin.packageName}: ${formatPluginLabel(resolvedPlugin.loaded.definition)}`);
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
writeLine(context.stdout, ` - ${resolvedPlugin.packageName}: failed`);
|
|
970
|
+
if (resolvedPlugin.error) {
|
|
971
|
+
writeLine(context.stdout, ` ${resolvedPlugin.error}`);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
name: "plugin:remove",
|
|
978
|
+
aliases: ["plugins:remove"],
|
|
979
|
+
description: "Deactivate a Holo plugin package.",
|
|
980
|
+
usage: "holo plugin:remove <package> [--uninstall]",
|
|
981
|
+
source: "internal",
|
|
982
|
+
async prepare(input) {
|
|
983
|
+
const packageName = await ensureRequiredArg(context, input, 0, "Plugin package");
|
|
984
|
+
return {
|
|
985
|
+
args: [packageName],
|
|
986
|
+
flags: {
|
|
987
|
+
...resolveBooleanFlag(input.flags, "uninstall") === true ? { uninstall: true } : {}
|
|
988
|
+
}
|
|
989
|
+
};
|
|
990
|
+
},
|
|
991
|
+
async run(commandContext) {
|
|
992
|
+
const packageName = String(commandContext.args[0] ?? "");
|
|
993
|
+
const plugins = await loadProjectPluginsModule();
|
|
994
|
+
const deactivated = await plugins.deactivateProjectPlugin(context.projectRoot, packageName);
|
|
995
|
+
const uninstalled = commandContext.flags.uninstall === true ? await removeProjectDependency(context.projectRoot, packageName) : false;
|
|
996
|
+
if (uninstalled) {
|
|
997
|
+
await runProjectDependencyInstallForProject(context, projectExecutors, context.projectRoot);
|
|
998
|
+
}
|
|
999
|
+
if (deactivated || uninstalled) {
|
|
1000
|
+
const runProjectPrepare = await resolveProjectExecutor(projectExecutors, "runProjectPrepare");
|
|
1001
|
+
await runProjectPrepare(context.projectRoot, context);
|
|
1002
|
+
}
|
|
1003
|
+
writeLine(context.stdout, deactivated ? "Removed Holo plugin activation." : "Holo plugin was not active.");
|
|
1004
|
+
writeLine(context.stdout, ` - package: ${packageName}`);
|
|
1005
|
+
if (commandContext.flags.uninstall === true) {
|
|
1006
|
+
writeLine(context.stdout, ` - dependency: ${uninstalled ? "removed from package.json" : "not present in package.json"}`);
|
|
1007
|
+
} else {
|
|
1008
|
+
writeLine(context.stdout, " - dependency: left installed");
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
},
|
|
1012
|
+
{
|
|
1013
|
+
name: "plugin:info",
|
|
1014
|
+
aliases: ["plugins:info"],
|
|
1015
|
+
description: "Show metadata for a Holo plugin package.",
|
|
1016
|
+
usage: "holo plugin:info <package>",
|
|
1017
|
+
source: "internal",
|
|
1018
|
+
async prepare(input) {
|
|
1019
|
+
const packageName = await ensureRequiredArg(context, input, 0, "Plugin package");
|
|
1020
|
+
return { args: [packageName], flags: {} };
|
|
1021
|
+
},
|
|
1022
|
+
async run(commandContext) {
|
|
1023
|
+
const packageName = String(commandContext.args[0] ?? "");
|
|
1024
|
+
const plugins = await loadProjectPluginsModule();
|
|
1025
|
+
const loadedPlugin = await plugins.loadHoloPluginFromPackage(context.projectRoot, packageName);
|
|
1026
|
+
writePluginDetails(context, loadedPlugin);
|
|
1027
|
+
}
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
name: "plugin:doctor",
|
|
1031
|
+
aliases: ["plugins:doctor"],
|
|
1032
|
+
description: "Validate active Holo plugin packages.",
|
|
1033
|
+
usage: "holo plugin:doctor",
|
|
1034
|
+
source: "internal",
|
|
1035
|
+
async prepare() {
|
|
1036
|
+
return { args: [], flags: {} };
|
|
1037
|
+
},
|
|
1038
|
+
async run() {
|
|
1039
|
+
const plugins = await loadProjectPluginsModule();
|
|
1040
|
+
const resolvedPlugins = await plugins.resolveProjectPlugins(context.projectRoot);
|
|
1041
|
+
const failedPlugins = resolvedPlugins.filter((resolvedPlugin) => !resolvedPlugin.loaded);
|
|
1042
|
+
if (resolvedPlugins.length === 0) {
|
|
1043
|
+
writeLine(context.stdout, "No active Holo plugins.");
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
for (const resolvedPlugin of resolvedPlugins) {
|
|
1047
|
+
if (resolvedPlugin.loaded) {
|
|
1048
|
+
writeLine(context.stdout, `Loaded ${resolvedPlugin.packageName}: ${formatPluginLabel(resolvedPlugin.loaded.definition)}`);
|
|
1049
|
+
continue;
|
|
1050
|
+
}
|
|
1051
|
+
writeLine(context.stdout, `Failed ${resolvedPlugin.packageName}: ${resolvedPlugin.error ?? "Unknown plugin loading error."}`);
|
|
1052
|
+
}
|
|
1053
|
+
if (failedPlugins.length > 0) {
|
|
1054
|
+
throw new Error(`${failedPlugins.length} Holo ${failedPlugins.length === 1 ? "plugin" : "plugins"} failed validation.`);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
},
|
|
741
1058
|
{
|
|
742
1059
|
name: "auth:notifications:publish",
|
|
743
1060
|
description: "Publish editable auth notification definitions into the application.",
|
|
@@ -812,13 +1129,18 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
812
1129
|
{
|
|
813
1130
|
name: "start",
|
|
814
1131
|
description: "Run the production framework server with Holo runtime preloads.",
|
|
815
|
-
usage: "holo start",
|
|
1132
|
+
usage: "holo start [...frameworkArgs]",
|
|
816
1133
|
source: "internal",
|
|
817
|
-
async prepare() {
|
|
818
|
-
return { args:
|
|
1134
|
+
async prepare(input) {
|
|
1135
|
+
return { args: input.args, flags: input.flags };
|
|
819
1136
|
},
|
|
820
|
-
async run() {
|
|
1137
|
+
async run(input) {
|
|
821
1138
|
const runProjectStartServer = await resolveProjectExecutor(projectExecutors, "runProjectStartServer");
|
|
1139
|
+
const passthroughArgs = serializePassthroughInput(input);
|
|
1140
|
+
if (passthroughArgs.length > 0) {
|
|
1141
|
+
await runProjectStartServer(context, context.projectRoot, void 0, passthroughArgs);
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
822
1144
|
await runProjectStartServer(context, context.projectRoot);
|
|
823
1145
|
}
|
|
824
1146
|
},
|
|
@@ -1654,10 +1976,15 @@ async function runCli(argv, io) {
|
|
|
1654
1976
|
};
|
|
1655
1977
|
const internalCommands = createInternalCommands(internalContext);
|
|
1656
1978
|
const registry = [...internalCommands];
|
|
1657
|
-
const
|
|
1979
|
+
const requestedInternalCommand = requestedCommandName ? findCommand(registry, requestedCommandName) : void 0;
|
|
1980
|
+
const canSkipAppDiscovery = requestedCommandName === "config:cache" || requestedCommandName === "config:clear" || requestedCommandName === "key:generate" || requestedCommandName === "new" || requestedCommandName === "install" || requestedCommandName === "agents:install" || requestedCommandName === "agent:install" || requestedCommandName === "ai:install" || requestedCommandName === "auth:notifications:publish" || requestedCommandName === "prepare" || requestedCommandName === "dev" || requestedCommandName === "build" || requestedCommandName === "cache:table" || requestedCommandName === "cache:clear" || requestedCommandName === "cache:forget" || requestedCommandName === "media:table" || requestedCommandName === "broadcast:work" || requestedCommandName === "queue:table" || requestedCommandName === "queue:failed-table" || requestedCommandName === "queue:work" || requestedCommandName === "queue:listen" || requestedCommandName === "queue:failed" || requestedCommandName === "queue:retry" || requestedCommandName === "queue:forget" || requestedCommandName === "queue:flush" || requestedCommandName === "queue:restart" || requestedCommandName === "queue:clear" || requestedCommandName === "rate-limit:clear" || requestedCommandName === "plugin:add" || requestedCommandName === "plugins:add" || requestedCommandName === "plugin:list" || requestedCommandName === "plugins:list" || requestedCommandName === "plugin:remove" || requestedCommandName === "plugins:remove" || requestedCommandName === "plugin:info" || requestedCommandName === "plugins:info" || requestedCommandName === "plugin:doctor" || requestedCommandName === "plugins:doctor" || typeof requestedInternalCommand !== "undefined" && requestedInternalCommand.name !== "list";
|
|
1658
1981
|
if (!canSkipAppDiscovery) {
|
|
1659
1982
|
const initialProject = await loadProject();
|
|
1660
|
-
const
|
|
1983
|
+
const pluginCommands = await (await loadProjectPluginsModule()).loadProjectPluginCommands(projectRoot);
|
|
1984
|
+
const appCommands = [
|
|
1985
|
+
...pluginCommands,
|
|
1986
|
+
...await (await loadProjectDiscoveryModule()).discoverAppCommands(projectRoot, initialProject.config)
|
|
1987
|
+
].map((entry) => createAppCommandDefinition(entry));
|
|
1661
1988
|
for (const appCommand of appCommands) {
|
|
1662
1989
|
const duplicate = findCommandConflict(registry, appCommand);
|
|
1663
1990
|
if (duplicate) {
|