@holo-js/cli 0.1.9 → 0.2.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/bin/holo.mjs +165 -81
- package/dist/broadcast-WI6PJS5P.mjs +203 -0
- package/dist/broadcast-YWS4N5QU.mjs +203 -0
- package/dist/{cache-ETOIQ5IG.mjs → cache-KWNQECAA.mjs} +6 -6
- package/dist/cache-QARFSW4F.mjs +66 -0
- package/dist/{cache-migrations-2GGI4TJK.mjs → cache-migrations-3OXR4FN5.mjs} +50 -30
- package/dist/cache-migrations-MDFMDVTK.mjs +173 -0
- package/dist/{chunk-IMOGEKB4.mjs → chunk-2DKQKZML.mjs} +188 -106
- package/dist/{chunk-7JR73TOH.mjs → chunk-2RGJTPYF.mjs} +36 -25
- package/dist/{chunk-ASTSSSL2.mjs → chunk-EWYXSN2C.mjs} +75 -122
- package/dist/{chunk-F4MT6GBK.mjs → chunk-FGQ2I2YH.mjs} +1 -1
- package/dist/chunk-I7QBCEV7.mjs +33 -0
- package/dist/{chunk-R6BWRY3E.mjs → chunk-ILU426CF.mjs} +3 -1
- package/dist/{chunk-HB4Q7VYK.mjs → chunk-IUDD5FYL.mjs} +28 -273
- package/dist/{chunk-WRZFATUT.mjs → chunk-KWRIBHC3.mjs} +229 -142
- package/dist/{chunk-57SJ566R.mjs → chunk-LBJAJLKU.mjs} +1 -1
- package/dist/{chunk-BAFQ2GOA.mjs → chunk-LXGQCG56.mjs} +1 -1
- package/dist/{chunk-SRPGIWCF.mjs → chunk-ONKESAQA.mjs} +2 -2
- package/dist/chunk-QA7TP5EO.mjs +448 -0
- package/dist/chunk-UPZH6KCF.mjs +3306 -0
- package/dist/{chunk-5EU32E7X.mjs → chunk-VRGB6DIS.mjs} +116 -12
- package/dist/{config-ARLE6PKR.mjs → config-TWEO2R4N.mjs} +3 -3
- package/dist/{dev-6RG5SSZ7.mjs → dev-2OULECTU.mjs} +7 -7
- package/dist/dev-PJMEGTAC.mjs +42 -0
- package/dist/{discovery-FCVGQQVD.mjs → discovery-7FXND7Y6.mjs} +3 -3
- package/dist/{generators-UI2LJK3O.mjs → generators-4BP7B47W.mjs} +11 -34
- package/dist/generators-Z4XLSMC7.mjs +520 -0
- package/dist/index.mjs +167 -83
- package/dist/{media-migrations-JQSDCC7S.mjs → media-migrations-BFEL7NFG.mjs} +9 -20
- package/dist/media-migrations-VR7DLLR6.mjs +106 -0
- package/dist/{queue-BY3PLH4I.mjs → queue-SVOJPTRO.mjs} +10 -10
- package/dist/queue-YCBQTCYI.mjs +625 -0
- package/dist/{queue-migrations-YZUKEZK7.mjs → queue-migrations-HPXOO3NA.mjs} +13 -12
- package/dist/queue-migrations-X4P7FZKJ.mjs +167 -0
- package/dist/{runtime-BI343WHS.mjs → runtime-CPKR663Y.mjs} +9 -9
- package/dist/runtime-GIE56H47.mjs +57 -0
- package/dist/{runtime-ZKD6URAV.mjs → runtime-GSXF4NB3.mjs} +1 -1
- package/dist/runtime-worker.d.ts +2 -0
- package/dist/runtime-worker.mjs +242 -0
- package/dist/{scaffold-UBOS2NZR.mjs → scaffold-3QPGYQEQ.mjs} +9 -5
- package/dist/scaffold-RGAAHC6I.mjs +139 -0
- package/dist/{security-TYPVOYGF.mjs → security-7H5TNHZY.mjs} +6 -6
- package/dist/security-BZGD6ONY.mjs +71 -0
- package/package.json +9 -7
- package/dist/broadcast-VR46UZEL.mjs +0 -84
- package/dist/chunk-ZXDU7RHU.mjs +0 -9
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import {
|
|
2
|
+
authFeaturesRequireConfigUpdate,
|
|
3
|
+
detectAuthInstallFeaturesFromConfig,
|
|
4
|
+
hasLoadedConfigFile,
|
|
5
|
+
inferConnectionDriver,
|
|
6
|
+
inferDatabaseDriverFromUrl,
|
|
7
|
+
injectBroadcastAuthEndpoint,
|
|
8
|
+
installAuthIntoProject,
|
|
9
|
+
installAuthorizationIntoProject,
|
|
10
|
+
installBroadcastIntoProject,
|
|
11
|
+
installCacheIntoProject,
|
|
12
|
+
installEventsIntoProject,
|
|
13
|
+
installMailIntoProject,
|
|
14
|
+
installMediaIntoProject,
|
|
15
|
+
installNotificationsIntoProject,
|
|
16
|
+
installQueueIntoProject,
|
|
17
|
+
installRealtimeIntoProject,
|
|
18
|
+
installSecurityIntoProject,
|
|
19
|
+
normalizeScaffoldEnvSegments,
|
|
20
|
+
publishAuthNotificationsIntoProject,
|
|
21
|
+
renderAuthConfig,
|
|
22
|
+
renderAuthEnvFiles,
|
|
23
|
+
renderAuthMigration,
|
|
24
|
+
renderAuthUserModel,
|
|
25
|
+
renderCacheConfig,
|
|
26
|
+
renderCacheEnvFiles,
|
|
27
|
+
renderCorsConfig,
|
|
28
|
+
renderEnvFileContents,
|
|
29
|
+
renderMailConfig,
|
|
30
|
+
renderMailEnvFiles,
|
|
31
|
+
renderMediaConfig,
|
|
32
|
+
renderNotificationsConfig,
|
|
33
|
+
renderNotificationsMigration,
|
|
34
|
+
renderQueueConfig,
|
|
35
|
+
renderQueueEnvFiles,
|
|
36
|
+
renderRedisConfig,
|
|
37
|
+
renderScaffoldAppConfig,
|
|
38
|
+
renderScaffoldDatabaseConfig,
|
|
39
|
+
renderScaffoldEnvFiles,
|
|
40
|
+
renderScaffoldGitignore,
|
|
41
|
+
renderScaffoldPackageJson,
|
|
42
|
+
renderScaffoldTsconfig,
|
|
43
|
+
renderSecurityConfig,
|
|
44
|
+
renderSessionConfig,
|
|
45
|
+
renderStorageConfig,
|
|
46
|
+
renderVSCodeSettings,
|
|
47
|
+
resolveBroadcastConfigTargetPath,
|
|
48
|
+
resolveDefaultDatabaseUrl,
|
|
49
|
+
resolvePackageManagerVersion,
|
|
50
|
+
scaffoldProject,
|
|
51
|
+
syncManagedDriverDependencies,
|
|
52
|
+
upsertAuthPackageDependencies,
|
|
53
|
+
upsertCachePackageDependencies,
|
|
54
|
+
upsertEventsPackageDependency,
|
|
55
|
+
upsertMailPackageDependency,
|
|
56
|
+
upsertMediaPackageDependency,
|
|
57
|
+
upsertNotificationsPackageDependency,
|
|
58
|
+
upsertSecurityPackageDependency
|
|
59
|
+
} from "./chunk-KWRIBHC3.mjs";
|
|
60
|
+
import "./chunk-ONKESAQA.mjs";
|
|
61
|
+
import {
|
|
62
|
+
renderAuthProviderRouteFiles,
|
|
63
|
+
renderFrameworkFiles,
|
|
64
|
+
renderFrameworkRunner,
|
|
65
|
+
renderNextBroadcastConfigRoute
|
|
66
|
+
} from "./chunk-2DKQKZML.mjs";
|
|
67
|
+
import {
|
|
68
|
+
isSupportedCacheInstallerDriver,
|
|
69
|
+
isSupportedQueueInstallerDriver,
|
|
70
|
+
normalizeScaffoldOptionalPackages,
|
|
71
|
+
sanitizePackageName
|
|
72
|
+
} from "./chunk-ILU426CF.mjs";
|
|
73
|
+
export {
|
|
74
|
+
authFeaturesRequireConfigUpdate,
|
|
75
|
+
detectAuthInstallFeaturesFromConfig,
|
|
76
|
+
hasLoadedConfigFile,
|
|
77
|
+
inferConnectionDriver,
|
|
78
|
+
inferDatabaseDriverFromUrl,
|
|
79
|
+
injectBroadcastAuthEndpoint,
|
|
80
|
+
installAuthIntoProject,
|
|
81
|
+
installAuthorizationIntoProject,
|
|
82
|
+
installBroadcastIntoProject,
|
|
83
|
+
installCacheIntoProject,
|
|
84
|
+
installEventsIntoProject,
|
|
85
|
+
installMailIntoProject,
|
|
86
|
+
installMediaIntoProject,
|
|
87
|
+
installNotificationsIntoProject,
|
|
88
|
+
installQueueIntoProject,
|
|
89
|
+
installRealtimeIntoProject,
|
|
90
|
+
installSecurityIntoProject,
|
|
91
|
+
isSupportedCacheInstallerDriver,
|
|
92
|
+
isSupportedQueueInstallerDriver,
|
|
93
|
+
normalizeScaffoldEnvSegments,
|
|
94
|
+
normalizeScaffoldOptionalPackages,
|
|
95
|
+
publishAuthNotificationsIntoProject,
|
|
96
|
+
renderAuthConfig,
|
|
97
|
+
renderAuthEnvFiles,
|
|
98
|
+
renderAuthMigration,
|
|
99
|
+
renderAuthProviderRouteFiles,
|
|
100
|
+
renderAuthUserModel,
|
|
101
|
+
renderCacheConfig,
|
|
102
|
+
renderCacheEnvFiles,
|
|
103
|
+
renderCorsConfig,
|
|
104
|
+
renderEnvFileContents,
|
|
105
|
+
renderFrameworkFiles,
|
|
106
|
+
renderFrameworkRunner,
|
|
107
|
+
renderMailConfig,
|
|
108
|
+
renderMailEnvFiles,
|
|
109
|
+
renderMediaConfig,
|
|
110
|
+
renderNextBroadcastConfigRoute,
|
|
111
|
+
renderNotificationsConfig,
|
|
112
|
+
renderNotificationsMigration,
|
|
113
|
+
renderQueueConfig,
|
|
114
|
+
renderQueueEnvFiles,
|
|
115
|
+
renderRedisConfig,
|
|
116
|
+
renderScaffoldAppConfig,
|
|
117
|
+
renderScaffoldDatabaseConfig,
|
|
118
|
+
renderScaffoldEnvFiles,
|
|
119
|
+
renderScaffoldGitignore,
|
|
120
|
+
renderScaffoldPackageJson,
|
|
121
|
+
renderScaffoldTsconfig,
|
|
122
|
+
renderSecurityConfig,
|
|
123
|
+
renderSessionConfig,
|
|
124
|
+
renderStorageConfig,
|
|
125
|
+
renderVSCodeSettings,
|
|
126
|
+
resolveBroadcastConfigTargetPath,
|
|
127
|
+
resolveDefaultDatabaseUrl,
|
|
128
|
+
resolvePackageManagerVersion,
|
|
129
|
+
sanitizePackageName,
|
|
130
|
+
scaffoldProject,
|
|
131
|
+
syncManagedDriverDependencies,
|
|
132
|
+
upsertAuthPackageDependencies,
|
|
133
|
+
upsertCachePackageDependencies,
|
|
134
|
+
upsertEventsPackageDependency,
|
|
135
|
+
upsertMailPackageDependency,
|
|
136
|
+
upsertMediaPackageDependency,
|
|
137
|
+
upsertNotificationsPackageDependency,
|
|
138
|
+
upsertSecurityPackageDependency
|
|
139
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
writeLine
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-I7QBCEV7.mjs";
|
|
4
4
|
import "./chunk-D7O4SU6N.mjs";
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-2RGJTPYF.mjs";
|
|
6
|
+
import "./chunk-UPZH6KCF.mjs";
|
|
7
|
+
import "./chunk-ONKESAQA.mjs";
|
|
8
|
+
import "./chunk-2DKQKZML.mjs";
|
|
9
9
|
import {
|
|
10
10
|
resolveProjectPackageImportSpecifier
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ILU426CF.mjs";
|
|
12
12
|
|
|
13
13
|
// src/security.ts
|
|
14
14
|
import { loadConfigDirectory } from "@holo-js/config";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
writeLine
|
|
3
|
+
} from "./chunk-I7QBCEV7.mjs";
|
|
4
|
+
import "./chunk-D7O4SU6N.mjs";
|
|
5
|
+
import "./chunk-2RGJTPYF.mjs";
|
|
6
|
+
import "./chunk-KWRIBHC3.mjs";
|
|
7
|
+
import "./chunk-ONKESAQA.mjs";
|
|
8
|
+
import "./chunk-2DKQKZML.mjs";
|
|
9
|
+
import {
|
|
10
|
+
resolveProjectPackageImportSpecifier
|
|
11
|
+
} from "./chunk-ILU426CF.mjs";
|
|
12
|
+
|
|
13
|
+
// src/security.ts
|
|
14
|
+
import { loadConfigDirectory } from "@holo-js/config";
|
|
15
|
+
async function loadSecurityCliModule(projectRoot) {
|
|
16
|
+
const specifier = resolveProjectPackageImportSpecifier(projectRoot, "@holo-js/security");
|
|
17
|
+
try {
|
|
18
|
+
return await import(specifier);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
21
|
+
throw new Error(
|
|
22
|
+
`Unable to load @holo-js/security from ${projectRoot}. Install it with "holo install security". ${details}`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function runRateLimitClearCommand(io, projectRoot, options, dependencies = {}) {
|
|
27
|
+
const loadSecurityModule = dependencies.loadSecurityModule ?? loadSecurityCliModule;
|
|
28
|
+
const loadConfig = dependencies.loadConfig ?? (async (root) => {
|
|
29
|
+
const loaded = await loadConfigDirectory(root, {
|
|
30
|
+
preferCache: false,
|
|
31
|
+
processEnv: process.env
|
|
32
|
+
});
|
|
33
|
+
return { security: loaded.security };
|
|
34
|
+
});
|
|
35
|
+
const loadRedisAdapter = dependencies.loadRedisAdapter ?? (async (root) => {
|
|
36
|
+
return await import(resolveProjectPackageImportSpecifier(root, "@holo-js/security/drivers/redis-adapter"));
|
|
37
|
+
});
|
|
38
|
+
const { security: securityConfig } = await loadConfig(projectRoot);
|
|
39
|
+
const securityModule = await loadSecurityModule(projectRoot);
|
|
40
|
+
const driver = securityConfig.rateLimit.driver;
|
|
41
|
+
if (driver === "memory") {
|
|
42
|
+
throw new Error("[security] The memory rate-limit driver is process-local and cannot be cleared meaningfully from the CLI.");
|
|
43
|
+
}
|
|
44
|
+
let redisAdapter;
|
|
45
|
+
if (driver === "redis") {
|
|
46
|
+
const { createSecurityRedisAdapter } = await loadRedisAdapter(projectRoot);
|
|
47
|
+
redisAdapter = createSecurityRedisAdapter(securityConfig.rateLimit.redis);
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
await redisAdapter?.connect();
|
|
51
|
+
const rateLimitStoreOptions = redisAdapter ? { projectRoot, redisAdapter } : { projectRoot };
|
|
52
|
+
const rateLimitStore = securityModule.createRateLimitStoreFromConfig(securityConfig, rateLimitStoreOptions);
|
|
53
|
+
securityModule.configureSecurityRuntime({
|
|
54
|
+
config: securityConfig,
|
|
55
|
+
rateLimitStore
|
|
56
|
+
});
|
|
57
|
+
const cleared = await securityModule.clearRateLimit(options);
|
|
58
|
+
const count = typeof cleared === "boolean" ? cleared ? 1 : 0 : cleared;
|
|
59
|
+
writeLine(io.stdout, `[security] Cleared ${count} rate-limit bucket(s).`);
|
|
60
|
+
} finally {
|
|
61
|
+
try {
|
|
62
|
+
await redisAdapter?.close();
|
|
63
|
+
} finally {
|
|
64
|
+
securityModule.resetSecurityRuntime();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
loadSecurityCliModule,
|
|
70
|
+
runRateLimitClearCommand
|
|
71
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holo-js/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Holo-JS Framework - project creation, discovery, and operational CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,16 +27,18 @@
|
|
|
27
27
|
"test:integration": "HOLO_CLI_INCLUDE_INTEGRATION=1 vitest --run tests/cli.test.ts"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@
|
|
31
|
-
"@holo-js/
|
|
32
|
-
"@holo-js/
|
|
30
|
+
"@clack/prompts": "^1.5.1",
|
|
31
|
+
"@holo-js/cache-db": "^0.2.0",
|
|
32
|
+
"@holo-js/config": "^0.2.0",
|
|
33
|
+
"@holo-js/core": "^0.2.0",
|
|
34
|
+
"@holo-js/db": "^0.2.0",
|
|
33
35
|
"esbuild": "^0.27.4",
|
|
34
36
|
"inflection": "^3.0.2"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"@holo-js/events": "^0.
|
|
38
|
-
"@holo-js/queue": "^0.
|
|
39
|
-
"@holo-js/queue-db": "^0.
|
|
39
|
+
"@holo-js/events": "^0.2.0",
|
|
40
|
+
"@holo-js/queue": "^0.2.0",
|
|
41
|
+
"@holo-js/queue-db": "^0.2.0",
|
|
40
42
|
"@types/node": "^22.10.2",
|
|
41
43
|
"tsup": "^8.3.5",
|
|
42
44
|
"typescript": "^5.7.2",
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
writeLine
|
|
3
|
-
} from "./chunk-ZXDU7RHU.mjs";
|
|
4
|
-
import "./chunk-D7O4SU6N.mjs";
|
|
5
|
-
import {
|
|
6
|
-
prepareProjectDiscovery
|
|
7
|
-
} from "./chunk-7JR73TOH.mjs";
|
|
8
|
-
import "./chunk-WRZFATUT.mjs";
|
|
9
|
-
import {
|
|
10
|
-
loadProjectConfig
|
|
11
|
-
} from "./chunk-SRPGIWCF.mjs";
|
|
12
|
-
import {
|
|
13
|
-
loadGeneratedProjectRegistry
|
|
14
|
-
} from "./chunk-IMOGEKB4.mjs";
|
|
15
|
-
import {
|
|
16
|
-
importProjectModule,
|
|
17
|
-
resolveProjectPackageImportSpecifier
|
|
18
|
-
} from "./chunk-R6BWRY3E.mjs";
|
|
19
|
-
|
|
20
|
-
// src/broadcast.ts
|
|
21
|
-
import { basename, extname } from "path";
|
|
22
|
-
import { loadConfigDirectory } from "@holo-js/config";
|
|
23
|
-
function hasLoadedRedisConfigSection(loadedFiles) {
|
|
24
|
-
return Array.isArray(loadedFiles) && loadedFiles.some((filePath) => {
|
|
25
|
-
return basename(filePath, extname(filePath)) === "redis";
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
async function loadBroadcastCliModule(projectRoot) {
|
|
29
|
-
try {
|
|
30
|
-
return await import(resolveProjectPackageImportSpecifier(projectRoot, "@holo-js/broadcast"));
|
|
31
|
-
} catch (error) {
|
|
32
|
-
const details = error instanceof Error ? error.message : String(error);
|
|
33
|
-
throw new Error(
|
|
34
|
-
`Unable to load @holo-js/broadcast from ${projectRoot}. Install it with "holo install broadcast". ${details}`
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async function runBroadcastWorkCommand(io, projectRoot, dependencies = {}) {
|
|
39
|
-
const loadConfig = dependencies.loadConfig ?? loadConfigDirectory;
|
|
40
|
-
const loadModule = dependencies.loadModule ?? loadBroadcastCliModule;
|
|
41
|
-
const config = await loadConfig(projectRoot);
|
|
42
|
-
const project = await loadProjectConfig(projectRoot);
|
|
43
|
-
const loadRegistry = dependencies.loadRegistry ?? loadGeneratedProjectRegistry;
|
|
44
|
-
await loadRegistry(projectRoot).catch(() => void 0);
|
|
45
|
-
const registry = await prepareProjectDiscovery(projectRoot, project.config);
|
|
46
|
-
const broadcastModule = await loadModule(projectRoot);
|
|
47
|
-
const worker = await broadcastModule.startBroadcastWorker({
|
|
48
|
-
config: config.broadcast,
|
|
49
|
-
queue: config.queue,
|
|
50
|
-
...hasLoadedRedisConfigSection(config.loadedFiles) ? { redis: config.redis } : {},
|
|
51
|
-
...registry ? {
|
|
52
|
-
channelAuth: {
|
|
53
|
-
registry: {
|
|
54
|
-
projectRoot,
|
|
55
|
-
channels: registry.channels
|
|
56
|
-
},
|
|
57
|
-
importModule: async (absolutePath) => await importProjectModule(projectRoot, absolutePath)
|
|
58
|
-
}
|
|
59
|
-
} : {}
|
|
60
|
-
});
|
|
61
|
-
writeLine(io.stdout, `[broadcast] Worker listening on ${worker.host}:${worker.port}`);
|
|
62
|
-
await new Promise((resolvePromise) => {
|
|
63
|
-
let stopped = false;
|
|
64
|
-
const stop = async () => {
|
|
65
|
-
if (stopped) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
stopped = true;
|
|
69
|
-
process.off("SIGINT", onSignal);
|
|
70
|
-
process.off("SIGTERM", onSignal);
|
|
71
|
-
await worker.stop();
|
|
72
|
-
resolvePromise();
|
|
73
|
-
};
|
|
74
|
-
const onSignal = () => {
|
|
75
|
-
void stop();
|
|
76
|
-
};
|
|
77
|
-
process.on("SIGINT", onSignal);
|
|
78
|
-
process.on("SIGTERM", onSignal);
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
export {
|
|
82
|
-
loadBroadcastCliModule,
|
|
83
|
-
runBroadcastWorkCommand
|
|
84
|
-
};
|