@c15t/cli 1.5.0 → 1.6.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/README.md +97 -74
- package/dist/commands/generate/index.d.ts +6 -0
- package/dist/commands/generate/index.d.ts.map +1 -0
- package/dist/{onboarding/storage-modes → commands/generate/options}/c15t-mode.d.ts +5 -10
- package/dist/commands/generate/options/c15t-mode.d.ts.map +1 -0
- package/dist/{onboarding/storage-modes → commands/generate/options}/custom-mode.d.ts +5 -7
- package/dist/commands/generate/options/custom-mode.d.ts.map +1 -0
- package/dist/{onboarding/storage-modes → commands/generate/options}/offline-mode.d.ts +5 -7
- package/dist/commands/generate/options/offline-mode.d.ts.map +1 -0
- package/dist/commands/generate/options/self-hosted-mode.d.ts +19 -0
- package/dist/commands/generate/options/self-hosted-mode.d.ts.map +1 -0
- package/dist/commands/generate/options/types.d.ts +12 -0
- package/dist/commands/generate/options/types.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate/options/utils}/dependencies.d.ts +12 -0
- package/dist/commands/generate/options/utils/dependencies.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate/options/utils}/generate-files.d.ts +4 -8
- package/dist/commands/generate/options/utils/generate-files.d.ts.map +1 -0
- package/dist/commands/generate/options/utils/shared-frontend.d.ts +13 -0
- package/dist/commands/generate/options/utils/shared-frontend.d.ts.map +1 -0
- package/dist/commands/generate/templates/backend.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate}/templates/config.d.ts +1 -1
- package/dist/commands/generate/templates/config.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate}/templates/env.d.ts +1 -1
- package/dist/commands/generate/templates/env.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate}/templates/index.d.ts +1 -1
- package/dist/commands/generate/templates/index.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate}/templates/layout.d.ts +1 -1
- package/dist/commands/generate/templates/layout.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate}/templates/next/app/layout.d.ts +1 -1
- package/dist/commands/generate/templates/next/app/layout.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate}/templates/next/index.d.ts +1 -1
- package/dist/commands/generate/templates/next/index.d.ts.map +1 -0
- package/dist/{onboarding → commands/generate}/templates/next/pages/layout.d.ts +1 -1
- package/dist/commands/generate/templates/next/pages/layout.d.ts.map +1 -0
- package/dist/commands/generate/templates/next-config.d.ts.map +1 -0
- package/dist/commands/generate/templates/shared/options.d.ts.map +1 -0
- package/dist/commands/self-host/index.d.ts +6 -0
- package/dist/commands/self-host/index.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/ensure-backend-config.d.ts +7 -0
- package/dist/commands/self-host/migrate/ensure-backend-config.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/ensure-backend-config.test.d.ts +2 -0
- package/dist/commands/self-host/migrate/ensure-backend-config.test.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/index.d.ts +3 -0
- package/dist/commands/self-host/migrate/index.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/index.test.d.ts +2 -0
- package/dist/commands/self-host/migrate/index.test.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/migrator-result.d.ts +4 -0
- package/dist/commands/self-host/migrate/migrator-result.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/migrator-result.test.d.ts +2 -0
- package/dist/commands/self-host/migrate/migrator-result.test.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/orm-result.d.ts +4 -0
- package/dist/commands/self-host/migrate/orm-result.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/orm-result.test.d.ts +2 -0
- package/dist/commands/self-host/migrate/orm-result.test.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/read-config.d.ts +6 -0
- package/dist/commands/self-host/migrate/read-config.d.ts.map +1 -0
- package/dist/commands/self-host/migrate/read-config.test.d.ts +2 -0
- package/dist/commands/self-host/migrate/read-config.test.d.ts.map +1 -0
- package/dist/context/creator.d.ts.map +1 -1
- package/dist/context/framework-detection.d.ts +1 -1
- package/dist/context/framework-detection.d.ts.map +1 -1
- package/dist/context/types.d.ts +1 -0
- package/dist/context/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +760 -940
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/telemetry.d.ts +3 -0
- package/dist/utils/telemetry.d.ts.map +1 -1
- package/package.json +12 -5
- package/readme.json +70 -0
- package/dist/actions/get-config/config-extraction.d.ts +0 -37
- package/dist/actions/get-config/config-extraction.d.ts.map +0 -1
- package/dist/actions/get-config/config-validation.d.ts +0 -7
- package/dist/actions/get-config/config-validation.d.ts.map +0 -1
- package/dist/actions/get-config/constants.d.ts +0 -13
- package/dist/actions/get-config/constants.d.ts.map +0 -1
- package/dist/actions/get-config/directory-search.d.ts +0 -6
- package/dist/actions/get-config/directory-search.d.ts.map +0 -1
- package/dist/actions/get-config/jiti-options.d.ts +0 -9
- package/dist/actions/get-config/jiti-options.d.ts.map +0 -1
- package/dist/actions/get-config.d.ts +0 -13
- package/dist/actions/get-config.d.ts.map +0 -1
- package/dist/actions/load-config-and-onboard.d.ts +0 -9
- package/dist/actions/load-config-and-onboard.d.ts.map +0 -1
- package/dist/commands/generate/actions/handle-existing-file.d.ts +0 -7
- package/dist/commands/generate/actions/handle-existing-file.d.ts.map +0 -1
- package/dist/commands/generate/actions/handle-new-file.d.ts +0 -7
- package/dist/commands/generate/actions/handle-new-file.d.ts.map +0 -1
- package/dist/commands/generate/actions/perform-write-action.d.ts +0 -6
- package/dist/commands/generate/actions/perform-write-action.d.ts.map +0 -1
- package/dist/commands/generate/generators/drizzle.d.ts +0 -4
- package/dist/commands/generate/generators/drizzle.d.ts.map +0 -1
- package/dist/commands/generate/generators/index.d.ts +0 -19
- package/dist/commands/generate/generators/index.d.ts.map +0 -1
- package/dist/commands/generate/generators/kysely.d.ts +0 -11
- package/dist/commands/generate/generators/kysely.d.ts.map +0 -1
- package/dist/commands/generate/generators/prisma.d.ts +0 -3
- package/dist/commands/generate/generators/prisma.d.ts.map +0 -1
- package/dist/commands/generate/generators/types.d.ts +0 -13
- package/dist/commands/generate/generators/types.d.ts.map +0 -1
- package/dist/commands/generate/schema.d.ts +0 -10
- package/dist/commands/generate/schema.d.ts.map +0 -1
- package/dist/commands/generate/setup.d.ts +0 -13
- package/dist/commands/generate/setup.d.ts.map +0 -1
- package/dist/commands/generate/write.d.ts +0 -8
- package/dist/commands/generate/write.d.ts.map +0 -1
- package/dist/commands/generate.d.ts +0 -6
- package/dist/commands/generate.d.ts.map +0 -1
- package/dist/commands/migrate/execute.d.ts +0 -7
- package/dist/commands/migrate/execute.d.ts.map +0 -1
- package/dist/commands/migrate/plan.d.ts +0 -12
- package/dist/commands/migrate/plan.d.ts.map +0 -1
- package/dist/commands/migrate/setup.d.ts +0 -12
- package/dist/commands/migrate/setup.d.ts.map +0 -1
- package/dist/commands/migrate.d.ts +0 -3
- package/dist/commands/migrate.d.ts.map +0 -1
- package/dist/context/config-management.d.ts +0 -20
- package/dist/context/config-management.d.ts.map +0 -1
- package/dist/onboarding/dependencies.d.ts.map +0 -1
- package/dist/onboarding/generate-files.d.ts.map +0 -1
- package/dist/onboarding/index.d.ts +0 -11
- package/dist/onboarding/index.d.ts.map +0 -1
- package/dist/onboarding/storage-modes/c15t-mode.d.ts.map +0 -1
- package/dist/onboarding/storage-modes/custom-mode.d.ts.map +0 -1
- package/dist/onboarding/storage-modes/index.d.ts +0 -5
- package/dist/onboarding/storage-modes/index.d.ts.map +0 -1
- package/dist/onboarding/storage-modes/offline-mode.d.ts.map +0 -1
- package/dist/onboarding/storage-modes/self-hosted-mode.d.ts +0 -22
- package/dist/onboarding/storage-modes/self-hosted-mode.d.ts.map +0 -1
- package/dist/onboarding/templates/backend.d.ts.map +0 -1
- package/dist/onboarding/templates/config.d.ts.map +0 -1
- package/dist/onboarding/templates/env.d.ts.map +0 -1
- package/dist/onboarding/templates/index.d.ts.map +0 -1
- package/dist/onboarding/templates/layout.d.ts.map +0 -1
- package/dist/onboarding/templates/next/app/layout.d.ts.map +0 -1
- package/dist/onboarding/templates/next/index.d.ts.map +0 -1
- package/dist/onboarding/templates/next/pages/layout.d.ts.map +0 -1
- package/dist/onboarding/templates/next-config.d.ts.map +0 -1
- package/dist/onboarding/templates/shared/options.d.ts.map +0 -1
- package/dist/onboarding.d.ts +0 -15
- package/dist/onboarding.d.ts.map +0 -1
- /package/dist/{onboarding → commands/generate}/templates/backend.d.ts +0 -0
- /package/dist/{onboarding → commands/generate}/templates/next-config.d.ts +0 -0
- /package/dist/{onboarding → commands/generate}/templates/shared/options.d.ts +0 -0
package/dist/index.mjs
CHANGED
|
@@ -3,9 +3,8 @@ import * as __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__ from "@clack/pro
|
|
|
3
3
|
import "dotenv/config";
|
|
4
4
|
import * as __WEBPACK_EXTERNAL_MODULE_open__ from "open";
|
|
5
5
|
import * as __WEBPACK_EXTERNAL_MODULE_picocolors__ from "picocolors";
|
|
6
|
-
import * as __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__ from "node:fs/promises";
|
|
7
6
|
import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
|
|
8
|
-
import * as
|
|
7
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__ from "node:fs/promises";
|
|
9
8
|
import * as __WEBPACK_EXTERNAL_MODULE_node_crypto_9ba42079__ from "node:crypto";
|
|
10
9
|
import * as __WEBPACK_EXTERNAL_MODULE_node_os_74b4b876__ from "node:os";
|
|
11
10
|
import * as __WEBPACK_EXTERNAL_MODULE_posthog_node_1b07bdf4__ from "posthog-node";
|
|
@@ -13,213 +12,12 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:c
|
|
|
13
12
|
import * as __WEBPACK_EXTERNAL_MODULE_node_events_0a6aefe7__ from "node:events";
|
|
14
13
|
import * as __WEBPACK_EXTERNAL_MODULE__doubletie_logger_91c58a8f__ from "@doubletie/logger";
|
|
15
14
|
import * as __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__ from "ts-morph";
|
|
16
|
-
import * as
|
|
17
|
-
import * as
|
|
18
|
-
import * as
|
|
15
|
+
import * as __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_migrator_64e67b79__ from "@c15t/backend/v2/db/migrator";
|
|
16
|
+
import * as __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_schema_c18e255b__ from "@c15t/backend/v2/db/schema";
|
|
17
|
+
import * as __WEBPACK_EXTERNAL_MODULE_c12__ from "c12";
|
|
19
18
|
import * as __WEBPACK_EXTERNAL_MODULE_figlet__ from "figlet";
|
|
20
19
|
import * as __WEBPACK_EXTERNAL_MODULE_fs_extra_ce68a66b__ from "fs-extra";
|
|
21
20
|
import * as __WEBPACK_EXTERNAL_MODULE_package_manager_detector_detect_94d6a9ae__ from "package-manager-detector/detect";
|
|
22
|
-
function isC15TOptions(obj) {
|
|
23
|
-
return 'object' == typeof obj && null !== obj && 'appName' in obj;
|
|
24
|
-
}
|
|
25
|
-
function isClientOptions(obj) {
|
|
26
|
-
return 'object' == typeof obj && null !== obj && ('mode' in obj || 'backendURL' in obj);
|
|
27
|
-
}
|
|
28
|
-
function tryGetFunctionResult(fn) {
|
|
29
|
-
if ('function' == typeof fn) try {
|
|
30
|
-
return fn();
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.warn('Error executing config function:', error);
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
function extractOptionsFromConfig(config) {
|
|
37
|
-
if (config.c15tConfig && isClientOptions(config.c15tConfig)) return config.c15tConfig;
|
|
38
|
-
if (config.c15tOptions && isClientOptions(config.c15tOptions)) return config.c15tOptions;
|
|
39
|
-
if (isClientOptions(config)) return config;
|
|
40
|
-
if (isC15TOptions(config.c15t)) return config.c15t;
|
|
41
|
-
if ('function' == typeof config.c15t) {
|
|
42
|
-
const result = tryGetFunctionResult(config.c15t);
|
|
43
|
-
if (isC15TOptions(result)) return result;
|
|
44
|
-
}
|
|
45
|
-
if (isC15TOptions(config.default)) return config.default;
|
|
46
|
-
if ('function' == typeof config.default) {
|
|
47
|
-
const result = tryGetFunctionResult(config.default);
|
|
48
|
-
if (isC15TOptions(result)) return result;
|
|
49
|
-
}
|
|
50
|
-
if (isC15TOptions(config.c15tInstance)) return config.c15tInstance;
|
|
51
|
-
if ('function' == typeof config.c15tInstance) {
|
|
52
|
-
const result = tryGetFunctionResult(config.c15tInstance);
|
|
53
|
-
if (isC15TOptions(result)) return result;
|
|
54
|
-
}
|
|
55
|
-
if (isC15TOptions(config.consent)) return config.consent;
|
|
56
|
-
if ('function' == typeof config.consent) {
|
|
57
|
-
const result = tryGetFunctionResult(config.consent);
|
|
58
|
-
if (isC15TOptions(result)) return result;
|
|
59
|
-
}
|
|
60
|
-
if ('object' == typeof config.c15t && null !== config.c15t && isC15TOptions(config.c15t.options)) return config.c15t.options;
|
|
61
|
-
if ('object' == typeof config.default && null !== config.default && isC15TOptions(config.default.options)) return config.default.options;
|
|
62
|
-
if ('object' == typeof config.c15tInstance && null !== config.c15tInstance && isC15TOptions(config.c15tInstance.options)) return config.c15tInstance.options;
|
|
63
|
-
if ('object' == typeof config.instance && null !== config.instance && isC15TOptions(config.instance.options)) return config.instance.options;
|
|
64
|
-
if ('object' == typeof config.consent && null !== config.consent && isC15TOptions(config.consent.options)) return config.consent.options;
|
|
65
|
-
if ('object' == typeof config.config && null !== config.config && isC15TOptions(config.config.options)) return config.config.options;
|
|
66
|
-
console.debug('No valid configuration found in any of the expected locations');
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
const configFileNames = [
|
|
70
|
-
'c15t.config',
|
|
71
|
-
'c15t.backend',
|
|
72
|
-
'c15t',
|
|
73
|
-
'c15t.client',
|
|
74
|
-
'consent.config',
|
|
75
|
-
'consent.backend',
|
|
76
|
-
'consent',
|
|
77
|
-
'cmp.config',
|
|
78
|
-
'cmp.backend',
|
|
79
|
-
'cmp'
|
|
80
|
-
];
|
|
81
|
-
const constants_extensions = [
|
|
82
|
-
'.js',
|
|
83
|
-
'.jsx',
|
|
84
|
-
'.ts',
|
|
85
|
-
'.tsx',
|
|
86
|
-
'.cjs',
|
|
87
|
-
'.cts',
|
|
88
|
-
'.mjs',
|
|
89
|
-
'.mts',
|
|
90
|
-
'.server.cjs',
|
|
91
|
-
'.server.cts',
|
|
92
|
-
'.server.js',
|
|
93
|
-
'.server.jsx',
|
|
94
|
-
'.server.mjs',
|
|
95
|
-
'.server.mts',
|
|
96
|
-
'.server.ts',
|
|
97
|
-
'.server.tsx'
|
|
98
|
-
];
|
|
99
|
-
let possiblePaths = configFileNames.flatMap((name)=>constants_extensions.map((ext)=>`${name}${ext}`));
|
|
100
|
-
const directories = [
|
|
101
|
-
'',
|
|
102
|
-
'lib/server/',
|
|
103
|
-
'server/',
|
|
104
|
-
'lib/',
|
|
105
|
-
'utils/',
|
|
106
|
-
'config/',
|
|
107
|
-
'src/',
|
|
108
|
-
'app/'
|
|
109
|
-
];
|
|
110
|
-
possiblePaths = directories.flatMap((dir)=>possiblePaths.map((file)=>`${dir}${file}`));
|
|
111
|
-
const jitiOptions = (context, cwd)=>{
|
|
112
|
-
const alias = context.config.getPathAliases(cwd) || {};
|
|
113
|
-
return {
|
|
114
|
-
extensions: [
|
|
115
|
-
'.ts',
|
|
116
|
-
'.tsx',
|
|
117
|
-
'.js',
|
|
118
|
-
'.jsx',
|
|
119
|
-
'.mjs',
|
|
120
|
-
'.cjs',
|
|
121
|
-
'.mts',
|
|
122
|
-
'.cts'
|
|
123
|
-
],
|
|
124
|
-
alias
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
async function getConfig(contextOrOptions) {
|
|
128
|
-
const context = 'logger' in contextOrOptions ? contextOrOptions : {
|
|
129
|
-
...contextOrOptions,
|
|
130
|
-
logger: {
|
|
131
|
-
debug: console.debug,
|
|
132
|
-
info: console.info,
|
|
133
|
-
warn: console.warn,
|
|
134
|
-
error: console.error
|
|
135
|
-
},
|
|
136
|
-
flags: {
|
|
137
|
-
config: contextOrOptions.configPath
|
|
138
|
-
},
|
|
139
|
-
error: {
|
|
140
|
-
handleError: (error)=>{
|
|
141
|
-
console.error('Error loading configuration:', error);
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
const { cwd, logger, flags } = context;
|
|
147
|
-
const configPath = flags.config;
|
|
148
|
-
let foundConfigPath = null;
|
|
149
|
-
try {
|
|
150
|
-
let options = null;
|
|
151
|
-
const customJitiOptions = jitiOptions(context, cwd);
|
|
152
|
-
if (configPath) {
|
|
153
|
-
foundConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].resolve(cwd, configPath);
|
|
154
|
-
logger.debug(`Using explicitly provided config path: ${foundConfigPath}`);
|
|
155
|
-
} else {
|
|
156
|
-
const prioritizedDirs = [
|
|
157
|
-
cwd,
|
|
158
|
-
__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cwd, 'packages/cli')
|
|
159
|
-
];
|
|
160
|
-
const primaryName = 'c15t.config';
|
|
161
|
-
const extensions = [
|
|
162
|
-
'.ts',
|
|
163
|
-
'.js',
|
|
164
|
-
'.mjs'
|
|
165
|
-
];
|
|
166
|
-
for (const dir of prioritizedDirs){
|
|
167
|
-
for (const ext of extensions){
|
|
168
|
-
const checkPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(dir, `${primaryName}${ext}`);
|
|
169
|
-
try {
|
|
170
|
-
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].access(checkPath);
|
|
171
|
-
foundConfigPath = checkPath;
|
|
172
|
-
logger.debug(`Found config via manual check: ${foundConfigPath}`);
|
|
173
|
-
break;
|
|
174
|
-
} catch {}
|
|
175
|
-
}
|
|
176
|
-
if (foundConfigPath) break;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
if (foundConfigPath) try {
|
|
180
|
-
logger.debug(`Loading configuration from resolved path: ${foundConfigPath}`);
|
|
181
|
-
const result = await (0, __WEBPACK_EXTERNAL_MODULE_c12__.loadConfig)({
|
|
182
|
-
configFile: foundConfigPath,
|
|
183
|
-
jitiOptions: customJitiOptions
|
|
184
|
-
});
|
|
185
|
-
logger.debug('Raw config loading result:', result);
|
|
186
|
-
if (result.config) {
|
|
187
|
-
logger.debug('Trying to extract config from result.config');
|
|
188
|
-
options = extractOptionsFromConfig(result.config);
|
|
189
|
-
}
|
|
190
|
-
if (options) {
|
|
191
|
-
logger.debug('Extracted config:', options);
|
|
192
|
-
if (isC15TOptions(options) || isClientOptions(options)) {
|
|
193
|
-
logger.debug('Configuration validated successfully.');
|
|
194
|
-
return options;
|
|
195
|
-
}
|
|
196
|
-
logger.debug('Loaded config does not match expected schema');
|
|
197
|
-
} else logger.debug('No configuration extracted from loaded file');
|
|
198
|
-
logger.debug('Raw loaded configuration:', result);
|
|
199
|
-
return null;
|
|
200
|
-
} catch (error) {
|
|
201
|
-
logger.debug('Error loading config from explicit path:', error);
|
|
202
|
-
try {
|
|
203
|
-
logger.debug(`Trying to require module directly: ${foundConfigPath}`);
|
|
204
|
-
const importedModule = await import(foundConfigPath);
|
|
205
|
-
logger.debug('Directly imported module:', importedModule);
|
|
206
|
-
const extracted = extractOptionsFromConfig(importedModule);
|
|
207
|
-
if (extracted && (isC15TOptions(extracted) || isClientOptions(extracted))) {
|
|
208
|
-
logger.debug('Found valid config through direct import');
|
|
209
|
-
return extracted;
|
|
210
|
-
}
|
|
211
|
-
} catch (importError) {
|
|
212
|
-
logger.debug('Error importing module directly:', importError);
|
|
213
|
-
}
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
return options;
|
|
217
|
-
} catch (error) {
|
|
218
|
-
if ('error' in context && context.error && 'function' == typeof context.error.handleError) return context.error.handleError(error, 'Error loading configuration');
|
|
219
|
-
console.error('Error loading configuration:', error);
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
21
|
function showHelpMenu(context, version, commands, flags) {
|
|
224
22
|
const { logger } = context;
|
|
225
23
|
logger.debug('Displaying help menu using command and flag structures.');
|
|
@@ -288,7 +86,7 @@ async function detectFramework(projectRoot, logger) {
|
|
|
288
86
|
return {
|
|
289
87
|
framework: null,
|
|
290
88
|
frameworkVersion: null,
|
|
291
|
-
pkg:
|
|
89
|
+
pkg: 'c15t',
|
|
292
90
|
hasReact: false,
|
|
293
91
|
reactVersion: null
|
|
294
92
|
};
|
|
@@ -368,7 +166,10 @@ const TelemetryEventName = {
|
|
|
368
166
|
MIGRATION_FAILED: 'migration.failed',
|
|
369
167
|
GENERATE_STARTED: 'generate.started',
|
|
370
168
|
GENERATE_COMPLETED: 'generate.completed',
|
|
371
|
-
GENERATE_FAILED: 'generate.failed'
|
|
169
|
+
GENERATE_FAILED: 'generate.failed',
|
|
170
|
+
SELF_HOST_STARTED: 'self-host.started',
|
|
171
|
+
SELF_HOST_COMPLETED: 'self-host.completed',
|
|
172
|
+
SELF_HOST_FAILED: 'self-host.failed'
|
|
372
173
|
};
|
|
373
174
|
class Telemetry {
|
|
374
175
|
client = null;
|
|
@@ -591,6 +392,58 @@ function getManualInstallCommand(dependencies, packageManager) {
|
|
|
591
392
|
return `npm install ${dependencies.join(' ')}`;
|
|
592
393
|
}
|
|
593
394
|
}
|
|
395
|
+
async function installDependencies({ context, dependenciesToAdd, handleCancel, autoInstall = false }) {
|
|
396
|
+
const { telemetry, logger } = context;
|
|
397
|
+
const s = __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner();
|
|
398
|
+
if (0 === dependenciesToAdd.length) return {
|
|
399
|
+
installDepsConfirmed: false,
|
|
400
|
+
ranInstall: false
|
|
401
|
+
};
|
|
402
|
+
const depsString = dependenciesToAdd.map((d)=>__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(d)).join(', ');
|
|
403
|
+
if (!autoInstall) {
|
|
404
|
+
const addDepsSelection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
405
|
+
message: `Add required dependencies using ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(context.packageManager.name)}? (${depsString})`,
|
|
406
|
+
initialValue: true
|
|
407
|
+
});
|
|
408
|
+
if (handleCancel?.(addDepsSelection)) return {
|
|
409
|
+
installDepsConfirmed: false,
|
|
410
|
+
ranInstall: false
|
|
411
|
+
};
|
|
412
|
+
if (!addDepsSelection) return {
|
|
413
|
+
installDepsConfirmed: false,
|
|
414
|
+
ranInstall: false
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
s.start(`Running ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(context.packageManager.name)} to add and install dependencies... (this might take a moment)`);
|
|
418
|
+
try {
|
|
419
|
+
await addAndInstallDependenciesViaPM(context.projectRoot, dependenciesToAdd, context.packageManager.name);
|
|
420
|
+
s.stop(`✅ Dependencies installed: ${dependenciesToAdd.map((d)=>__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(d)).join(', ')}`);
|
|
421
|
+
telemetry.trackEvent(TelemetryEventName.ONBOARDING_DEPENDENCIES_INSTALLED, {
|
|
422
|
+
success: true,
|
|
423
|
+
dependencies: dependenciesToAdd.join(','),
|
|
424
|
+
packageManager: context.packageManager.name
|
|
425
|
+
});
|
|
426
|
+
return {
|
|
427
|
+
installDepsConfirmed: true,
|
|
428
|
+
ranInstall: true
|
|
429
|
+
};
|
|
430
|
+
} catch (installError) {
|
|
431
|
+
s.stop(__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].yellow('⚠️ Dependency installation failed.'));
|
|
432
|
+
logger.error('Installation Error:', installError);
|
|
433
|
+
telemetry.trackEvent(TelemetryEventName.ONBOARDING_DEPENDENCIES_INSTALLED, {
|
|
434
|
+
success: false,
|
|
435
|
+
error: installError instanceof Error ? installError.message : String(installError),
|
|
436
|
+
dependencies: dependenciesToAdd.join(','),
|
|
437
|
+
packageManager: context.packageManager.name
|
|
438
|
+
});
|
|
439
|
+
const pmCommand = getManualInstallCommand(dependenciesToAdd, context.packageManager.name);
|
|
440
|
+
logger.info(`Please try running '${pmCommand}' manually in ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(context.cwd, context.projectRoot))}.`);
|
|
441
|
+
return {
|
|
442
|
+
installDepsConfirmed: true,
|
|
443
|
+
ranInstall: false
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
}
|
|
594
447
|
const validLogLevels = [
|
|
595
448
|
'error',
|
|
596
449
|
'warn',
|
|
@@ -1471,10 +1324,11 @@ async function handleEnvFiles(options) {
|
|
|
1471
1324
|
throw error;
|
|
1472
1325
|
}
|
|
1473
1326
|
}
|
|
1474
|
-
async function generateFiles({ context,
|
|
1327
|
+
async function generateFiles({ context, mode, spinner, useEnvFile, proxyNextjs, backendURL }) {
|
|
1475
1328
|
const result = {
|
|
1476
1329
|
layoutUpdated: false
|
|
1477
1330
|
};
|
|
1331
|
+
const { projectRoot, framework: { pkg } } = context;
|
|
1478
1332
|
if ('@c15t/nextjs' === pkg || '@c15t/react' === pkg) {
|
|
1479
1333
|
const layoutResult = await handleReactLayout({
|
|
1480
1334
|
projectRoot,
|
|
@@ -1514,6 +1368,39 @@ async function generateFiles({ context, projectRoot, mode, pkg, backendURL, spin
|
|
|
1514
1368
|
});
|
|
1515
1369
|
return result;
|
|
1516
1370
|
}
|
|
1371
|
+
async function getSharedFrontendOptions({ backendURL, context, handleCancel }) {
|
|
1372
|
+
let useEnvFile = false;
|
|
1373
|
+
let proxyNextjs;
|
|
1374
|
+
if (!backendURL) return {
|
|
1375
|
+
proxyNextjs: void 0,
|
|
1376
|
+
useEnvFile: void 0
|
|
1377
|
+
};
|
|
1378
|
+
const useEnvFileSelection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1379
|
+
message: 'Store the backendURL in a .env file? (Recommended, URL is public)',
|
|
1380
|
+
initialValue: true
|
|
1381
|
+
});
|
|
1382
|
+
if (handleCancel?.(useEnvFileSelection)) context.error.handleCancel('Setup cancelled.', {
|
|
1383
|
+
command: 'onboarding',
|
|
1384
|
+
stage: 'self_hosted_env_file_setup'
|
|
1385
|
+
});
|
|
1386
|
+
useEnvFile = useEnvFileSelection;
|
|
1387
|
+
if ('@c15t/nextjs' === context.framework.pkg) {
|
|
1388
|
+
context.logger.info('Learn more about Next.js Rewrites: https://nextjs.org/docs/app/api-reference/config/next-config-js/rewrites');
|
|
1389
|
+
const proxyNextjsSelection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1390
|
+
message: 'Proxy requests to your instance with Next.js Rewrites? (Recommended)',
|
|
1391
|
+
initialValue: true
|
|
1392
|
+
});
|
|
1393
|
+
if (handleCancel?.(proxyNextjsSelection)) context.error.handleCancel('Setup cancelled.', {
|
|
1394
|
+
command: 'onboarding',
|
|
1395
|
+
stage: 'self_hosted_proxy_nextjs_setup'
|
|
1396
|
+
});
|
|
1397
|
+
proxyNextjs = proxyNextjsSelection;
|
|
1398
|
+
}
|
|
1399
|
+
return {
|
|
1400
|
+
proxyNextjs,
|
|
1401
|
+
useEnvFile
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1517
1404
|
async function handleAccountCreation(context, handleCancel) {
|
|
1518
1405
|
const { logger } = context;
|
|
1519
1406
|
const needsAccount = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
@@ -1572,218 +1459,567 @@ async function getBackendURL(context, initialBackendURL, handleCancel) {
|
|
|
1572
1459
|
});
|
|
1573
1460
|
return backendURLSelection;
|
|
1574
1461
|
}
|
|
1575
|
-
async function setupC15tMode({ context,
|
|
1462
|
+
async function setupC15tMode({ context, spinner, initialBackendURL, handleCancel }) {
|
|
1576
1463
|
await handleAccountCreation(context, handleCancel);
|
|
1577
1464
|
const backendURL = await getBackendURL(context, initialBackendURL, handleCancel);
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
if (handleCancel?.(useEnvFileSelection)) context.error.handleCancel('Setup cancelled.', {
|
|
1583
|
-
command: 'onboarding',
|
|
1584
|
-
stage: 'c15t_env_file_setup'
|
|
1465
|
+
const { useEnvFile, proxyNextjs } = await getSharedFrontendOptions({
|
|
1466
|
+
backendURL: backendURL,
|
|
1467
|
+
context,
|
|
1468
|
+
handleCancel
|
|
1585
1469
|
});
|
|
1586
|
-
const useEnvFile = useEnvFileSelection;
|
|
1587
|
-
let proxyNextjs;
|
|
1588
|
-
if ('@c15t/nextjs' === packageName) {
|
|
1589
|
-
context.logger.info('Learn more about Next.js Rewrites: https://nextjs.org/docs/app/api-reference/config/next-config-js/rewrites');
|
|
1590
|
-
const proxyNextjsSelection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1591
|
-
message: 'Proxy requests to your instance with Next.js Rewrites? (Recommended)',
|
|
1592
|
-
initialValue: true
|
|
1593
|
-
});
|
|
1594
|
-
if (handleCancel?.(proxyNextjsSelection)) context.error.handleCancel('Setup cancelled.', {
|
|
1595
|
-
command: 'onboarding',
|
|
1596
|
-
stage: 'c15t_proxy_nextjs_setup'
|
|
1597
|
-
});
|
|
1598
|
-
proxyNextjs = proxyNextjsSelection;
|
|
1599
|
-
}
|
|
1600
1470
|
await generateFiles({
|
|
1601
1471
|
context,
|
|
1602
|
-
projectRoot,
|
|
1603
1472
|
mode: 'c15t',
|
|
1604
|
-
pkg: packageName,
|
|
1605
1473
|
backendURL,
|
|
1606
1474
|
spinner,
|
|
1607
1475
|
useEnvFile,
|
|
1608
1476
|
proxyNextjs
|
|
1609
1477
|
});
|
|
1478
|
+
const { ranInstall, installDepsConfirmed } = await installDependencies({
|
|
1479
|
+
context,
|
|
1480
|
+
dependenciesToAdd: [
|
|
1481
|
+
context.framework.pkg
|
|
1482
|
+
],
|
|
1483
|
+
handleCancel
|
|
1484
|
+
});
|
|
1610
1485
|
return {
|
|
1611
1486
|
backendURL,
|
|
1612
|
-
usingEnvFile: useEnvFile,
|
|
1613
|
-
proxyNextjs
|
|
1487
|
+
usingEnvFile: useEnvFile ?? false,
|
|
1488
|
+
proxyNextjs,
|
|
1489
|
+
installDepsConfirmed,
|
|
1490
|
+
ranInstall
|
|
1614
1491
|
};
|
|
1615
1492
|
}
|
|
1616
|
-
async function setupCustomMode({ context,
|
|
1617
|
-
const { logger, cwd } = context;
|
|
1493
|
+
async function setupCustomMode({ context, spinner }) {
|
|
1494
|
+
const { logger, cwd, framework: { pkg } } = context;
|
|
1495
|
+
if (!pkg) throw new Error('Error detecting framework');
|
|
1618
1496
|
const result = await generateFiles({
|
|
1619
1497
|
context,
|
|
1620
|
-
projectRoot,
|
|
1621
1498
|
mode: 'custom',
|
|
1622
|
-
pkg,
|
|
1623
1499
|
spinner
|
|
1624
1500
|
});
|
|
1625
1501
|
logger.info(`Remember to implement custom endpoint handlers ${result.configPath ? `(see ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, result.configPath))})` : ''}`);
|
|
1502
|
+
const { ranInstall, installDepsConfirmed } = await installDependencies({
|
|
1503
|
+
context,
|
|
1504
|
+
dependenciesToAdd: [
|
|
1505
|
+
context.framework.pkg
|
|
1506
|
+
]
|
|
1507
|
+
});
|
|
1626
1508
|
return {
|
|
1627
|
-
clientConfigContent: result.configContent ?? ''
|
|
1509
|
+
clientConfigContent: result.configContent ?? '',
|
|
1510
|
+
installDepsConfirmed,
|
|
1511
|
+
ranInstall
|
|
1628
1512
|
};
|
|
1629
1513
|
}
|
|
1630
|
-
async function setupOfflineMode({ context,
|
|
1514
|
+
async function setupOfflineMode({ context, spinner }) {
|
|
1631
1515
|
const result = await generateFiles({
|
|
1632
1516
|
context,
|
|
1633
|
-
projectRoot,
|
|
1634
1517
|
mode: 'offline',
|
|
1635
|
-
pkg,
|
|
1636
1518
|
spinner
|
|
1637
1519
|
});
|
|
1520
|
+
const { ranInstall, installDepsConfirmed } = await installDependencies({
|
|
1521
|
+
context,
|
|
1522
|
+
dependenciesToAdd: [
|
|
1523
|
+
context.framework.pkg
|
|
1524
|
+
]
|
|
1525
|
+
});
|
|
1638
1526
|
return {
|
|
1639
|
-
clientConfigContent: result.configContent ?? ''
|
|
1527
|
+
clientConfigContent: result.configContent ?? '',
|
|
1528
|
+
installDepsConfirmed,
|
|
1529
|
+
ranInstall
|
|
1640
1530
|
};
|
|
1641
1531
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1532
|
+
const ADAPTER_LABELS = {
|
|
1533
|
+
kyselyAdapter: 'kysely',
|
|
1534
|
+
drizzleAdapter: 'drizzle',
|
|
1535
|
+
prismaAdapter: 'prisma',
|
|
1536
|
+
typeormAdapter: 'typeorm',
|
|
1537
|
+
mongoAdapter: 'mongo'
|
|
1538
|
+
};
|
|
1539
|
+
const PROVIDERS_BY_ADAPTER = {
|
|
1540
|
+
kyselyAdapter: [
|
|
1541
|
+
{
|
|
1542
|
+
label: 'PostgreSQL',
|
|
1543
|
+
value: 'postgresql'
|
|
1544
|
+
},
|
|
1545
|
+
{
|
|
1546
|
+
label: 'MySQL',
|
|
1547
|
+
value: 'mysql'
|
|
1548
|
+
},
|
|
1549
|
+
{
|
|
1550
|
+
label: 'SQLite',
|
|
1551
|
+
value: 'sqlite'
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
label: 'CockroachDB',
|
|
1555
|
+
value: 'cockroachdb'
|
|
1556
|
+
},
|
|
1557
|
+
{
|
|
1558
|
+
label: 'Microsoft SQL Server',
|
|
1559
|
+
value: 'mssql'
|
|
1560
|
+
}
|
|
1561
|
+
],
|
|
1562
|
+
drizzleAdapter: [
|
|
1563
|
+
{
|
|
1564
|
+
label: 'PostgreSQL',
|
|
1565
|
+
value: 'postgresql'
|
|
1566
|
+
},
|
|
1567
|
+
{
|
|
1568
|
+
label: 'MySQL',
|
|
1569
|
+
value: 'mysql'
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
label: 'SQLite',
|
|
1573
|
+
value: 'sqlite'
|
|
1574
|
+
}
|
|
1575
|
+
],
|
|
1576
|
+
prismaAdapter: [
|
|
1577
|
+
{
|
|
1578
|
+
label: 'PostgreSQL',
|
|
1579
|
+
value: 'postgresql'
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
label: 'MySQL',
|
|
1583
|
+
value: 'mysql'
|
|
1584
|
+
},
|
|
1585
|
+
{
|
|
1586
|
+
label: 'SQLite',
|
|
1587
|
+
value: 'sqlite'
|
|
1588
|
+
},
|
|
1589
|
+
{
|
|
1590
|
+
label: 'MongoDB',
|
|
1591
|
+
value: 'mongodb'
|
|
1592
|
+
}
|
|
1593
|
+
],
|
|
1594
|
+
typeormAdapter: [
|
|
1595
|
+
{
|
|
1596
|
+
label: 'PostgreSQL',
|
|
1597
|
+
value: 'postgresql'
|
|
1598
|
+
},
|
|
1599
|
+
{
|
|
1600
|
+
label: 'MySQL',
|
|
1601
|
+
value: 'mysql'
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
label: 'SQLite',
|
|
1605
|
+
value: 'sqlite'
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
label: 'SQL Server',
|
|
1609
|
+
value: 'mssql'
|
|
1610
|
+
}
|
|
1611
|
+
],
|
|
1612
|
+
mongoAdapter: [
|
|
1613
|
+
{
|
|
1614
|
+
label: 'MongoDB',
|
|
1615
|
+
value: 'mongodb'
|
|
1616
|
+
}
|
|
1617
|
+
]
|
|
1618
|
+
};
|
|
1619
|
+
class Cancelled extends Error {
|
|
1620
|
+
stage;
|
|
1621
|
+
constructor(stage){
|
|
1622
|
+
super('Operation cancelled.');
|
|
1623
|
+
this.stage = stage;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
const CONFIG_BUILDERS = {
|
|
1627
|
+
kyselyAdapter: (provider)=>`kyselyAdapter({ provider: '${provider}', db })`,
|
|
1628
|
+
drizzleAdapter: (provider)=>`drizzleAdapter({ provider: '${provider}', db })`,
|
|
1629
|
+
prismaAdapter: (provider)=>`prismaAdapter({ provider: '${provider}', prisma })`,
|
|
1630
|
+
typeormAdapter: (provider)=>`typeormAdapter({ provider: '${provider}', source })`,
|
|
1631
|
+
mongoAdapter: ()=>'mongoAdapter({ client })'
|
|
1632
|
+
};
|
|
1633
|
+
async function pathExists(filePath) {
|
|
1634
|
+
try {
|
|
1635
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].access(filePath);
|
|
1636
|
+
return true;
|
|
1637
|
+
} catch {
|
|
1638
|
+
return false;
|
|
1668
1639
|
}
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1640
|
+
}
|
|
1641
|
+
function buildDatabaseConfig(adapter, provider, connection) {
|
|
1642
|
+
const builder = CONFIG_BUILDERS[adapter];
|
|
1643
|
+
return builder(provider, connection);
|
|
1644
|
+
}
|
|
1645
|
+
function buildKyselyPrelude(provider, connection) {
|
|
1646
|
+
const connExpr = connection.useEnv ? `process.env.${connection.envVar || 'DATABASE_URL'}!` : `"${connection.value || ''}"`;
|
|
1647
|
+
if ('postgresql' === provider || 'cockroachdb' === provider) return {
|
|
1648
|
+
imports: "import { Kysely, PostgresDialect } from 'kysely';\nimport { Pool } from 'pg';",
|
|
1649
|
+
prelude: `const db = new Kysely({\n\tdialect: new PostgresDialect({\n\t\tpool: new Pool({ connectionString: ${connExpr} }),\n\t}),\n});`
|
|
1650
|
+
};
|
|
1651
|
+
if ('mysql' === provider) return {
|
|
1652
|
+
imports: "import { Kysely, MysqlDialect } from 'kysely';\nimport mysql from 'mysql2/promise';",
|
|
1653
|
+
prelude: `const db = new Kysely({\n\tdialect: new MysqlDialect({\n\t\tpool: mysql.createPool(${connExpr}),\n\t}),\n});`
|
|
1654
|
+
};
|
|
1655
|
+
if ('mssql' === provider) return {
|
|
1656
|
+
imports: "import { Kysely, MssqlDialect } from 'kysely';\nimport mssql from 'mssql';",
|
|
1657
|
+
prelude: `const db = new Kysely({\n\tdialect: new MssqlDialect({\n\t\tpool: new mssql.ConnectionPool(${connExpr}),\n\t}),\n});`
|
|
1658
|
+
};
|
|
1659
|
+
return {
|
|
1660
|
+
imports: '',
|
|
1661
|
+
prelude: ''
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
function buildSqliteKyselyPrelude(file) {
|
|
1665
|
+
return {
|
|
1666
|
+
imports: "import { Kysely, SqliteDialect } from 'kysely';\nimport Database from 'better-sqlite3';",
|
|
1667
|
+
prelude: `const db = new Kysely({\n\tdialect: new SqliteDialect({\n\t\tdatabase: new Database("${file}"),\n\t}),\n});`
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
function buildDrizzlePrelude(provider, connection) {
|
|
1671
|
+
const connExpr = connection.useEnv ? `process.env.${connection.envVar || 'DATABASE_URL'}!` : `"${connection.value || ''}"`;
|
|
1672
|
+
if ('postgresql' === provider) return {
|
|
1673
|
+
imports: "import { drizzle } from 'drizzle-orm/node-postgres';\nimport { Pool } from 'pg';",
|
|
1674
|
+
prelude: `const db = drizzle(new Pool({ connectionString: ${connExpr} }));`
|
|
1675
|
+
};
|
|
1676
|
+
if ('mysql' === provider) return {
|
|
1677
|
+
imports: "import { drizzle } from 'drizzle-orm/mysql2';\nimport mysql from 'mysql2/promise';",
|
|
1678
|
+
prelude: `const db = drizzle(await mysql.createConnection(${connExpr}));`
|
|
1679
|
+
};
|
|
1680
|
+
if ('sqlite' === provider) {
|
|
1681
|
+
const file = connection.sqliteFile || './db.sqlite';
|
|
1682
|
+
return {
|
|
1683
|
+
imports: "import { drizzle } from 'drizzle-orm/better-sqlite3';\nimport Database from 'better-sqlite3';",
|
|
1684
|
+
prelude: `const db = drizzle(new Database("${file}"));`
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
return {
|
|
1688
|
+
imports: '',
|
|
1689
|
+
prelude: ''
|
|
1690
|
+
};
|
|
1691
|
+
}
|
|
1692
|
+
function buildPrismaPrelude(_provider, _connection) {
|
|
1693
|
+
return {
|
|
1694
|
+
imports: "import { PrismaClient } from '@prisma/client';",
|
|
1695
|
+
prelude: 'const prisma = new PrismaClient();'
|
|
1696
|
+
};
|
|
1697
|
+
}
|
|
1698
|
+
function buildTypeormPrelude(provider, connection) {
|
|
1699
|
+
const connExpr = connection.useEnv ? `process.env.${connection.envVar || 'DATABASE_URL'}!` : `"${connection.value || ''}"`;
|
|
1700
|
+
if ('sqlite' === provider) {
|
|
1701
|
+
const file = connection.sqliteFile || './db.sqlite';
|
|
1702
|
+
return {
|
|
1703
|
+
imports: "import { DataSource } from 'typeorm';",
|
|
1704
|
+
prelude: `const source = new DataSource({ type: 'sqlite', database: "${file}" });`
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1707
|
+
const typeMap = {
|
|
1708
|
+
postgresql: 'postgres',
|
|
1709
|
+
mysql: 'mysql',
|
|
1710
|
+
mssql: 'mssql'
|
|
1711
|
+
};
|
|
1712
|
+
return {
|
|
1713
|
+
imports: "import { DataSource } from 'typeorm';",
|
|
1714
|
+
prelude: `const source = new DataSource({ type: '${typeMap[String(provider)]}', url: ${connExpr} });`
|
|
1715
|
+
};
|
|
1716
|
+
}
|
|
1717
|
+
function buildMongoPrelude(connection) {
|
|
1718
|
+
const urlExpr = connection.useEnv ? `process.env.${connection.envVar || 'MONGODB_URI'}!` : `"${connection.value || ''}"`;
|
|
1719
|
+
return {
|
|
1720
|
+
imports: "import { MongoClient } from 'mongodb';",
|
|
1721
|
+
prelude: `const client = new MongoClient(${urlExpr});`
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
function buildFileContent(adapter, provider, dbConfig, connection) {
|
|
1725
|
+
const adapterPath = 'mongoAdapter' === adapter ? 'mongo' : adapter.replace('Adapter', '');
|
|
1726
|
+
const importAdapter = `import { ${adapter} } from '@c15t/backend/v2/db/adapters/${adapterPath}';`;
|
|
1727
|
+
let extras = {
|
|
1728
|
+
imports: '',
|
|
1729
|
+
prelude: ''
|
|
1730
|
+
};
|
|
1731
|
+
if ('kyselyAdapter' === adapter) if ('sqlite' === provider) {
|
|
1732
|
+
const file = connection.sqliteFile || './db.sqlite';
|
|
1733
|
+
extras = buildSqliteKyselyPrelude(file);
|
|
1734
|
+
} else extras = buildKyselyPrelude(provider, connection);
|
|
1735
|
+
else if ('drizzleAdapter' === adapter) extras = buildDrizzlePrelude(provider, connection);
|
|
1736
|
+
else if ('prismaAdapter' === adapter) extras = buildPrismaPrelude(provider, connection);
|
|
1737
|
+
else if ('typeormAdapter' === adapter) extras = buildTypeormPrelude(provider, connection);
|
|
1738
|
+
else if ('mongoAdapter' === adapter) extras = buildMongoPrelude(connection);
|
|
1739
|
+
return `import { defineConfig } from '@c15t/backend/v2';
|
|
1740
|
+
${importAdapter}
|
|
1741
|
+
${extras.imports ? `${extras.imports}\n` : ''}
|
|
1742
|
+
${extras.prelude ? `${extras.prelude}\n` : ''}
|
|
1743
|
+
export default defineConfig({
|
|
1744
|
+
adapter: ${dbConfig},
|
|
1684
1745
|
});
|
|
1685
|
-
|
|
1686
|
-
export default instance;
|
|
1687
1746
|
`;
|
|
1688
1747
|
}
|
|
1689
|
-
async function
|
|
1690
|
-
const
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
message: 'Set up the backend configuration now?',
|
|
1697
|
-
initialValue: true
|
|
1748
|
+
async function promptSelectAdapter() {
|
|
1749
|
+
const selection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.select({
|
|
1750
|
+
message: 'Select database adapter:',
|
|
1751
|
+
options: Object.keys(ADAPTER_LABELS).map((key)=>({
|
|
1752
|
+
value: key,
|
|
1753
|
+
label: ADAPTER_LABELS[key]
|
|
1754
|
+
}))
|
|
1698
1755
|
});
|
|
1699
|
-
if (
|
|
1700
|
-
|
|
1701
|
-
|
|
1756
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(selection)) throw new Cancelled('adapter_select');
|
|
1757
|
+
return selection;
|
|
1758
|
+
}
|
|
1759
|
+
async function promptSelectProvider(adapter) {
|
|
1760
|
+
const providers = PROVIDERS_BY_ADAPTER[adapter];
|
|
1761
|
+
if (0 === providers.length) throw new Error('No providers available for selected adapter');
|
|
1762
|
+
if (1 === providers.length) {
|
|
1763
|
+
const [first] = providers;
|
|
1764
|
+
return first.value;
|
|
1765
|
+
}
|
|
1766
|
+
const selection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.select({
|
|
1767
|
+
message: 'Select database provider:',
|
|
1768
|
+
options: providers.map((opt)=>({
|
|
1769
|
+
value: opt.value,
|
|
1770
|
+
label: opt.label
|
|
1771
|
+
}))
|
|
1702
1772
|
});
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
},
|
|
1715
|
-
{
|
|
1716
|
-
value: 'kysely-postgres',
|
|
1717
|
-
label: 'Kysely (PostgreSQL)',
|
|
1718
|
-
hint: 'Production'
|
|
1719
|
-
},
|
|
1720
|
-
{
|
|
1721
|
-
value: 'memory',
|
|
1722
|
-
label: 'Memory',
|
|
1723
|
-
hint: 'Testing/development only'
|
|
1724
|
-
}
|
|
1725
|
-
]
|
|
1773
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(selection)) throw new Cancelled('provider_select');
|
|
1774
|
+
return selection;
|
|
1775
|
+
}
|
|
1776
|
+
async function promptConnection(adapter, provider) {
|
|
1777
|
+
const connection = {
|
|
1778
|
+
useEnv: true
|
|
1779
|
+
};
|
|
1780
|
+
if ('sqlite' === provider) {
|
|
1781
|
+
const sqliteFile = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.text({
|
|
1782
|
+
message: 'SQLite file path:',
|
|
1783
|
+
initialValue: './db.sqlite'
|
|
1726
1784
|
});
|
|
1727
|
-
if (
|
|
1728
|
-
|
|
1729
|
-
|
|
1785
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(sqliteFile)) throw new Cancelled('sqlite_path');
|
|
1786
|
+
connection.sqliteFile = String(sqliteFile);
|
|
1787
|
+
return connection;
|
|
1788
|
+
}
|
|
1789
|
+
const useEnv = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1790
|
+
message: 'Store connection string in an environment variable?',
|
|
1791
|
+
initialValue: true
|
|
1792
|
+
});
|
|
1793
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(useEnv)) throw new Cancelled('use_env_confirm');
|
|
1794
|
+
connection.useEnv = Boolean(useEnv);
|
|
1795
|
+
if (connection.useEnv) {
|
|
1796
|
+
const defaultVar = 'mongoAdapter' === adapter ? 'MONGODB_URI' : 'DATABASE_URL';
|
|
1797
|
+
const envVarName = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.text({
|
|
1798
|
+
message: 'Env var name for connection string:',
|
|
1799
|
+
initialValue: defaultVar
|
|
1730
1800
|
});
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
});
|
|
1754
|
-
if (handleCancel?.(dbPathSelection)) context.error.handleCancel('Setup cancelled.', {
|
|
1755
|
-
command: 'onboarding',
|
|
1756
|
-
stage: 'self_hosted_sqlite_setup'
|
|
1757
|
-
});
|
|
1758
|
-
if (!dbPathSelection || '' === dbPathSelection) context.error.handleCancel('A valid database path is required', {
|
|
1759
|
-
command: 'onboarding',
|
|
1760
|
-
stage: 'self_hosted_sqlite_validation'
|
|
1761
|
-
});
|
|
1762
|
-
dbPath = dbPathSelection;
|
|
1763
|
-
}
|
|
1764
|
-
backendConfigContent = generateBackendConfigContent(adapterChoice, connectionString, dbPath);
|
|
1765
|
-
const backendConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, 'c15t.backend.ts');
|
|
1766
|
-
spinner.start('Creating backend configuration file...');
|
|
1767
|
-
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(backendConfigPath, backendConfigContent);
|
|
1768
|
-
spinner.stop(formatLogMessage('info', `Backend configuration created: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, backendConfigPath))}`));
|
|
1801
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(envVarName)) throw new Cancelled('env_var_name');
|
|
1802
|
+
connection.envVar = String(envVarName);
|
|
1803
|
+
return connection;
|
|
1804
|
+
}
|
|
1805
|
+
const placeholder = 'mongoAdapter' === adapter ? 'mongodb+srv://user:pass@host/db' : 'postgresql://user:pass@host:5432/db';
|
|
1806
|
+
const connectionString = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.text({
|
|
1807
|
+
message: 'Connection string:',
|
|
1808
|
+
placeholder
|
|
1809
|
+
});
|
|
1810
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(connectionString)) throw new Cancelled('connection_string');
|
|
1811
|
+
connection.value = String(connectionString);
|
|
1812
|
+
return connection;
|
|
1813
|
+
}
|
|
1814
|
+
async function ensureBackendConfig(context) {
|
|
1815
|
+
const { cwd, logger } = context;
|
|
1816
|
+
const targetPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cwd, 'c15t-backend.config.ts');
|
|
1817
|
+
if (await pathExists(targetPath)) {
|
|
1818
|
+
logger.debug(`Backend config already exists at ${targetPath}`);
|
|
1819
|
+
return {
|
|
1820
|
+
path: targetPath,
|
|
1821
|
+
dependencies: []
|
|
1822
|
+
};
|
|
1769
1823
|
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1824
|
+
try {
|
|
1825
|
+
const adapter = await promptSelectAdapter();
|
|
1826
|
+
const provider = await promptSelectProvider(adapter);
|
|
1827
|
+
const connection = await promptConnection(adapter, provider);
|
|
1828
|
+
const dependencies = [];
|
|
1829
|
+
if ('kyselyAdapter' === adapter) {
|
|
1830
|
+
dependencies.push('kysely');
|
|
1831
|
+
if ('postgresql' === provider || 'cockroachdb' === provider) dependencies.push('pg');
|
|
1832
|
+
else if ('mysql' === provider) dependencies.push('mysql2');
|
|
1833
|
+
else if ('mssql' === provider) dependencies.push('mssql');
|
|
1834
|
+
else if ('sqlite' === provider) dependencies.push('better-sqlite3');
|
|
1835
|
+
} else if ('drizzleAdapter' === adapter) {
|
|
1836
|
+
dependencies.push('drizzle-orm');
|
|
1837
|
+
if ('postgresql' === provider) dependencies.push('pg');
|
|
1838
|
+
else if ('mysql' === provider) dependencies.push('mysql2');
|
|
1839
|
+
else if ('sqlite' === provider) dependencies.push('better-sqlite3');
|
|
1840
|
+
} else if ('prismaAdapter' === adapter) dependencies.push('@prisma/client');
|
|
1841
|
+
else if ('typeormAdapter' === adapter) dependencies.push('typeorm');
|
|
1842
|
+
else if ('mongoAdapter' === adapter) dependencies.push('mongodb');
|
|
1843
|
+
const dbConfig = buildDatabaseConfig(adapter, provider, connection);
|
|
1844
|
+
const fileContent = buildFileContent(adapter, String(provider), dbConfig, connection);
|
|
1845
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(targetPath, fileContent, 'utf8');
|
|
1846
|
+
context.logger.success(`Created ${__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, targetPath)}`);
|
|
1847
|
+
if ('sqlite' !== provider && connection.useEnv && connection.envVar) context.logger.note(`Remember to set ${connection.envVar} in your environment or .env file.`, 'Environment');
|
|
1848
|
+
return {
|
|
1849
|
+
path: targetPath,
|
|
1850
|
+
dependencies
|
|
1851
|
+
};
|
|
1852
|
+
} catch (err) {
|
|
1853
|
+
if (err instanceof Cancelled) return context.error.handleCancel('Operation cancelled.', {
|
|
1854
|
+
command: 'ensure-backend-config',
|
|
1855
|
+
stage: err.stage
|
|
1856
|
+
});
|
|
1857
|
+
throw err;
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
async function handleMigrationResult(context, result) {
|
|
1861
|
+
const { logger, telemetry } = context;
|
|
1862
|
+
telemetry.trackEvent(TelemetryEventName.MIGRATION_PLANNED, {
|
|
1863
|
+
success: true
|
|
1864
|
+
});
|
|
1865
|
+
const viewSQL = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1866
|
+
message: 'View SQL for this migration?',
|
|
1867
|
+
initialValue: true
|
|
1868
|
+
});
|
|
1869
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(viewSQL)) return void telemetry.trackEvent(TelemetryEventName.MIGRATION_FAILED, {
|
|
1870
|
+
viewSQL: false
|
|
1871
|
+
});
|
|
1872
|
+
if (viewSQL) {
|
|
1873
|
+
const sql = result.getSQL?.() ?? '';
|
|
1874
|
+
logger.info(sql);
|
|
1875
|
+
}
|
|
1876
|
+
const execute = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1877
|
+
message: 'Execute this migration?',
|
|
1878
|
+
initialValue: false
|
|
1879
|
+
});
|
|
1880
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(execute)) return void telemetry.trackEvent(TelemetryEventName.MIGRATION_FAILED, {
|
|
1881
|
+
execute: false
|
|
1882
|
+
});
|
|
1883
|
+
await result.execute();
|
|
1884
|
+
logger.success('Migration completed.');
|
|
1885
|
+
telemetry.trackEvent(TelemetryEventName.MIGRATION_COMPLETED, {
|
|
1886
|
+
success: true
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
async function handleORMResult(context, result) {
|
|
1890
|
+
const { logger, telemetry, cwd } = context;
|
|
1891
|
+
const filePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cwd, result.path);
|
|
1892
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].mkdir(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(filePath), {
|
|
1893
|
+
recursive: true
|
|
1894
|
+
});
|
|
1895
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(filePath, result.code);
|
|
1896
|
+
logger.info(`Migration file created at ${filePath}`);
|
|
1897
|
+
telemetry.trackEvent(TelemetryEventName.MIGRATION_COMPLETED, {
|
|
1898
|
+
success: true,
|
|
1899
|
+
migrationFileCreated: true
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
async function readConfigAndGetDb(context, absoluteConfigPath) {
|
|
1903
|
+
const { logger } = context;
|
|
1904
|
+
logger.info(`Loading backend config from ${absoluteConfigPath}`);
|
|
1905
|
+
const resolvedPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].resolve(absoluteConfigPath);
|
|
1906
|
+
try {
|
|
1907
|
+
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].access(resolvedPath);
|
|
1908
|
+
} catch {
|
|
1909
|
+
throw new Error(`Backend config not found at: ${resolvedPath}`);
|
|
1910
|
+
}
|
|
1911
|
+
try {
|
|
1912
|
+
const { config } = await (0, __WEBPACK_EXTERNAL_MODULE_c12__.loadConfig)({
|
|
1913
|
+
configFile: absoluteConfigPath,
|
|
1914
|
+
jitiOptions: {
|
|
1915
|
+
extensions: [
|
|
1916
|
+
'.ts',
|
|
1917
|
+
'.tsx',
|
|
1918
|
+
'.js',
|
|
1919
|
+
'.jsx',
|
|
1920
|
+
'.mjs',
|
|
1921
|
+
'.cjs',
|
|
1922
|
+
'.mts',
|
|
1923
|
+
'.cts',
|
|
1924
|
+
'.cjs'
|
|
1925
|
+
]
|
|
1926
|
+
}
|
|
1927
|
+
});
|
|
1928
|
+
logger.debug('Imported Config');
|
|
1929
|
+
return {
|
|
1930
|
+
db: __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_schema_c18e255b__.DB.client(config.adapter)
|
|
1931
|
+
};
|
|
1932
|
+
} catch (error) {
|
|
1933
|
+
logger.error('Failed to load backend config', error);
|
|
1934
|
+
if (error instanceof Error) throw error;
|
|
1935
|
+
throw new Error(`Unknown error loading backend config: ${String(error)}`);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
async function migrate(context) {
|
|
1939
|
+
const { logger } = context;
|
|
1940
|
+
logger.info('Starting migration process...');
|
|
1941
|
+
const configResult = await ensureBackendConfig(context);
|
|
1942
|
+
if (!configResult || !configResult.path) return void logger.error('No backend config found.');
|
|
1943
|
+
const { path, dependencies } = configResult;
|
|
1944
|
+
if (dependencies.length > 0) await installDependencies({
|
|
1945
|
+
context,
|
|
1946
|
+
dependenciesToAdd: dependencies,
|
|
1947
|
+
autoInstall: true
|
|
1948
|
+
});
|
|
1949
|
+
const { db } = await readConfigAndGetDb(context, path);
|
|
1950
|
+
logger.info('Loaded c15t-backend.config.ts');
|
|
1951
|
+
const result = await (0, __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_migrator_64e67b79__.migrator)({
|
|
1952
|
+
db,
|
|
1953
|
+
schema: 'latest'
|
|
1954
|
+
});
|
|
1955
|
+
if ('path' in result) await handleORMResult(context, result);
|
|
1956
|
+
else await handleMigrationResult(context, result);
|
|
1957
|
+
}
|
|
1958
|
+
async function setupSelfHostedMode({ context, spinner, handleCancel }) {
|
|
1959
|
+
const dependenciesToAdd = [
|
|
1960
|
+
context.framework.pkg,
|
|
1961
|
+
'@c15t/backend'
|
|
1962
|
+
];
|
|
1963
|
+
const targetPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(context.cwd, 'c15t-backend.config.ts');
|
|
1964
|
+
let createBackendConfig = false;
|
|
1965
|
+
if (!await pathExists(targetPath)) {
|
|
1966
|
+
if (createBackendConfig) {
|
|
1967
|
+
const config = await ensureBackendConfig(context);
|
|
1968
|
+
createBackendConfig = true;
|
|
1969
|
+
dependenciesToAdd.push(...config?.dependencies ?? []);
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
const backendURL = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.text({
|
|
1973
|
+
message: 'Enter the backend URL:',
|
|
1974
|
+
initialValue: 'http://localhost:3000'
|
|
1975
|
+
});
|
|
1976
|
+
if (handleCancel?.(backendURL)) context.error.handleCancel('Setup cancelled.', {
|
|
1977
|
+
command: 'onboarding',
|
|
1978
|
+
stage: 'self_hosted_backend_url_setup'
|
|
1979
|
+
});
|
|
1980
|
+
const { useEnvFile, proxyNextjs } = await getSharedFrontendOptions({
|
|
1981
|
+
backendURL: backendURL,
|
|
1982
|
+
context,
|
|
1983
|
+
handleCancel
|
|
1984
|
+
});
|
|
1985
|
+
await generateFiles({
|
|
1986
|
+
context,
|
|
1987
|
+
mode: 'c15t',
|
|
1988
|
+
backendURL: backendURL,
|
|
1989
|
+
spinner,
|
|
1990
|
+
useEnvFile,
|
|
1991
|
+
proxyNextjs
|
|
1992
|
+
});
|
|
1993
|
+
const { ranInstall, installDepsConfirmed } = await installDependencies({
|
|
1994
|
+
context,
|
|
1995
|
+
dependenciesToAdd,
|
|
1996
|
+
handleCancel
|
|
1997
|
+
});
|
|
1998
|
+
const runMigrations = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1999
|
+
message: 'Would you like to run migrations?',
|
|
2000
|
+
initialValue: true
|
|
2001
|
+
});
|
|
2002
|
+
if (handleCancel?.(runMigrations)) context.error.handleCancel('Setup cancelled.', {
|
|
2003
|
+
command: 'onboarding',
|
|
2004
|
+
stage: 'self_hosted_run_migrations_setup'
|
|
2005
|
+
});
|
|
2006
|
+
if (runMigrations) await migrate(context);
|
|
2007
|
+
return {
|
|
2008
|
+
backendURL: backendURL,
|
|
2009
|
+
usingEnvFile: useEnvFile ?? false,
|
|
2010
|
+
proxyNextjs,
|
|
2011
|
+
createBackendConfig: createBackendConfig,
|
|
2012
|
+
installDepsConfirmed,
|
|
2013
|
+
ranInstall,
|
|
2014
|
+
runMigrations: runMigrations
|
|
2015
|
+
};
|
|
2016
|
+
}
|
|
2017
|
+
const WINDOWS_PATH_SEPARATOR_REGEX = /\\/g;
|
|
1783
2018
|
const FILE_EXTENSION_REGEX = /\.(ts|js|tsx|jsx)$/;
|
|
1784
|
-
async function
|
|
2019
|
+
async function generate(context, mode) {
|
|
1785
2020
|
const { logger, telemetry } = context;
|
|
1786
|
-
|
|
2021
|
+
logger.debug('Starting generate command...');
|
|
2022
|
+
logger.debug(`Mode: ${mode}`);
|
|
1787
2023
|
const handleCancel = (value)=>{
|
|
1788
2024
|
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(value)) {
|
|
1789
2025
|
telemetry.trackEvent(TelemetryEventName.ONBOARDING_EXITED, {
|
|
@@ -1799,12 +2035,10 @@ async function startOnboarding(context, existingConfig) {
|
|
|
1799
2035
|
return false;
|
|
1800
2036
|
};
|
|
1801
2037
|
try {
|
|
1802
|
-
logger.info(
|
|
1803
|
-
telemetry.trackEvent(
|
|
1804
|
-
isUpdate
|
|
1805
|
-
});
|
|
2038
|
+
logger.info('Starting onboarding process...');
|
|
2039
|
+
telemetry.trackEvent(TelemetryEventName.ONBOARDING_STARTED, {});
|
|
1806
2040
|
telemetry.flushSync();
|
|
1807
|
-
await performOnboarding(context,
|
|
2041
|
+
await performOnboarding(context, handleCancel, mode);
|
|
1808
2042
|
logger.success('🚀 Setup completed successfully!');
|
|
1809
2043
|
} catch (error) {
|
|
1810
2044
|
if (!__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(error)) telemetry.trackEvent(TelemetryEventName.ONBOARDING_COMPLETED, {
|
|
@@ -1813,70 +2047,78 @@ async function startOnboarding(context, existingConfig) {
|
|
|
1813
2047
|
});
|
|
1814
2048
|
}
|
|
1815
2049
|
}
|
|
1816
|
-
async function performOnboarding(context,
|
|
2050
|
+
async function performOnboarding(context, handleCancel, mode) {
|
|
1817
2051
|
const { telemetry, logger, packageManager } = context;
|
|
1818
|
-
const isUpdate = !!existingConfig;
|
|
1819
2052
|
const projectRoot = await detectProjectRoot(context.cwd, logger);
|
|
1820
2053
|
const { pkg } = await detectFramework(projectRoot, logger);
|
|
1821
2054
|
if (!pkg) throw new Error('Error detecting framework');
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
2055
|
+
let selectedMode = mode ?? null;
|
|
2056
|
+
logger.debug(`Selected mode: ${selectedMode}`);
|
|
2057
|
+
if (!selectedMode) selectedMode = await handleStorageModeSelection(context, handleCancel);
|
|
2058
|
+
if (!selectedMode) return;
|
|
2059
|
+
const sharedOptions = {
|
|
2060
|
+
context,
|
|
2061
|
+
spinner: __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner(),
|
|
2062
|
+
handleCancel
|
|
2063
|
+
};
|
|
2064
|
+
let installDepsConfirmed = false;
|
|
2065
|
+
let ranInstall = false;
|
|
2066
|
+
const dependenciesToAdd = [];
|
|
2067
|
+
switch(selectedMode){
|
|
1828
2068
|
case 'c15t':
|
|
1829
2069
|
{
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
spinner: __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner(),
|
|
1835
|
-
packageName: pkg,
|
|
1836
|
-
initialBackendURL,
|
|
1837
|
-
handleCancel
|
|
1838
|
-
});
|
|
2070
|
+
const c15tResult = await setupC15tMode(sharedOptions);
|
|
2071
|
+
installDepsConfirmed = c15tResult.installDepsConfirmed;
|
|
2072
|
+
ranInstall = c15tResult.ranInstall;
|
|
2073
|
+
dependenciesToAdd.push(context.framework.pkg);
|
|
1839
2074
|
telemetry.trackEvent(TelemetryEventName.ONBOARDING_C15T_MODE_CONFIGURED, {
|
|
1840
2075
|
usingEnvFile: c15tResult.usingEnvFile,
|
|
1841
|
-
hasInitialBackendURL: !!initialBackendURL,
|
|
1842
2076
|
proxyNextjs: c15tResult.proxyNextjs
|
|
1843
2077
|
});
|
|
1844
2078
|
break;
|
|
1845
2079
|
}
|
|
1846
2080
|
case 'offline':
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
2081
|
+
{
|
|
2082
|
+
const offlineResult = await setupOfflineMode({
|
|
2083
|
+
context,
|
|
2084
|
+
spinner: __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner()
|
|
2085
|
+
});
|
|
2086
|
+
installDepsConfirmed = offlineResult.installDepsConfirmed;
|
|
2087
|
+
ranInstall = offlineResult.ranInstall;
|
|
2088
|
+
dependenciesToAdd.push(context.framework.pkg);
|
|
2089
|
+
telemetry.trackEvent(TelemetryEventName.ONBOARDING_OFFLINE_MODE_CONFIGURED, {});
|
|
2090
|
+
break;
|
|
2091
|
+
}
|
|
1855
2092
|
case 'self-hosted':
|
|
1856
2093
|
{
|
|
1857
|
-
const selfHostedResult = await setupSelfHostedMode(
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
dependencies: selfHostedResult.dependencies.join(',')
|
|
2094
|
+
const selfHostedResult = await setupSelfHostedMode({
|
|
2095
|
+
context,
|
|
2096
|
+
spinner: __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner(),
|
|
2097
|
+
handleCancel
|
|
1862
2098
|
});
|
|
2099
|
+
installDepsConfirmed = selfHostedResult.installDepsConfirmed;
|
|
2100
|
+
ranInstall = selfHostedResult.ranInstall;
|
|
2101
|
+
dependenciesToAdd.push(context.framework.pkg);
|
|
2102
|
+
telemetry.trackEvent(TelemetryEventName.ONBOARDING_SELF_HOSTED_CONFIGURED, {});
|
|
1863
2103
|
break;
|
|
1864
2104
|
}
|
|
1865
2105
|
default:
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
2106
|
+
{
|
|
2107
|
+
const customResult = await setupCustomMode({
|
|
2108
|
+
context,
|
|
2109
|
+
spinner: __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner()
|
|
2110
|
+
});
|
|
2111
|
+
installDepsConfirmed = customResult.installDepsConfirmed;
|
|
2112
|
+
ranInstall = customResult.ranInstall;
|
|
2113
|
+
dependenciesToAdd.push(context.framework.pkg);
|
|
2114
|
+
telemetry.trackEvent(TelemetryEventName.ONBOARDING_CUSTOM_MODE_CONFIGURED, {});
|
|
2115
|
+
break;
|
|
2116
|
+
}
|
|
1874
2117
|
}
|
|
1875
|
-
const { installDepsConfirmed, ranInstall } = await handleDependencyInstallation(context, projectRoot, dependenciesToAdd, packageManager, handleCancel, isUpdate);
|
|
1876
2118
|
await displayNextSteps({
|
|
1877
2119
|
context,
|
|
1878
2120
|
projectRoot,
|
|
1879
|
-
storageMode,
|
|
2121
|
+
storageMode: selectedMode,
|
|
1880
2122
|
installDepsConfirmed,
|
|
1881
2123
|
ranInstall,
|
|
1882
2124
|
dependenciesToAdd,
|
|
@@ -1885,16 +2127,15 @@ async function performOnboarding(context, existingConfig, handleCancel) {
|
|
|
1885
2127
|
await handleGitHubStar(context);
|
|
1886
2128
|
telemetry.trackEvent(TelemetryEventName.ONBOARDING_COMPLETED, {
|
|
1887
2129
|
success: true,
|
|
1888
|
-
|
|
2130
|
+
selectedMode,
|
|
1889
2131
|
installDependencies: ranInstall
|
|
1890
2132
|
});
|
|
1891
2133
|
}
|
|
1892
|
-
async function handleStorageModeSelection(context, handleCancel
|
|
2134
|
+
async function handleStorageModeSelection(context, handleCancel) {
|
|
1893
2135
|
const { telemetry } = context;
|
|
1894
|
-
const initialStorageMode = getInitialStorageMode(existingConfig);
|
|
1895
2136
|
const storageModeSelection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.select({
|
|
1896
|
-
message:
|
|
1897
|
-
initialValue:
|
|
2137
|
+
message: 'How would you like to store consent decisions?',
|
|
2138
|
+
initialValue: 'c15t',
|
|
1898
2139
|
options: [
|
|
1899
2140
|
{
|
|
1900
2141
|
value: 'c15t',
|
|
@@ -1921,71 +2162,15 @@ async function handleStorageModeSelection(context, handleCancel, existingConfig)
|
|
|
1921
2162
|
if (handleCancel(storageModeSelection)) return null;
|
|
1922
2163
|
const storageMode = storageModeSelection;
|
|
1923
2164
|
telemetry.trackEvent(TelemetryEventName.ONBOARDING_STORAGE_MODE_SELECTED, {
|
|
1924
|
-
storageMode
|
|
1925
|
-
isUpdate: !!existingConfig
|
|
2165
|
+
storageMode
|
|
1926
2166
|
});
|
|
1927
2167
|
return storageMode;
|
|
1928
2168
|
}
|
|
1929
|
-
async function handleDependencyInstallation(context, projectRoot, dependenciesToAdd, packageManager, handleCancel, isUpdate) {
|
|
1930
|
-
const { telemetry, logger } = context;
|
|
1931
|
-
const s = __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner();
|
|
1932
|
-
if (0 === dependenciesToAdd.length) return {
|
|
1933
|
-
installDepsConfirmed: false,
|
|
1934
|
-
ranInstall: false
|
|
1935
|
-
};
|
|
1936
|
-
const depsString = dependenciesToAdd.map((d)=>__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(d)).join(', ');
|
|
1937
|
-
const addDepsSelection = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
1938
|
-
message: `${isUpdate ? 'Update' : 'Add'} required dependencies using ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(packageManager.name)}? (${depsString})`,
|
|
1939
|
-
initialValue: true
|
|
1940
|
-
});
|
|
1941
|
-
if (handleCancel(addDepsSelection)) return {
|
|
1942
|
-
installDepsConfirmed: false,
|
|
1943
|
-
ranInstall: false
|
|
1944
|
-
};
|
|
1945
|
-
if (!addDepsSelection) return {
|
|
1946
|
-
installDepsConfirmed: false,
|
|
1947
|
-
ranInstall: false
|
|
1948
|
-
};
|
|
1949
|
-
s.start(`Running ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(packageManager.name)} to add and install dependencies... (this might take a moment)`);
|
|
1950
|
-
try {
|
|
1951
|
-
await addAndInstallDependenciesViaPM(projectRoot, dependenciesToAdd, packageManager.name);
|
|
1952
|
-
s.stop(`✅ Dependencies installed: ${dependenciesToAdd.map((d)=>__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(d)).join(', ')}`);
|
|
1953
|
-
telemetry.trackEvent(TelemetryEventName.ONBOARDING_DEPENDENCIES_INSTALLED, {
|
|
1954
|
-
success: true,
|
|
1955
|
-
dependencies: dependenciesToAdd.join(','),
|
|
1956
|
-
packageManager: packageManager.name
|
|
1957
|
-
});
|
|
1958
|
-
return {
|
|
1959
|
-
installDepsConfirmed: true,
|
|
1960
|
-
ranInstall: true
|
|
1961
|
-
};
|
|
1962
|
-
} catch (installError) {
|
|
1963
|
-
s.stop(__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].yellow('⚠️ Dependency installation failed.'));
|
|
1964
|
-
logger.error('Installation Error:', installError);
|
|
1965
|
-
telemetry.trackEvent(TelemetryEventName.ONBOARDING_DEPENDENCIES_INSTALLED, {
|
|
1966
|
-
success: false,
|
|
1967
|
-
error: installError instanceof Error ? installError.message : String(installError),
|
|
1968
|
-
dependencies: dependenciesToAdd.join(','),
|
|
1969
|
-
packageManager: packageManager.name
|
|
1970
|
-
});
|
|
1971
|
-
const pmCommand = getManualInstallCommand(dependenciesToAdd, packageManager.name);
|
|
1972
|
-
logger.info(`Please try running '${pmCommand}' manually in ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(context.cwd, projectRoot))}.`);
|
|
1973
|
-
return {
|
|
1974
|
-
installDepsConfirmed: true,
|
|
1975
|
-
ranInstall: false
|
|
1976
|
-
};
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
function getInitialStorageMode(config) {
|
|
1980
|
-
if (!config) return;
|
|
1981
|
-
if ('mode' in config) return isClientOptions(config) ? config.mode : 'c15t';
|
|
1982
|
-
}
|
|
1983
2169
|
async function displayNextSteps(options) {
|
|
1984
2170
|
const { context, projectRoot, storageMode, installDepsConfirmed, ranInstall, dependenciesToAdd, packageManager } = options;
|
|
1985
2171
|
const { logger, cwd } = context;
|
|
1986
2172
|
const { log } = __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__;
|
|
1987
2173
|
const configPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, 'c15t.config.ts');
|
|
1988
|
-
const backendConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, 'c15t.backend.ts');
|
|
1989
2174
|
const relativeConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, configPath);
|
|
1990
2175
|
const importPath = `./${relativeConfigPath.replace(WINDOWS_PATH_SEPARATOR_REGEX, '/').replace(FILE_EXTENSION_REGEX, '')}`;
|
|
1991
2176
|
const importStatement = __WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(`import { c15tConfig } from '${importPath}';`);
|
|
@@ -1995,20 +2180,9 @@ async function displayNextSteps(options) {
|
|
|
1995
2180
|
case 'offline':
|
|
1996
2181
|
break;
|
|
1997
2182
|
case 'self-hosted':
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
try {
|
|
2002
|
-
await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].access(backendConfigPath);
|
|
2003
|
-
steps += `1. Configure database connection in ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, backendConfigPath))}.\n`;
|
|
2004
|
-
steps += ' 2. Set up API routes using the exported backend instance.\n';
|
|
2005
|
-
} catch {
|
|
2006
|
-
steps += '1. Set up your c15t backend instance and API routes.\n';
|
|
2007
|
-
}
|
|
2008
|
-
steps += `3. Ensure ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan('backendURL')} in ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeConfigPath)} points to your API.\n`;
|
|
2009
|
-
logger.info(steps);
|
|
2010
|
-
break;
|
|
2011
|
-
}
|
|
2183
|
+
log.step('Setup your backend with the c15t docs:');
|
|
2184
|
+
logger.info('https://c15t.com/docs/self-host/v2');
|
|
2185
|
+
break;
|
|
2012
2186
|
case 'custom':
|
|
2013
2187
|
{
|
|
2014
2188
|
log.step('Configuration Complete! Next Steps:');
|
|
@@ -2054,335 +2228,90 @@ If you find this useful, we'd really appreciate a GitHub star - it helps others
|
|
|
2054
2228
|
logger.info(`You can star us later by visiting: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan('https://github.com/c15t/c15t')}`);
|
|
2055
2229
|
}
|
|
2056
2230
|
}
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
logger.debug('Attempting to load configuration...');
|
|
2070
|
-
const config = await context.config.loadConfig();
|
|
2071
|
-
if (!config) {
|
|
2072
|
-
logger.debug('No config found during setup, generate command will handle onboarding.');
|
|
2073
|
-
try {
|
|
2074
|
-
const memAdapter = await (0, __WEBPACK_EXTERNAL_MODULE__c15t_backend_pkgs_db_adapters_cee37d0f__.getAdapter)({
|
|
2075
|
-
appName: 'temp-for-setup',
|
|
2076
|
-
database: {
|
|
2077
|
-
adapter: 'memory'
|
|
2078
|
-
}
|
|
2079
|
-
});
|
|
2080
|
-
return {
|
|
2081
|
-
config: null,
|
|
2082
|
-
adapter: memAdapter
|
|
2083
|
-
};
|
|
2084
|
-
} catch (adapterError) {
|
|
2085
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_FAILED, {
|
|
2086
|
-
error: adapterError instanceof Error ? adapterError.message : String(adapterError),
|
|
2087
|
-
stage: 'adapter_initialization'
|
|
2088
|
-
});
|
|
2089
|
-
return error.handleError(adapterError, 'Failed to initialize default memory adapter');
|
|
2090
|
-
}
|
|
2091
|
-
}
|
|
2092
|
-
logger.debug('Config loaded, initializing adapter...');
|
|
2093
|
-
let adapter;
|
|
2094
|
-
try {
|
|
2095
|
-
adapter = await (0, __WEBPACK_EXTERNAL_MODULE__c15t_backend_pkgs_db_adapters_cee37d0f__.getAdapter)(config);
|
|
2096
|
-
logger.debug('Adapter initialized successfully');
|
|
2097
|
-
} catch (e) {
|
|
2098
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_FAILED, {
|
|
2099
|
-
error: e instanceof Error ? e.message : String(e),
|
|
2100
|
-
stage: 'adapter_initialization_with_config'
|
|
2101
|
-
});
|
|
2102
|
-
return error.handleError(e, 'Failed to initialize database adapter');
|
|
2103
|
-
}
|
|
2104
|
-
if (!adapter) {
|
|
2105
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_FAILED, {
|
|
2106
|
-
error: 'Adapter initialization returned undefined',
|
|
2107
|
-
stage: 'adapter_initialization_check'
|
|
2108
|
-
});
|
|
2109
|
-
return error.handleError(new Error('Adapter initialization returned undefined'), 'Database adapter could not be initialized');
|
|
2231
|
+
const subcommands = [
|
|
2232
|
+
{
|
|
2233
|
+
name: 'generate',
|
|
2234
|
+
label: 'Generate',
|
|
2235
|
+
hint: 'Generate code for your c15t project',
|
|
2236
|
+
action: generate
|
|
2237
|
+
},
|
|
2238
|
+
{
|
|
2239
|
+
name: 'migrate',
|
|
2240
|
+
label: 'Migrate',
|
|
2241
|
+
hint: 'Run database migrations',
|
|
2242
|
+
action: migrate
|
|
2110
2243
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
};
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
});
|
|
2132
|
-
const shouldUpdate = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
2133
|
-
message: formatLogMessage('warn', `A c15t configuration already exists. Would you like to update it before generating? (${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].dim(`Current mode: ${currentMode}`)})`),
|
|
2134
|
-
initialValue: false
|
|
2135
|
-
});
|
|
2136
|
-
if (!shouldUpdate) {
|
|
2137
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_COMPLETED, {
|
|
2138
|
-
success: false,
|
|
2139
|
-
reason: 'user_cancelled'
|
|
2140
|
-
});
|
|
2141
|
-
return error.handleCancel('Operation cancelled.', {
|
|
2142
|
-
command: 'generate',
|
|
2143
|
-
stage: 'config_update_prompt'
|
|
2144
|
-
});
|
|
2145
|
-
}
|
|
2146
|
-
if (shouldUpdate) {
|
|
2147
|
-
await startOnboarding(context, config);
|
|
2148
|
-
logger.debug('Reloading configuration after update...');
|
|
2149
|
-
const postUpdateResult = await setupGenerateEnvironment(context);
|
|
2150
|
-
if (!postUpdateResult.config) {
|
|
2151
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_FAILED, {
|
|
2152
|
-
error: 'Failed to load configuration after update'
|
|
2244
|
+
];
|
|
2245
|
+
async function selfHost(context) {
|
|
2246
|
+
const { logger, telemetry, commandArgs, error } = context;
|
|
2247
|
+
logger.debug('Starting self-host command...');
|
|
2248
|
+
telemetry.trackEvent(TelemetryEventName.SELF_HOST_STARTED, {});
|
|
2249
|
+
const [subcommand] = commandArgs;
|
|
2250
|
+
if (subcommand) {
|
|
2251
|
+
switch(subcommand){
|
|
2252
|
+
case 'generate':
|
|
2253
|
+
await generate(context, 'self-hosted');
|
|
2254
|
+
break;
|
|
2255
|
+
case 'migrate':
|
|
2256
|
+
await migrate(context);
|
|
2257
|
+
break;
|
|
2258
|
+
default:
|
|
2259
|
+
logger.error(`Unknown self-host subcommand: ${subcommand}`);
|
|
2260
|
+
logger.info('Available subcommands: generate, migrate');
|
|
2261
|
+
telemetry.trackEvent(TelemetryEventName.SELF_HOST_COMPLETED, {
|
|
2262
|
+
success: false,
|
|
2263
|
+
reason: 'unknown_subcommand'
|
|
2153
2264
|
});
|
|
2154
|
-
|
|
2155
|
-
}
|
|
2156
|
-
config = postUpdateResult.config;
|
|
2157
|
-
postUpdateResult.adapter;
|
|
2158
|
-
logger.info('Configuration updated successfully.');
|
|
2159
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_COMPLETED, {
|
|
2160
|
-
success: true,
|
|
2161
|
-
configUpdated: true
|
|
2162
|
-
});
|
|
2163
|
-
} else {
|
|
2164
|
-
logger.debug('Proceeding with existing configuration.');
|
|
2165
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_COMPLETED, {
|
|
2166
|
-
success: true,
|
|
2167
|
-
configUpdated: false
|
|
2168
|
-
});
|
|
2169
|
-
}
|
|
2170
|
-
} else {
|
|
2171
|
-
logger.info('No configuration found.');
|
|
2172
|
-
telemetry.trackEvent(TelemetryEventName.CONFIG_LOADED, {
|
|
2173
|
-
exists: false
|
|
2174
|
-
});
|
|
2175
|
-
const shouldOnboard = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
|
|
2176
|
-
message: 'No c15t configuration found. Would you like to create one now?',
|
|
2177
|
-
initialValue: true
|
|
2178
|
-
});
|
|
2179
|
-
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(shouldOnboard) || !shouldOnboard) {
|
|
2180
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_COMPLETED, {
|
|
2181
|
-
success: false,
|
|
2182
|
-
reason: 'onboarding_declined'
|
|
2183
|
-
});
|
|
2184
|
-
return error.handleCancel('Configuration setup cancelled.', {
|
|
2185
|
-
command: 'generate',
|
|
2186
|
-
stage: 'onboarding_prompt'
|
|
2187
|
-
});
|
|
2188
|
-
}
|
|
2189
|
-
await startOnboarding(context);
|
|
2190
|
-
logger.debug('Reloading configuration after onboarding...');
|
|
2191
|
-
const postOnboardResult = await setupGenerateEnvironment(context);
|
|
2192
|
-
if (!postOnboardResult.config) {
|
|
2193
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_FAILED, {
|
|
2194
|
-
error: 'Failed to load configuration even after onboarding'
|
|
2195
|
-
});
|
|
2196
|
-
return error.handleError(new Error('Failed to load configuration even after onboarding.'), 'Configuration Error');
|
|
2265
|
+
break;
|
|
2197
2266
|
}
|
|
2198
|
-
|
|
2199
|
-
postOnboardResult.adapter;
|
|
2200
|
-
logger.info('New configuration loaded successfully.');
|
|
2201
|
-
telemetry.trackEvent(TelemetryEventName.GENERATE_COMPLETED, {
|
|
2202
|
-
success: true,
|
|
2203
|
-
newConfigCreated: true
|
|
2204
|
-
});
|
|
2267
|
+
return;
|
|
2205
2268
|
}
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
logger.info('Executing migrations...');
|
|
2210
|
-
const s = __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner();
|
|
2211
|
-
s.start('Running migrations...');
|
|
2212
|
-
telemetry.trackEvent(TelemetryEventName.MIGRATION_EXECUTED, {
|
|
2213
|
-
status: 'started'
|
|
2269
|
+
logger.debug('No subcommand specified, entering interactive selection.');
|
|
2270
|
+
telemetry.trackEvent(TelemetryEventName.INTERACTIVE_MENU_OPENED, {
|
|
2271
|
+
context: 'self-host'
|
|
2214
2272
|
});
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2273
|
+
const promptOptions = subcommands.map((cmd)=>({
|
|
2274
|
+
value: cmd.name,
|
|
2275
|
+
label: cmd.label,
|
|
2276
|
+
hint: cmd.hint
|
|
2277
|
+
}));
|
|
2278
|
+
promptOptions.push({
|
|
2279
|
+
value: 'exit',
|
|
2280
|
+
label: 'Exit',
|
|
2281
|
+
hint: 'Return to main menu'
|
|
2282
|
+
});
|
|
2283
|
+
const selectedSubcommandName = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.select({
|
|
2284
|
+
message: formatLogMessage('info', 'Which self-host command would you like to run?'),
|
|
2285
|
+
options: promptOptions
|
|
2286
|
+
});
|
|
2287
|
+
if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(selectedSubcommandName) || 'exit' === selectedSubcommandName) {
|
|
2288
|
+
logger.debug('Interactive selection cancelled or exit chosen.');
|
|
2289
|
+
telemetry.trackEvent(TelemetryEventName.INTERACTIVE_MENU_EXITED, {
|
|
2290
|
+
action: __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(selectedSubcommandName) ? 'cancelled' : 'exit',
|
|
2291
|
+
context: 'self-host'
|
|
2221
2292
|
});
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
status: 'failed',
|
|
2226
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2293
|
+
error.handleCancel('Operation cancelled.', {
|
|
2294
|
+
command: 'self-host',
|
|
2295
|
+
stage: 'menu_selection'
|
|
2227
2296
|
});
|
|
2228
|
-
|
|
2229
|
-
}
|
|
2230
|
-
}
|
|
2231
|
-
async function planMigrations(context, config, skipConfirmation) {
|
|
2232
|
-
const { logger } = context;
|
|
2233
|
-
logger.info('Planning migrations...');
|
|
2234
|
-
logger.debug('Config:', config);
|
|
2235
|
-
logger.debug(`Skip confirmation: ${skipConfirmation}`);
|
|
2236
|
-
const s = __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.spinner();
|
|
2237
|
-
s.start('Preparing migration plan...');
|
|
2238
|
-
let migrationData;
|
|
2239
|
-
try {
|
|
2240
|
-
migrationData = await (0, __WEBPACK_EXTERNAL_MODULE__c15t_backend_pkgs_migrations_80b6e3bd__.getMigrations)(config);
|
|
2241
|
-
logger.debug('Migration data:', migrationData);
|
|
2242
|
-
} catch (err) {
|
|
2243
|
-
s.stop('Migration preparation failed.');
|
|
2244
|
-
if (err instanceof Error) logger.error(err.message);
|
|
2245
|
-
else logger.error(String(err));
|
|
2246
|
-
logger.failed('Migration planning failed');
|
|
2247
|
-
return {
|
|
2248
|
-
shouldRun: false,
|
|
2249
|
-
runMigrationsFn: null
|
|
2250
|
-
};
|
|
2251
|
-
}
|
|
2252
|
-
if (!migrationData) {
|
|
2253
|
-
s.stop('Could not retrieve migration data.');
|
|
2254
|
-
logger.failed('Migration planning failed');
|
|
2255
|
-
return {
|
|
2256
|
-
shouldRun: false,
|
|
2257
|
-
runMigrationsFn: null
|
|
2258
|
-
};
|
|
2259
|
-
}
|
|
2260
|
-
const { toBeAdded, toBeCreated, runMigrations } = migrationData;
|
|
2261
|
-
logger.debug('Migrations to be added:', toBeAdded);
|
|
2262
|
-
logger.debug('Migrations to be created:', toBeCreated);
|
|
2263
|
-
if (!toBeAdded.length && !toBeCreated.length) {
|
|
2264
|
-
s.stop('No migrations needed.');
|
|
2265
|
-
logger.info('🚀 Database is up to date');
|
|
2266
|
-
return {
|
|
2267
|
-
shouldRun: false,
|
|
2268
|
-
runMigrationsFn: null
|
|
2269
|
-
};
|
|
2270
|
-
}
|
|
2271
|
-
s.stop('Migration plan prepared.');
|
|
2272
|
-
logger.info('🔑 The following migrations will be applied:');
|
|
2273
|
-
for (const table of [
|
|
2274
|
-
...toBeCreated,
|
|
2275
|
-
...toBeAdded
|
|
2276
|
-
]){
|
|
2277
|
-
const fields = Object.keys(table.fields).join(', ');
|
|
2278
|
-
const tableName = table.table;
|
|
2279
|
-
logger.info(` + Table ${tableName}: Add fields [${fields}]`);
|
|
2280
|
-
logger.message(` ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan('+')} Table ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].yellow(tableName)}: Add fields [${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green(fields)}]`);
|
|
2281
|
-
}
|
|
2282
|
-
logger.message('');
|
|
2283
|
-
let shouldMigrate = skipConfirmation;
|
|
2284
|
-
if (!shouldMigrate) {
|
|
2285
|
-
shouldMigrate = await context.confirm('Apply these migrations to the database?', false);
|
|
2286
|
-
logger.debug(`User confirmation: ${shouldMigrate}`);
|
|
2287
|
-
}
|
|
2288
|
-
if (!shouldMigrate) {
|
|
2289
|
-
logger.failed('Migration cancelled');
|
|
2290
|
-
return {
|
|
2291
|
-
shouldRun: false,
|
|
2292
|
-
runMigrationsFn: null
|
|
2293
|
-
};
|
|
2294
|
-
}
|
|
2295
|
-
logger.debug('Proceeding with migration execution');
|
|
2296
|
-
return {
|
|
2297
|
-
shouldRun: true,
|
|
2298
|
-
runMigrationsFn: runMigrations
|
|
2299
|
-
};
|
|
2300
|
-
}
|
|
2301
|
-
async function loadConfigAndOnboard(context) {
|
|
2302
|
-
const { logger } = context;
|
|
2303
|
-
logger.debug('Checking for existing configuration...');
|
|
2304
|
-
let config;
|
|
2305
|
-
try {
|
|
2306
|
-
config = await context.config.loadConfig();
|
|
2307
|
-
} catch (error) {
|
|
2308
|
-
return context.error.handleError(error, 'Unexpected error during configuration loading');
|
|
2309
|
-
}
|
|
2310
|
-
if (!config) {
|
|
2311
|
-
logger.info('No config found, starting onboarding.');
|
|
2312
|
-
await startOnboarding(context);
|
|
2313
|
-
logger.debug('Exiting after triggering onboarding.');
|
|
2314
|
-
process.exit(0);
|
|
2297
|
+
return;
|
|
2315
2298
|
}
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
}
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
error.handleError(new Error('Adapter validation failed: Not using Kysely'), message);
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
async function setupEnvironment(context) {
|
|
2330
|
-
const { logger, flags, cwd, error } = context;
|
|
2331
|
-
logger.info('Setting up migration environment...');
|
|
2332
|
-
logger.debug('Flags:', flags);
|
|
2333
|
-
logger.debug(`Working directory: ${cwd}`);
|
|
2334
|
-
if (!(0, __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__.existsSync)(cwd)) return error.handleError(new Error(`The directory "${cwd}" does not exist`), 'Migration setup failed');
|
|
2335
|
-
const config = await loadConfigAndOnboard(context);
|
|
2336
|
-
logger.debug('Config loaded:', config);
|
|
2337
|
-
let adapter;
|
|
2338
|
-
try {
|
|
2339
|
-
logger.debug('Initializing database adapter...');
|
|
2340
|
-
adapter = await (0, __WEBPACK_EXTERNAL_MODULE__c15t_backend_pkgs_db_adapters_cee37d0f__.getAdapter)(config);
|
|
2341
|
-
logger.debug('Adapter initialized:', adapter);
|
|
2342
|
-
} catch (e) {
|
|
2343
|
-
return error.handleError(e, 'Failed to initialize database adapter');
|
|
2344
|
-
}
|
|
2345
|
-
validateAdapterIsKysely(context, adapter);
|
|
2346
|
-
logger.info('✅ Environment setup complete');
|
|
2347
|
-
return {
|
|
2348
|
-
config,
|
|
2349
|
-
adapter: adapter
|
|
2350
|
-
};
|
|
2351
|
-
}
|
|
2352
|
-
async function migrate(context) {
|
|
2353
|
-
const { logger, flags, telemetry } = context;
|
|
2354
|
-
logger.info('Starting migration process...');
|
|
2355
|
-
logger.debug('Context:', context);
|
|
2356
|
-
telemetry.trackEvent(TelemetryEventName.MIGRATION_STARTED, {
|
|
2357
|
-
skipConfirmation: true === flags.y
|
|
2358
|
-
});
|
|
2359
|
-
const skipConfirmation = flags.y;
|
|
2360
|
-
try {
|
|
2361
|
-
const { config } = await setupEnvironment(context);
|
|
2362
|
-
const planResult = await planMigrations(context, config, skipConfirmation);
|
|
2363
|
-
logger.debug('Plan result:', planResult);
|
|
2364
|
-
telemetry.trackEvent(TelemetryEventName.MIGRATION_PLANNED, {
|
|
2365
|
-
shouldRun: planResult.shouldRun,
|
|
2366
|
-
hasMigrations: !!planResult.runMigrationsFn
|
|
2367
|
-
});
|
|
2368
|
-
if (planResult.shouldRun && planResult.runMigrationsFn) {
|
|
2369
|
-
await executeMigrations(context, planResult.runMigrationsFn);
|
|
2370
|
-
telemetry.trackEvent(TelemetryEventName.MIGRATION_COMPLETED, {
|
|
2371
|
-
success: true
|
|
2372
|
-
});
|
|
2373
|
-
} else {
|
|
2374
|
-
logger.debug('Skipping migration execution based on plan result');
|
|
2375
|
-
telemetry.trackEvent(TelemetryEventName.MIGRATION_COMPLETED, {
|
|
2376
|
-
success: true,
|
|
2377
|
-
reason: planResult.shouldRun ? 'no_migrations_needed' : 'user_cancelled'
|
|
2378
|
-
});
|
|
2379
|
-
}
|
|
2380
|
-
} catch (error) {
|
|
2381
|
-
telemetry.trackEvent(TelemetryEventName.MIGRATION_FAILED, {
|
|
2382
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2299
|
+
const selectedSubcommand = subcommands.find((cmd)=>cmd.name === selectedSubcommandName);
|
|
2300
|
+
if (selectedSubcommand) {
|
|
2301
|
+
logger.debug(`User selected subcommand: ${selectedSubcommand.name}`);
|
|
2302
|
+
if ('generate' === selectedSubcommand.name) await generate(context, 'self-hosted');
|
|
2303
|
+
else await selectedSubcommand.action(context);
|
|
2304
|
+
} else {
|
|
2305
|
+
logger.error(`Unknown subcommand: ${selectedSubcommandName}`);
|
|
2306
|
+
telemetry.trackEvent(TelemetryEventName.SELF_HOST_COMPLETED, {
|
|
2307
|
+
success: false,
|
|
2308
|
+
reason: 'invalid_selection'
|
|
2383
2309
|
});
|
|
2384
|
-
|
|
2310
|
+
return;
|
|
2385
2311
|
}
|
|
2312
|
+
telemetry.trackEvent(TelemetryEventName.SELF_HOST_COMPLETED, {
|
|
2313
|
+
success: true
|
|
2314
|
+
});
|
|
2386
2315
|
}
|
|
2387
2316
|
async function displayIntro(context, version) {
|
|
2388
2317
|
const { logger } = context;
|
|
@@ -2431,86 +2360,6 @@ async function displayIntro(context, version) {
|
|
|
2431
2360
|
});
|
|
2432
2361
|
logger.message(coloredLines.join('\n'));
|
|
2433
2362
|
}
|
|
2434
|
-
function createConfigManagement(context) {
|
|
2435
|
-
const { logger, error } = context;
|
|
2436
|
-
return {
|
|
2437
|
-
loadConfig: async ()=>{
|
|
2438
|
-
logger.debug('Attempting to load configuration...');
|
|
2439
|
-
try {
|
|
2440
|
-
const configResult = await getConfig(context);
|
|
2441
|
-
const config = configResult ?? null;
|
|
2442
|
-
logger.debug('Config loading result:', config);
|
|
2443
|
-
if (config) logger.debug('Configuration loaded successfully.');
|
|
2444
|
-
else logger.debug('No configuration found.');
|
|
2445
|
-
return config;
|
|
2446
|
-
} catch (err) {
|
|
2447
|
-
return error.handleError(err, 'Error loading configuration');
|
|
2448
|
-
}
|
|
2449
|
-
},
|
|
2450
|
-
requireConfig: async ()=>{
|
|
2451
|
-
const config = await context.config.loadConfig();
|
|
2452
|
-
if (!config) return error.handleError(new Error('Configuration required but not found'), 'Missing required configuration');
|
|
2453
|
-
return config;
|
|
2454
|
-
},
|
|
2455
|
-
getPathAliases: (configDir)=>{
|
|
2456
|
-
const cwd = configDir || context.cwd;
|
|
2457
|
-
const tsConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cwd, 'tsconfig.json');
|
|
2458
|
-
const jsConfigPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cwd, 'jsconfig.json');
|
|
2459
|
-
const configPath = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(tsConfigPath) ? tsConfigPath : __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(jsConfigPath) ? jsConfigPath : null;
|
|
2460
|
-
if (!configPath) return null;
|
|
2461
|
-
try {
|
|
2462
|
-
return extractAliasesFromConfigFile(context, configPath, cwd);
|
|
2463
|
-
} catch (extractError) {
|
|
2464
|
-
logger.warn(`Error extracting path aliases from ${configPath}:`, extractError);
|
|
2465
|
-
return null;
|
|
2466
|
-
}
|
|
2467
|
-
}
|
|
2468
|
-
};
|
|
2469
|
-
}
|
|
2470
|
-
function stripJsonComments(jsonString) {
|
|
2471
|
-
return jsonString.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g)=>g ? '' : m).replace(/,(?=\s*[}\]])/g, '');
|
|
2472
|
-
}
|
|
2473
|
-
function extractAliasesFromConfigFile(context, configPath, cwd) {
|
|
2474
|
-
try {
|
|
2475
|
-
const configContent = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(configPath, 'utf8');
|
|
2476
|
-
const strippedConfigContent = stripJsonComments(configContent);
|
|
2477
|
-
const config = JSON.parse(strippedConfigContent);
|
|
2478
|
-
const { paths = {}, baseUrl = '.' } = config.compilerOptions || {};
|
|
2479
|
-
const result = {};
|
|
2480
|
-
const obj = Object.entries(paths);
|
|
2481
|
-
for (const [alias, aliasPaths] of obj)for (const aliasedPath of aliasPaths){
|
|
2482
|
-
const resolvedBaseUrl = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cwd, baseUrl);
|
|
2483
|
-
const finalAlias = '*' === alias.slice(-1) ? alias.slice(0, -1) : alias;
|
|
2484
|
-
const finalAliasedPath = '*' === aliasedPath.slice(-1) ? aliasedPath.slice(0, -1) : aliasedPath;
|
|
2485
|
-
result[finalAlias || ''] = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(resolvedBaseUrl, finalAliasedPath);
|
|
2486
|
-
}
|
|
2487
|
-
if (hasSvelteKit(cwd)) addSvelteKitEnvModules(result);
|
|
2488
|
-
return result;
|
|
2489
|
-
} catch (error) {
|
|
2490
|
-
context.logger.warn(`Error parsing config file ${configPath}`, error);
|
|
2491
|
-
return null;
|
|
2492
|
-
}
|
|
2493
|
-
}
|
|
2494
|
-
function hasSvelteKit(cwd) {
|
|
2495
|
-
try {
|
|
2496
|
-
const packageJsonPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cwd, 'package.json');
|
|
2497
|
-
if (!__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].existsSync(packageJsonPath)) return false;
|
|
2498
|
-
const packageJson = JSON.parse(__WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(packageJsonPath, 'utf8'));
|
|
2499
|
-
const deps = {
|
|
2500
|
-
...packageJson.dependencies,
|
|
2501
|
-
...packageJson.devDependencies
|
|
2502
|
-
};
|
|
2503
|
-
return '@sveltejs/kit' in deps;
|
|
2504
|
-
} catch (error) {
|
|
2505
|
-
return false;
|
|
2506
|
-
}
|
|
2507
|
-
}
|
|
2508
|
-
function addSvelteKitEnvModules(aliases) {
|
|
2509
|
-
aliases['$app/'] = '$app/';
|
|
2510
|
-
aliases['$lib/'] = '$lib/';
|
|
2511
|
-
aliases['$env/'] = '$env/';
|
|
2512
|
-
aliases['$service-worker'] = '$service-worker';
|
|
2513
|
-
}
|
|
2514
2363
|
function createErrorHandlers(context) {
|
|
2515
2364
|
const { logger, telemetry } = context;
|
|
2516
2365
|
return {
|
|
@@ -2737,7 +2586,7 @@ function createUserInteraction(context) {
|
|
|
2737
2586
|
}
|
|
2738
2587
|
async function createCliContext(rawArgs, cwd, commands) {
|
|
2739
2588
|
const { commandName, commandArgs, parsedFlags } = parseCliArgs(rawArgs, commands);
|
|
2740
|
-
let desiredLogLevel = '
|
|
2589
|
+
let desiredLogLevel = 'debug';
|
|
2741
2590
|
const levelArg = parsedFlags.logger;
|
|
2742
2591
|
if ('string' == typeof levelArg) if (validLogLevels.includes(levelArg)) desiredLogLevel = levelArg;
|
|
2743
2592
|
else console.warn(`[CLI Setup] Invalid log level '${levelArg}' provided via --logger. Using default 'info'.`);
|
|
@@ -2755,11 +2604,10 @@ async function createCliContext(rawArgs, cwd, commands) {
|
|
|
2755
2604
|
context.error = createErrorHandlers(context);
|
|
2756
2605
|
const userInteraction = createUserInteraction(context);
|
|
2757
2606
|
context.confirm = userInteraction.confirm;
|
|
2758
|
-
context.config = createConfigManagement(context);
|
|
2759
2607
|
context.fs = createFileSystem(context);
|
|
2760
|
-
|
|
2761
|
-
context.framework = await detectFramework(projectRoot, logger);
|
|
2762
|
-
context.packageManager = await detectPackageManager(projectRoot, logger);
|
|
2608
|
+
context.projectRoot = await detectProjectRoot(cwd, logger);
|
|
2609
|
+
context.framework = await detectFramework(context.projectRoot, logger);
|
|
2610
|
+
context.packageManager = await detectPackageManager(context.projectRoot, logger);
|
|
2763
2611
|
const telemetryDisabled = true === parsedFlags['no-telemetry'];
|
|
2764
2612
|
const telemetryDebug = true === parsedFlags['telemetry-debug'];
|
|
2765
2613
|
try {
|
|
@@ -2794,17 +2642,17 @@ async function createCliContext(rawArgs, cwd, commands) {
|
|
|
2794
2642
|
const src_commands = [
|
|
2795
2643
|
{
|
|
2796
2644
|
name: 'generate',
|
|
2797
|
-
label: '
|
|
2798
|
-
hint: '
|
|
2799
|
-
description: '
|
|
2645
|
+
label: 'Generate (Recommended)',
|
|
2646
|
+
hint: 'Add c15t to your project',
|
|
2647
|
+
description: 'Setup your c15t project',
|
|
2800
2648
|
action: (context)=>generate(context)
|
|
2801
2649
|
},
|
|
2802
2650
|
{
|
|
2803
|
-
name: '
|
|
2804
|
-
label: '
|
|
2805
|
-
hint: '
|
|
2806
|
-
description: '
|
|
2807
|
-
action: (context)=>
|
|
2651
|
+
name: 'self-host',
|
|
2652
|
+
label: 'Self Host',
|
|
2653
|
+
hint: 'Host c15t backend on your own infra',
|
|
2654
|
+
description: 'Commands for self-hosting c15t (generate, migrate).',
|
|
2655
|
+
action: (context)=>selfHost(context)
|
|
2808
2656
|
},
|
|
2809
2657
|
{
|
|
2810
2658
|
name: 'github',
|
|
@@ -2878,34 +2726,6 @@ flag or set ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan('C15T_TELEM
|
|
|
2878
2726
|
await displayIntro(context, version);
|
|
2879
2727
|
logger.debug(`Current working directory: ${cwd}`);
|
|
2880
2728
|
logger.debug(`Config path flag: ${flags.config}`);
|
|
2881
|
-
let clientConfig;
|
|
2882
|
-
let backendConfig;
|
|
2883
|
-
try {
|
|
2884
|
-
const loadedConfig = await getConfig(context);
|
|
2885
|
-
if (loadedConfig) if (isClientOptions(loadedConfig)) clientConfig = loadedConfig;
|
|
2886
|
-
else if (isC15TOptions(loadedConfig)) backendConfig = loadedConfig;
|
|
2887
|
-
else logger.warn('Loaded configuration is of an unknown type.');
|
|
2888
|
-
if (loadedConfig) telemetry.trackEvent(TelemetryEventName.CONFIG_LOADED, {
|
|
2889
|
-
configType: clientConfig ? 'client' : backendConfig ? 'backend' : 'unknown',
|
|
2890
|
-
hasBackend: Boolean(backendConfig)
|
|
2891
|
-
});
|
|
2892
|
-
} catch (loadError) {
|
|
2893
|
-
telemetry.trackEvent(TelemetryEventName.CONFIG_ERROR, {
|
|
2894
|
-
error: loadError instanceof Error ? loadError.message : String(loadError)
|
|
2895
|
-
});
|
|
2896
|
-
return error.handleError(loadError, 'An unexpected error occurred during configuration loading');
|
|
2897
|
-
}
|
|
2898
|
-
if (!clientConfig) {
|
|
2899
|
-
telemetry.trackEvent(TelemetryEventName.ONBOARDING_STARTED, {});
|
|
2900
|
-
await startOnboarding(context);
|
|
2901
|
-
await telemetry.shutdown();
|
|
2902
|
-
return;
|
|
2903
|
-
}
|
|
2904
|
-
const coloredConsentIo = __WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyanBright('consent.io');
|
|
2905
|
-
const backendStatus = backendConfig ? 'Backend configuration loaded' : `Using ${coloredConsentIo} for your c15t deployment`;
|
|
2906
|
-
logger.info(`Client configuration successfully loaded and validated \n ${backendStatus}`);
|
|
2907
|
-
logger.debug('Client config details:', clientConfig);
|
|
2908
|
-
if (backendConfig) logger.debug('Backend config details:', backendConfig);
|
|
2909
2729
|
try {
|
|
2910
2730
|
if (commandName) {
|
|
2911
2731
|
const command = src_commands.find((cmd)=>cmd.name === commandName);
|