@holo-js/cli 0.1.4 → 0.1.5
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/bin/holo.mjs +192 -35
- package/dist/{broadcast-CSSARTSA.mjs → broadcast-RT5KVZWP.mjs} +5 -5
- package/dist/{cache-4G6QGIZO.mjs → cache-NHCCHT44.mjs} +5 -5
- package/dist/{cache-migrations-NATT5WPQ.mjs → cache-migrations-R2RL2RVD.mjs} +15 -16
- package/dist/{chunk-EUIVXVJL.mjs → chunk-57SJ566R.mjs} +1 -1
- package/dist/chunk-5BLEC66P.mjs +284 -0
- package/dist/{chunk-JX2ZH6XY.mjs → chunk-5EU32E7X.mjs} +3 -3
- package/dist/{chunk-Q5F6C2D4.mjs → chunk-BAFQ2GOA.mjs} +1 -1
- package/dist/{chunk-CUL4RJTG.mjs → chunk-F4MT6GBK.mjs} +1 -1
- package/dist/{chunk-3OTCSFDG.mjs → chunk-MXKNQACM.mjs} +544 -82
- package/dist/{chunk-QYLSMF7V.mjs → chunk-OZUDZEAW.mjs} +142 -28
- package/dist/{chunk-66FHW725.mjs → chunk-R6BWRY3E.mjs} +28 -2
- package/dist/{chunk-ZLRO7HXY.mjs → chunk-SCCPDJGO.mjs} +156 -15
- package/dist/{chunk-VT5IDQG6.mjs → chunk-UZTDQKIY.mjs} +61 -44
- package/dist/{chunk-MZXN2YMI.mjs → chunk-VCEO6N5T.mjs} +3542 -2517
- package/dist/{config-LS5USBRB.mjs → config-5JSC6KJG.mjs} +3 -3
- package/dist/{dev-LZ3O2E3U.mjs → dev-OSLYSBTL.mjs} +7 -7
- package/dist/{discovery-GBLAUTXS.mjs → discovery-JLT2EOGH.mjs} +3 -3
- package/dist/{generators-DSN4GWJI.mjs → generators-ZIWACCBE.mjs} +134 -16
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +189 -32
- package/dist/media-migrations-UBAL2YVV.mjs +117 -0
- package/dist/{queue-FV35LLPR.mjs → queue-I66EISVS.mjs} +14 -14
- package/dist/{queue-migrations-SSIYKK5S.mjs → queue-migrations-UIAMAB6E.mjs} +24 -20
- package/dist/{runtime-EFZ5H5IL.mjs → runtime-MMQGO4PP.mjs} +9 -7
- package/dist/{runtime-OOSJ5JBY.mjs → runtime-ZKD6URAV.mjs} +1 -1
- package/dist/{scaffold-7OTDH4UR.mjs → scaffold-ISDVICNQ.mjs} +18 -5
- package/dist/{security-ATKDC26E.mjs → security-OZXTMYXF.mjs} +10 -7
- package/package.json +13 -12
- package/dist/broadcast-YSIJCL3R.mjs +0 -85
- package/dist/cache-OWQY4E7W.mjs +0 -67
- package/dist/cache-migrations-RVEA6CEU.mjs +0 -155
- package/dist/chunk-BWW5TDFI.mjs +0 -4
- package/dist/chunk-D4GG556Y.mjs +0 -23
- package/dist/chunk-DMH2B4UQ.mjs +0 -343
- package/dist/chunk-ET7UXHHQ.mjs +0 -166
- package/dist/chunk-G5ADO27Q.mjs +0 -463
- package/dist/chunk-GSQ3HTRO.mjs +0 -165
- package/dist/chunk-H7TJ4FB3.mjs +0 -848
- package/dist/chunk-ICJR7TS4.mjs +0 -66
- package/dist/chunk-M7J3YTHR.mjs +0 -26
- package/dist/chunk-QFUSWV3J.mjs +0 -3237
- package/dist/chunk-S7P7EBM3.mjs +0 -787
- package/dist/chunk-SRWJU3A5.mjs +0 -11
- package/dist/chunk-URK7C3VQ.mjs +0 -538
- package/dist/chunk-XUYKPU5Q.mjs +0 -272
- package/dist/config-DMWBMMGD.mjs +0 -26
- package/dist/dev-KQFT7RHR.mjs +0 -43
- package/dist/discovery-R733D2PO.mjs +0 -29
- package/dist/generators-WX45BI4U.mjs +0 -426
- package/dist/queue-6OG7VJ34.mjs +0 -626
- package/dist/queue-migrations-NK2EYX3J.mjs +0 -163
- package/dist/runtime-4BV3JODY.mjs +0 -56
- package/dist/runtime-ANBO7VQM.mjs +0 -33
- package/dist/scaffold-DRKBGS2K.mjs +0 -120
- package/dist/security-R7VH6W5H.mjs +0 -69
package/dist/index.mjs
CHANGED
|
@@ -14,24 +14,24 @@ import {
|
|
|
14
14
|
resolveNewProjectInput,
|
|
15
15
|
resolveStringFlag,
|
|
16
16
|
splitCsv
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5EU32E7X.mjs";
|
|
18
|
+
import {
|
|
19
|
+
hasProjectDependency
|
|
20
|
+
} from "./chunk-F4MT6GBK.mjs";
|
|
18
21
|
import {
|
|
19
22
|
writeLine
|
|
20
23
|
} from "./chunk-ZXDU7RHU.mjs";
|
|
21
24
|
import {
|
|
22
25
|
fileExists
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import {
|
|
25
|
-
hasProjectDependency
|
|
26
|
-
} from "./chunk-CUL4RJTG.mjs";
|
|
26
|
+
} from "./chunk-57SJ566R.mjs";
|
|
27
27
|
import "./chunk-D7O4SU6N.mjs";
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-UZTDQKIY.mjs";
|
|
29
|
+
import "./chunk-VCEO6N5T.mjs";
|
|
30
|
+
import "./chunk-5BLEC66P.mjs";
|
|
31
|
+
import "./chunk-MXKNQACM.mjs";
|
|
32
32
|
import {
|
|
33
33
|
SUPPORTED_AUTH_SOCIAL_PROVIDERS
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-R6BWRY3E.mjs";
|
|
35
35
|
|
|
36
36
|
// src/types.ts
|
|
37
37
|
function defineCommand(command) {
|
|
@@ -39,13 +39,82 @@ function defineCommand(command) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// src/cli.ts
|
|
42
|
-
import { resolve } from "path";
|
|
42
|
+
import { resolve as resolve2 } from "path";
|
|
43
43
|
import { clearConfigCache, resolveConfigCachePath } from "@holo-js/config";
|
|
44
|
+
|
|
45
|
+
// src/app-key.ts
|
|
46
|
+
import { randomBytes } from "crypto";
|
|
47
|
+
import { readFile, writeFile } from "fs/promises";
|
|
48
|
+
import { resolve } from "path";
|
|
49
|
+
var appKeyLinePattern = /^(\s*(?:export\s+)?APP_KEY\s*=\s*)(.*)$/;
|
|
50
|
+
function generateAppKey() {
|
|
51
|
+
return randomBytes(32).toString("base64");
|
|
52
|
+
}
|
|
53
|
+
function isEmptyAppKeyValue(value) {
|
|
54
|
+
const normalized = value.trim();
|
|
55
|
+
return normalized === "" || normalized === '""' || normalized === "''";
|
|
56
|
+
}
|
|
57
|
+
function renderEnvWithAppKey(existingContents, appKey) {
|
|
58
|
+
if (!existingContents) {
|
|
59
|
+
return {
|
|
60
|
+
contents: `APP_KEY=${appKey}
|
|
61
|
+
`,
|
|
62
|
+
changed: true
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const lines = existingContents.replace(/\r\n/g, "\n").split("\n");
|
|
66
|
+
const appKeyIndex = lines.findIndex((line) => appKeyLinePattern.test(line));
|
|
67
|
+
if (appKeyIndex === -1) {
|
|
68
|
+
return {
|
|
69
|
+
contents: `${existingContents.replace(/\r\n/g, "\n").replace(/\n*$/, "")}
|
|
70
|
+
APP_KEY=${appKey}
|
|
71
|
+
`,
|
|
72
|
+
changed: true
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const appKeyLine = lines[appKeyIndex];
|
|
76
|
+
const match = appKeyLine.match(appKeyLinePattern);
|
|
77
|
+
const prefix = match[1];
|
|
78
|
+
const value = match[2];
|
|
79
|
+
if (!isEmptyAppKeyValue(value)) {
|
|
80
|
+
return {
|
|
81
|
+
contents: existingContents,
|
|
82
|
+
changed: false
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
lines[appKeyIndex] = `${prefix}${appKey}`;
|
|
86
|
+
return {
|
|
87
|
+
contents: `${lines.join("\n").replace(/\n*$/, "")}
|
|
88
|
+
`,
|
|
89
|
+
changed: true
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function generateProjectAppKey(projectRoot) {
|
|
93
|
+
const envPath = resolve(projectRoot, ".env");
|
|
94
|
+
const existingContents = await readFile(envPath, "utf8").catch(() => void 0);
|
|
95
|
+
const key = generateAppKey();
|
|
96
|
+
const nextEnv = renderEnvWithAppKey(existingContents, key);
|
|
97
|
+
if (!nextEnv.changed || typeof nextEnv.contents !== "string") {
|
|
98
|
+
return {
|
|
99
|
+
envPath,
|
|
100
|
+
generated: false
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
await writeFile(envPath, nextEnv.contents, "utf8");
|
|
104
|
+
return {
|
|
105
|
+
envPath,
|
|
106
|
+
generated: true,
|
|
107
|
+
key
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/cli.ts
|
|
44
112
|
var runtimeModulePromise;
|
|
45
113
|
var queueModulePromise;
|
|
46
114
|
var cacheModulePromise;
|
|
47
115
|
var queueMigrationsModulePromise;
|
|
48
116
|
var cacheMigrationsModulePromise;
|
|
117
|
+
var mediaMigrationsModulePromise;
|
|
49
118
|
var generatorsModulePromise;
|
|
50
119
|
var broadcastModulePromise;
|
|
51
120
|
var securityModulePromise;
|
|
@@ -55,55 +124,59 @@ var projectDiscoveryModulePromise;
|
|
|
55
124
|
var projectRuntimeModulePromise;
|
|
56
125
|
var projectScaffoldModulePromise;
|
|
57
126
|
function loadRuntimeModule() {
|
|
58
|
-
runtimeModulePromise ??= import("./runtime-
|
|
127
|
+
runtimeModulePromise ??= import("./runtime-MMQGO4PP.mjs");
|
|
59
128
|
return runtimeModulePromise;
|
|
60
129
|
}
|
|
61
130
|
function loadQueueModule() {
|
|
62
|
-
queueModulePromise ??= import("./queue-
|
|
131
|
+
queueModulePromise ??= import("./queue-I66EISVS.mjs");
|
|
63
132
|
return queueModulePromise;
|
|
64
133
|
}
|
|
65
134
|
function loadCacheModule() {
|
|
66
|
-
cacheModulePromise ??= import("./cache-
|
|
135
|
+
cacheModulePromise ??= import("./cache-NHCCHT44.mjs");
|
|
67
136
|
return cacheModulePromise;
|
|
68
137
|
}
|
|
69
138
|
function loadQueueMigrationsModule() {
|
|
70
|
-
queueMigrationsModulePromise ??= import("./queue-migrations-
|
|
139
|
+
queueMigrationsModulePromise ??= import("./queue-migrations-UIAMAB6E.mjs");
|
|
71
140
|
return queueMigrationsModulePromise;
|
|
72
141
|
}
|
|
73
142
|
function loadCacheMigrationsModule() {
|
|
74
|
-
cacheMigrationsModulePromise ??= import("./cache-migrations-
|
|
143
|
+
cacheMigrationsModulePromise ??= import("./cache-migrations-R2RL2RVD.mjs");
|
|
75
144
|
return cacheMigrationsModulePromise;
|
|
76
145
|
}
|
|
146
|
+
function loadMediaMigrationsModule() {
|
|
147
|
+
mediaMigrationsModulePromise ??= import("./media-migrations-UBAL2YVV.mjs");
|
|
148
|
+
return mediaMigrationsModulePromise;
|
|
149
|
+
}
|
|
77
150
|
function loadGeneratorsModule() {
|
|
78
|
-
generatorsModulePromise ??= import("./generators-
|
|
151
|
+
generatorsModulePromise ??= import("./generators-ZIWACCBE.mjs");
|
|
79
152
|
return generatorsModulePromise;
|
|
80
153
|
}
|
|
81
154
|
function loadBroadcastModule() {
|
|
82
|
-
broadcastModulePromise ??= import("./broadcast-
|
|
155
|
+
broadcastModulePromise ??= import("./broadcast-RT5KVZWP.mjs");
|
|
83
156
|
return broadcastModulePromise;
|
|
84
157
|
}
|
|
85
158
|
function loadSecurityModule() {
|
|
86
|
-
securityModulePromise ??= import("./security-
|
|
159
|
+
securityModulePromise ??= import("./security-OZXTMYXF.mjs");
|
|
87
160
|
return securityModulePromise;
|
|
88
161
|
}
|
|
89
162
|
function loadDevModule() {
|
|
90
|
-
devModulePromise ??= import("./dev-
|
|
163
|
+
devModulePromise ??= import("./dev-OSLYSBTL.mjs");
|
|
91
164
|
return devModulePromise;
|
|
92
165
|
}
|
|
93
166
|
function loadProjectConfigModule() {
|
|
94
|
-
projectConfigModulePromise ??= import("./config-
|
|
167
|
+
projectConfigModulePromise ??= import("./config-5JSC6KJG.mjs");
|
|
95
168
|
return projectConfigModulePromise;
|
|
96
169
|
}
|
|
97
170
|
function loadProjectDiscoveryModule() {
|
|
98
|
-
projectDiscoveryModulePromise ??= import("./discovery-
|
|
171
|
+
projectDiscoveryModulePromise ??= import("./discovery-JLT2EOGH.mjs");
|
|
99
172
|
return projectDiscoveryModulePromise;
|
|
100
173
|
}
|
|
101
174
|
function loadProjectRuntimeModule() {
|
|
102
|
-
projectRuntimeModulePromise ??= import("./runtime-
|
|
175
|
+
projectRuntimeModulePromise ??= import("./runtime-ZKD6URAV.mjs");
|
|
103
176
|
return projectRuntimeModulePromise;
|
|
104
177
|
}
|
|
105
178
|
function loadProjectScaffoldModule() {
|
|
106
|
-
projectScaffoldModulePromise ??= import("./scaffold-
|
|
179
|
+
projectScaffoldModulePromise ??= import("./scaffold-ISDVICNQ.mjs");
|
|
107
180
|
return projectScaffoldModulePromise;
|
|
108
181
|
}
|
|
109
182
|
async function resolveRuntimeExecutor(runtimeExecutor) {
|
|
@@ -138,6 +211,9 @@ var cacheExecutorLoaders = {
|
|
|
138
211
|
runCacheClearCommand: async () => (await loadCacheModule()).runCacheClearCommand,
|
|
139
212
|
runCacheForgetCommand: async () => (await loadCacheModule()).runCacheForgetCommand
|
|
140
213
|
};
|
|
214
|
+
var mediaExecutorLoaders = {
|
|
215
|
+
runMediaTableCommand: async () => (await loadMediaMigrationsModule()).runMediaTableCommand
|
|
216
|
+
};
|
|
141
217
|
var broadcastExecutorLoaders = {
|
|
142
218
|
runBroadcastWorkCommand: async () => (await loadBroadcastModule()).runBroadcastWorkCommand
|
|
143
219
|
};
|
|
@@ -155,6 +231,13 @@ async function resolveCacheExecutor(cacheExecutors, key) {
|
|
|
155
231
|
}
|
|
156
232
|
return cacheExecutorLoaders[key]();
|
|
157
233
|
}
|
|
234
|
+
async function resolveMediaExecutor(mediaExecutors, key) {
|
|
235
|
+
const existing = mediaExecutors[key];
|
|
236
|
+
if (existing) {
|
|
237
|
+
return existing;
|
|
238
|
+
}
|
|
239
|
+
return mediaExecutorLoaders[key]();
|
|
240
|
+
}
|
|
158
241
|
async function resolveBroadcastExecutor(broadcastExecutors, key) {
|
|
159
242
|
const existing = broadcastExecutors[key];
|
|
160
243
|
if (existing) {
|
|
@@ -219,7 +302,7 @@ function resolvePackageManagerDevCommand(packageManager) {
|
|
|
219
302
|
return "yarn dev";
|
|
220
303
|
}
|
|
221
304
|
}
|
|
222
|
-
function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, projectExecutors = {}, broadcastExecutors = {}, securityExecutors = {}, cacheExecutors = {}) {
|
|
305
|
+
function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, projectExecutors = {}, broadcastExecutors = {}, securityExecutors = {}, cacheExecutors = {}, mediaExecutors = {}) {
|
|
223
306
|
return [
|
|
224
307
|
{
|
|
225
308
|
name: "list",
|
|
@@ -260,7 +343,7 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
260
343
|
const optionalPackages = normalizeOptionalPackages(
|
|
261
344
|
(collectMultiStringFlag(commandContext.flags, "package") ?? []).flatMap((entry) => splitCsv(entry) ?? [])
|
|
262
345
|
);
|
|
263
|
-
const targetDir =
|
|
346
|
+
const targetDir = resolve2(commandContext.cwd, projectName);
|
|
264
347
|
const { scaffoldProject } = await loadProjectScaffoldModule();
|
|
265
348
|
await scaffoldProject(targetDir, {
|
|
266
349
|
projectName,
|
|
@@ -278,10 +361,26 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
278
361
|
writeLine(context.stdout, ` ${resolvePackageManagerDevCommand(packageManager)}`);
|
|
279
362
|
}
|
|
280
363
|
},
|
|
364
|
+
{
|
|
365
|
+
name: "key:generate",
|
|
366
|
+
description: "Generate APP_KEY in the project .env file when it is missing.",
|
|
367
|
+
usage: "holo key:generate",
|
|
368
|
+
source: "internal",
|
|
369
|
+
async prepare() {
|
|
370
|
+
return { args: [], flags: {} };
|
|
371
|
+
},
|
|
372
|
+
async run() {
|
|
373
|
+
const result = await generateProjectAppKey(context.projectRoot);
|
|
374
|
+
writeLine(
|
|
375
|
+
context.stdout,
|
|
376
|
+
result.generated ? `Generated APP_KEY in ${result.envPath}.` : `APP_KEY is already set in ${result.envPath}.`
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
},
|
|
281
380
|
{
|
|
282
381
|
name: "install",
|
|
283
382
|
description: "Install first-party Holo support into an existing project.",
|
|
284
|
-
usage: "holo install <queue|events|auth|authorization|notifications|mail|broadcast|security|cache> [--driver <queue: sync|file|redis|database; cache: file|redis|database
|
|
383
|
+
usage: "holo install <queue|events|auth|authorization|notifications|mail|broadcast|security|cache|media> [--driver <queue: sync|file|redis|database; cache: file|redis|database>] [--social] [--provider <google|github|discord|facebook|apple|linkedin>] [--workos] [--clerk]",
|
|
285
384
|
source: "internal",
|
|
286
385
|
async prepare(input) {
|
|
287
386
|
const target = normalizeChoice(
|
|
@@ -311,6 +410,9 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
311
410
|
if (target === "security" && requestedDriver) {
|
|
312
411
|
throw new Error("The security installer does not support --driver.");
|
|
313
412
|
}
|
|
413
|
+
if (target === "media" && requestedDriver) {
|
|
414
|
+
throw new Error("The media installer does not support --driver.");
|
|
415
|
+
}
|
|
314
416
|
const driver = target === "queue" ? requestedDriver ? normalizeChoice(requestedDriver, SUPPORTED_QUEUE_INSTALL_DRIVERS, "queue driver") : "sync" : target === "cache" ? requestedDriver ? normalizeChoice(requestedDriver, SUPPORTED_CACHE_INSTALL_DRIVERS, "cache driver") : "file" : void 0;
|
|
315
417
|
const socialProviders = target === "auth" ? (collectMultiStringFlag(input.flags, "provider") ?? []).flatMap((entry) => splitCsv(entry) ?? []).map((provider) => normalizeChoice(provider, SUPPORTED_AUTH_SOCIAL_PROVIDERS, "auth social provider")) : [];
|
|
316
418
|
const social = target === "auth" ? resolveBooleanFlag(input.flags, "social") === true || socialProviders.length > 0 : false;
|
|
@@ -335,9 +437,9 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
335
437
|
installEventsIntoProject,
|
|
336
438
|
installQueueIntoProject: installQueueIntoProject2
|
|
337
439
|
} = await loadProjectScaffoldModule();
|
|
440
|
+
const queueConfigured = await hasProjectDependency(context.projectRoot, "@holo-js/queue") || await fileExists(resolve2(context.projectRoot, "config/queue.ts")) || await fileExists(resolve2(context.projectRoot, "config/queue.mts")) || await fileExists(resolve2(context.projectRoot, "config/queue.js")) || await fileExists(resolve2(context.projectRoot, "config/queue.mjs"));
|
|
338
441
|
const eventsResult = await installEventsIntoProject(context.projectRoot);
|
|
339
442
|
let queueResult;
|
|
340
|
-
const queueConfigured = await hasProjectDependency(context.projectRoot, "@holo-js/queue") || await fileExists(resolve(context.projectRoot, "config/queue.ts")) || await fileExists(resolve(context.projectRoot, "config/queue.mts")) || await fileExists(resolve(context.projectRoot, "config/queue.js")) || await fileExists(resolve(context.projectRoot, "config/queue.mjs"));
|
|
341
443
|
if (!queueConfigured && isInteractive(context, commandContext.flags)) {
|
|
342
444
|
const enableQueuedListeners = await confirm(
|
|
343
445
|
context,
|
|
@@ -371,11 +473,13 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
371
473
|
workos: commandContext.flags.workos === true,
|
|
372
474
|
clerk: commandContext.flags.clerk === true
|
|
373
475
|
});
|
|
374
|
-
const changed2 = result2.updatedPackageJson || result2.createdAuthConfig || result2.createdSessionConfig || result2.createdUserModel || result2.createdMigrationFiles.length > 0 || result2.updatedEnv || result2.updatedEnvExample;
|
|
476
|
+
const changed2 = result2.updatedPackageJson || result2.createdAuthConfig || result2.createdSessionConfig || result2.createdSecurityConfig || result2.createdCorsConfig || result2.createdUserModel || result2.createdMigrationFiles.length > 0 || result2.updatedEnv || result2.updatedEnvExample;
|
|
375
477
|
writeLine(context.stdout, changed2 ? "Installed auth support." : "Auth support is already installed.");
|
|
376
478
|
if (result2.updatedPackageJson) writeLine(context.stdout, " - updated package.json");
|
|
377
479
|
if (result2.createdAuthConfig) writeLine(context.stdout, " - created config/auth.ts");
|
|
378
480
|
if (result2.createdSessionConfig) writeLine(context.stdout, " - created config/session.ts");
|
|
481
|
+
if (result2.createdSecurityConfig) writeLine(context.stdout, " - created config/security.ts");
|
|
482
|
+
if (result2.createdCorsConfig) writeLine(context.stdout, " - created config/cors.ts");
|
|
379
483
|
if (result2.createdUserModel) writeLine(context.stdout, " - created server/models/User.ts");
|
|
380
484
|
if (result2.updatedEnv) writeLine(context.stdout, " - updated .env");
|
|
381
485
|
if (result2.updatedEnvExample) writeLine(context.stdout, " - updated .env.example");
|
|
@@ -409,9 +513,11 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
409
513
|
if (target === "mail") {
|
|
410
514
|
const { installMailIntoProject } = await loadProjectScaffoldModule();
|
|
411
515
|
const result2 = await installMailIntoProject(context.projectRoot);
|
|
412
|
-
const changed2 = result2.updatedPackageJson || result2.createdMailConfig || result2.createdMailDirectory;
|
|
516
|
+
const changed2 = result2.updatedPackageJson || result2.createdMailConfig || result2.createdMailDirectory || result2.updatedEnv || result2.updatedEnvExample;
|
|
413
517
|
writeLine(context.stdout, changed2 ? "Installed mail support." : "Mail support is already installed.");
|
|
414
518
|
if (result2.updatedPackageJson) writeLine(context.stdout, " - updated package.json");
|
|
519
|
+
if (result2.updatedEnv) writeLine(context.stdout, " - updated .env");
|
|
520
|
+
if (result2.updatedEnvExample) writeLine(context.stdout, " - updated .env.example");
|
|
415
521
|
if (result2.createdMailConfig) writeLine(context.stdout, " - created config/mail.ts");
|
|
416
522
|
if (result2.createdMailDirectory) writeLine(context.stdout, " - created server/mail");
|
|
417
523
|
return;
|
|
@@ -434,10 +540,11 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
434
540
|
if (target === "security") {
|
|
435
541
|
const { installSecurityIntoProject } = await loadProjectScaffoldModule();
|
|
436
542
|
const result2 = await installSecurityIntoProject(context.projectRoot);
|
|
437
|
-
const changed2 = result2.updatedPackageJson || result2.createdSecurityConfig;
|
|
543
|
+
const changed2 = result2.updatedPackageJson || result2.createdSecurityConfig || result2.createdCorsConfig;
|
|
438
544
|
writeLine(context.stdout, changed2 ? "Installed security support." : "Security support is already installed.");
|
|
439
545
|
if (result2.updatedPackageJson) writeLine(context.stdout, " - updated package.json");
|
|
440
546
|
if (result2.createdSecurityConfig) writeLine(context.stdout, " - created config/security.ts");
|
|
547
|
+
if (result2.createdCorsConfig) writeLine(context.stdout, " - created config/cors.ts");
|
|
441
548
|
return;
|
|
442
549
|
}
|
|
443
550
|
if (target === "cache") {
|
|
@@ -455,6 +562,16 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
455
562
|
if (result2.databaseDriver) writeLine(context.stdout, ' - run "holo cache:table" to create the cache tables');
|
|
456
563
|
return;
|
|
457
564
|
}
|
|
565
|
+
if (target === "media") {
|
|
566
|
+
const { installMediaIntoProject } = await loadProjectScaffoldModule();
|
|
567
|
+
const result2 = await installMediaIntoProject(context.projectRoot);
|
|
568
|
+
const changed2 = result2.createdMediaConfig || result2.updatedPackageJson || result2.createdMigrationFiles.length > 0;
|
|
569
|
+
writeLine(context.stdout, changed2 ? "Installed media support." : "Media support is already installed.");
|
|
570
|
+
if (result2.createdMediaConfig) writeLine(context.stdout, " - created config/media.ts");
|
|
571
|
+
if (result2.updatedPackageJson) writeLine(context.stdout, " - updated package.json");
|
|
572
|
+
if (result2.createdMigrationFiles.length > 0) writeLine(context.stdout, " - created media migration");
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
458
575
|
if (target !== "queue") {
|
|
459
576
|
throw new Error(`Unsupported install target: ${target || "(empty)"}.`);
|
|
460
577
|
}
|
|
@@ -471,6 +588,33 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
471
588
|
if (result.createdJobsDirectory) writeLine(context.stdout, " - created server/jobs");
|
|
472
589
|
}
|
|
473
590
|
},
|
|
591
|
+
{
|
|
592
|
+
name: "auth:notifications:publish",
|
|
593
|
+
description: "Publish editable auth notification definitions into the application.",
|
|
594
|
+
usage: "holo auth:notifications:publish",
|
|
595
|
+
source: "internal",
|
|
596
|
+
async prepare() {
|
|
597
|
+
return { args: [], flags: {} };
|
|
598
|
+
},
|
|
599
|
+
async run() {
|
|
600
|
+
const { publishAuthNotificationsIntoProject } = await loadProjectScaffoldModule();
|
|
601
|
+
const result = await publishAuthNotificationsIntoProject(context.projectRoot);
|
|
602
|
+
const changed = result.createdFiles.length > 0;
|
|
603
|
+
writeLine(context.stdout, changed ? "Published auth notification files." : "Auth notification files are already published.");
|
|
604
|
+
for (const filePath of result.createdFiles) {
|
|
605
|
+
writeLine(context.stdout, ` - created ${filePath}`);
|
|
606
|
+
}
|
|
607
|
+
for (const filePath of result.skippedFiles) {
|
|
608
|
+
writeLine(context.stdout, ` - skipped existing ${filePath}`);
|
|
609
|
+
}
|
|
610
|
+
if (!result.hasMailDependency) {
|
|
611
|
+
writeLine(
|
|
612
|
+
context.stdout,
|
|
613
|
+
" - note: install @holo-js/mail or configure a notification mailer before email delivery can send."
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
},
|
|
474
618
|
{
|
|
475
619
|
name: "prepare",
|
|
476
620
|
description: "Discover Holo resources and refresh generated registries.",
|
|
@@ -587,6 +731,19 @@ function createInternalCommands(context, runtimeExecutor, queueExecutors = {}, p
|
|
|
587
731
|
);
|
|
588
732
|
}
|
|
589
733
|
},
|
|
734
|
+
{
|
|
735
|
+
name: "media:table",
|
|
736
|
+
description: "Generate the media table migration.",
|
|
737
|
+
usage: "holo media:table",
|
|
738
|
+
source: "internal",
|
|
739
|
+
async prepare() {
|
|
740
|
+
return { args: [], flags: {} };
|
|
741
|
+
},
|
|
742
|
+
async run() {
|
|
743
|
+
const runMediaTableCommand = await resolveMediaExecutor(mediaExecutors, "runMediaTableCommand");
|
|
744
|
+
await runMediaTableCommand(context, context.projectRoot);
|
|
745
|
+
}
|
|
746
|
+
},
|
|
590
747
|
{
|
|
591
748
|
name: "queue:table",
|
|
592
749
|
description: "Generate the database queue jobs table migration.",
|
|
@@ -1323,7 +1480,7 @@ async function runCli(argv, io) {
|
|
|
1323
1480
|
};
|
|
1324
1481
|
const internalCommands = createInternalCommands(internalContext);
|
|
1325
1482
|
const registry = [...internalCommands];
|
|
1326
|
-
const canSkipAppDiscovery = requestedCommandName === "config:cache" || requestedCommandName === "config:clear" || requestedCommandName === "new" || requestedCommandName === "install" || requestedCommandName === "prepare" || requestedCommandName === "dev" || requestedCommandName === "build" || requestedCommandName === "cache:table" || requestedCommandName === "cache:clear" || requestedCommandName === "cache:forget" || 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";
|
|
1483
|
+
const canSkipAppDiscovery = requestedCommandName === "config:cache" || requestedCommandName === "config:clear" || requestedCommandName === "key:generate" || requestedCommandName === "new" || requestedCommandName === "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";
|
|
1327
1484
|
if (!canSkipAppDiscovery) {
|
|
1328
1485
|
const initialProject = await loadProject();
|
|
1329
1486
|
const appCommands = (await (await loadProjectDiscoveryModule()).discoverAppCommands(projectRoot, initialProject.config)).map((entry) => createAppCommandDefinition(entry));
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRegistryMigrationSlug,
|
|
3
|
+
hasRegisteredCreateTableMigration,
|
|
4
|
+
hasRegisteredMigrationSlug,
|
|
5
|
+
nextMigrationTemplate
|
|
6
|
+
} from "./chunk-BAFQ2GOA.mjs";
|
|
7
|
+
import {
|
|
8
|
+
writeLine
|
|
9
|
+
} from "./chunk-ZXDU7RHU.mjs";
|
|
10
|
+
import "./chunk-57SJ566R.mjs";
|
|
11
|
+
import "./chunk-D7O4SU6N.mjs";
|
|
12
|
+
import {
|
|
13
|
+
prepareProjectDiscovery
|
|
14
|
+
} from "./chunk-UZTDQKIY.mjs";
|
|
15
|
+
import "./chunk-VCEO6N5T.mjs";
|
|
16
|
+
import {
|
|
17
|
+
ensureProjectConfig
|
|
18
|
+
} from "./chunk-5BLEC66P.mjs";
|
|
19
|
+
import {
|
|
20
|
+
loadGeneratedProjectRegistry
|
|
21
|
+
} from "./chunk-MXKNQACM.mjs";
|
|
22
|
+
import {
|
|
23
|
+
makeProjectRelativePath,
|
|
24
|
+
resolveDefaultArtifactPath,
|
|
25
|
+
writeTextFile
|
|
26
|
+
} from "./chunk-R6BWRY3E.mjs";
|
|
27
|
+
|
|
28
|
+
// src/media-migrations.ts
|
|
29
|
+
import { readdir } from "fs/promises";
|
|
30
|
+
import { resolve } from "path";
|
|
31
|
+
import { normalizeMigrationSlug } from "@holo-js/db";
|
|
32
|
+
var DEFAULT_MEDIA_TABLE = "media";
|
|
33
|
+
function normalizeMediaMigrationName(tableName = DEFAULT_MEDIA_TABLE) {
|
|
34
|
+
return normalizeMigrationSlug(`create_${tableName.replaceAll(".", "_")}_table`);
|
|
35
|
+
}
|
|
36
|
+
function renderMediaTableMigration(tableName = DEFAULT_MEDIA_TABLE) {
|
|
37
|
+
const tableNameLiteral = JSON.stringify(tableName);
|
|
38
|
+
return [
|
|
39
|
+
"import { defineMigration, type MigrationContext } from '@holo-js/db'",
|
|
40
|
+
"",
|
|
41
|
+
"export default defineMigration({",
|
|
42
|
+
" async up({ schema }: MigrationContext) {",
|
|
43
|
+
` await schema.createTable(${tableNameLiteral}, (table) => {`,
|
|
44
|
+
" table.id()",
|
|
45
|
+
" table.uuid('uuid').unique()",
|
|
46
|
+
" table.string('model_type')",
|
|
47
|
+
" table.string('model_id')",
|
|
48
|
+
" table.string('collection_name').default('default')",
|
|
49
|
+
" table.string('name')",
|
|
50
|
+
" table.string('file_name')",
|
|
51
|
+
" table.string('disk')",
|
|
52
|
+
" table.string('conversions_disk').nullable()",
|
|
53
|
+
" table.string('mime_type').nullable()",
|
|
54
|
+
" table.string('extension').nullable()",
|
|
55
|
+
" table.bigInteger('size')",
|
|
56
|
+
" table.string('path')",
|
|
57
|
+
" table.json('generated_conversions').default({})",
|
|
58
|
+
" table.integer('order_column').default(1)",
|
|
59
|
+
" table.timestamps()",
|
|
60
|
+
" table.index(['model_type', 'model_id'])",
|
|
61
|
+
" table.index(['model_type', 'model_id', 'collection_name'])",
|
|
62
|
+
" })",
|
|
63
|
+
" },",
|
|
64
|
+
" async down({ schema }: MigrationContext) {",
|
|
65
|
+
` await schema.dropTable(${tableNameLiteral})`,
|
|
66
|
+
" },",
|
|
67
|
+
"})",
|
|
68
|
+
""
|
|
69
|
+
].join("\n");
|
|
70
|
+
}
|
|
71
|
+
async function hasMigrationFile(migrationsDir, migrationName) {
|
|
72
|
+
const entries = await readdir(migrationsDir).catch(() => []);
|
|
73
|
+
return entries.some((entry) => entry.endsWith(`_${migrationName}.ts`) || entry.endsWith(`_${migrationName}.mts`) || entry.endsWith(`_${migrationName}.js`) || entry.endsWith(`_${migrationName}.mjs`) || entry.endsWith(`_${migrationName}.cts`) || entry.endsWith(`_${migrationName}.cjs`));
|
|
74
|
+
}
|
|
75
|
+
async function createMediaTableMigration(projectRoot, options = {}) {
|
|
76
|
+
const project = await ensureProjectConfig(projectRoot);
|
|
77
|
+
const registry = await loadGeneratedProjectRegistry(projectRoot) ?? await prepareProjectDiscovery(projectRoot, project.config);
|
|
78
|
+
const tableName = DEFAULT_MEDIA_TABLE;
|
|
79
|
+
const migrationName = normalizeMediaMigrationName(tableName);
|
|
80
|
+
const migrationsDir = resolve(projectRoot, project.config.paths.migrations);
|
|
81
|
+
if (hasRegisteredMigrationSlug(registry, migrationName) || hasRegisteredCreateTableMigration(registry, tableName) || await hasMigrationFile(migrationsDir, migrationName)) {
|
|
82
|
+
if (options.skipIfExists === true) {
|
|
83
|
+
return void 0;
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`A migration for table "${tableName}" already exists.`);
|
|
86
|
+
}
|
|
87
|
+
const migrationTemplate = await nextMigrationTemplate(
|
|
88
|
+
migrationName,
|
|
89
|
+
migrationsDir
|
|
90
|
+
);
|
|
91
|
+
const migrationFilePath = resolveDefaultArtifactPath(projectRoot, project.config.paths.migrations, migrationTemplate.fileName);
|
|
92
|
+
await writeTextFile(migrationFilePath, renderMediaTableMigration(tableName));
|
|
93
|
+
return migrationFilePath;
|
|
94
|
+
}
|
|
95
|
+
async function runMediaTableCommand(io, projectRoot) {
|
|
96
|
+
const migrationFilePath = await createMediaTableMigration(projectRoot);
|
|
97
|
+
const { runProjectPrepare } = await import("./dev-OSLYSBTL.mjs");
|
|
98
|
+
if (!migrationFilePath) {
|
|
99
|
+
throw new Error(`A migration for table "${DEFAULT_MEDIA_TABLE}" already exists.`);
|
|
100
|
+
}
|
|
101
|
+
await runProjectPrepare(projectRoot);
|
|
102
|
+
writeLine(io.stdout, `Created migration: ${makeProjectRelativePath(projectRoot, migrationFilePath)}`);
|
|
103
|
+
}
|
|
104
|
+
var mediaMigrationInternals = {
|
|
105
|
+
getRegistryMigrationSlug,
|
|
106
|
+
hasRegisteredMigrationSlug,
|
|
107
|
+
hasRegisteredCreateTableMigration,
|
|
108
|
+
nextMigrationTemplate
|
|
109
|
+
};
|
|
110
|
+
export {
|
|
111
|
+
DEFAULT_MEDIA_TABLE,
|
|
112
|
+
createMediaTableMigration,
|
|
113
|
+
mediaMigrationInternals,
|
|
114
|
+
normalizeMediaMigrationName,
|
|
115
|
+
renderMediaTableMigration,
|
|
116
|
+
runMediaTableCommand
|
|
117
|
+
};
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
writeLine
|
|
3
|
-
} from "./chunk-ZXDU7RHU.mjs";
|
|
4
|
-
import {
|
|
5
|
-
initializeProjectRuntime
|
|
6
|
-
} from "./chunk-URK7C3VQ.mjs";
|
|
7
|
-
import "./chunk-EUIVXVJL.mjs";
|
|
8
1
|
import {
|
|
9
2
|
isIgnorableWatchError,
|
|
10
3
|
isRecursiveWatchUnsupported,
|
|
11
4
|
normalizeWatchedFilePath,
|
|
12
5
|
runProjectPrepare,
|
|
13
6
|
toPosixSlashes
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-SCCPDJGO.mjs";
|
|
8
|
+
import "./chunk-F4MT6GBK.mjs";
|
|
9
|
+
import {
|
|
10
|
+
writeLine
|
|
11
|
+
} from "./chunk-ZXDU7RHU.mjs";
|
|
12
|
+
import {
|
|
13
|
+
initializeProjectRuntime
|
|
14
|
+
} from "./chunk-OZUDZEAW.mjs";
|
|
15
|
+
import "./chunk-57SJ566R.mjs";
|
|
16
16
|
import "./chunk-D7O4SU6N.mjs";
|
|
17
17
|
import {
|
|
18
18
|
prepareProjectDiscovery
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-UZTDQKIY.mjs";
|
|
20
|
+
import "./chunk-VCEO6N5T.mjs";
|
|
21
21
|
import {
|
|
22
22
|
ensureProjectConfig,
|
|
23
23
|
loadProjectConfig
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-5BLEC66P.mjs";
|
|
25
25
|
import {
|
|
26
26
|
loadGeneratedProjectRegistry
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-MXKNQACM.mjs";
|
|
28
28
|
import {
|
|
29
29
|
HOLO_RUNTIME_ROOT,
|
|
30
30
|
bundleProjectModule,
|
|
31
31
|
resolveProjectPackageImportSpecifier
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-R6BWRY3E.mjs";
|
|
33
33
|
|
|
34
34
|
// src/queue.ts
|
|
35
35
|
import { spawn } from "child_process";
|