@geekmidas/cli 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CronGenerator-BPTqNYOR.d.cts +14 -0
- package/dist/{CronGenerator-Bh26MaNA.mjs → CronGenerator-CCRYptuT.mjs} +2 -2
- package/dist/{CronGenerator-Bh26MaNA.mjs.map → CronGenerator-CCRYptuT.mjs.map} +1 -1
- package/dist/{CronGenerator-C6MF8rlG.cjs → CronGenerator-D4TWXQbh.cjs} +2 -2
- package/dist/{CronGenerator-C6MF8rlG.cjs.map → CronGenerator-D4TWXQbh.cjs.map} +1 -1
- package/dist/CronGenerator-YAj59JUd.d.mts +14 -0
- package/dist/EndpointGenerator-ChAD1INz.d.cts +19 -0
- package/dist/EndpointGenerator-Cj3O1U8-.d.mts +19 -0
- package/dist/{EndpointGenerator-CzDhG7Or.mjs → EndpointGenerator-DGivkPLT.mjs} +22 -6
- package/dist/EndpointGenerator-DGivkPLT.mjs.map +1 -0
- package/dist/{EndpointGenerator-BxNCkus4.cjs → EndpointGenerator-npWEDoK2.cjs} +22 -6
- package/dist/EndpointGenerator-npWEDoK2.cjs.map +1 -0
- package/dist/FunctionGenerator-429-9NER.d.cts +14 -0
- package/dist/FunctionGenerator-BQ4ehoID.d.mts +14 -0
- package/dist/{FunctionGenerator-BNE_GC7N.mjs → FunctionGenerator-CVk0h8tO.mjs} +2 -2
- package/dist/{FunctionGenerator-BNE_GC7N.mjs.map → FunctionGenerator-CVk0h8tO.mjs.map} +1 -1
- package/dist/{FunctionGenerator-FgZUTd8L.cjs → FunctionGenerator-DYTnyr4c.cjs} +2 -2
- package/dist/{FunctionGenerator-FgZUTd8L.cjs.map → FunctionGenerator-DYTnyr4c.cjs.map} +1 -1
- package/dist/Generator-BjHK_qce.d.mts +27 -0
- package/dist/{Generator-UanJW0_V.mjs → Generator-CDt4pB3W.mjs} +1 -1
- package/dist/{Generator-UanJW0_V.mjs.map → Generator-CDt4pB3W.mjs.map} +1 -1
- package/dist/{Generator-CDoEXCDg.cjs → Generator-CLVplqm2.cjs} +1 -1
- package/dist/{Generator-CDoEXCDg.cjs.map → Generator-CLVplqm2.cjs.map} +1 -1
- package/dist/Generator-DxQMCQp7.d.cts +27 -0
- package/dist/{OpenApiTsGenerator-NBNEoaeO.cjs → OpenApiTsGenerator-Be-sKGTT.cjs} +1 -1
- package/dist/{OpenApiTsGenerator-NBNEoaeO.cjs.map → OpenApiTsGenerator-Be-sKGTT.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-q3aWNkuM.mjs → OpenApiTsGenerator-C4mHHaku.mjs} +1 -1
- package/dist/{OpenApiTsGenerator-q3aWNkuM.mjs.map → OpenApiTsGenerator-C4mHHaku.mjs.map} +1 -1
- package/dist/SubscriberGenerator-7uX42xyG.d.mts +15 -0
- package/dist/{SubscriberGenerator-Dnlj_1FK.mjs → SubscriberGenerator-DABaJXML.mjs} +2 -2
- package/dist/{SubscriberGenerator-Dnlj_1FK.mjs.map → SubscriberGenerator-DABaJXML.mjs.map} +1 -1
- package/dist/{SubscriberGenerator-Bd-a7aiw.cjs → SubscriberGenerator-D_zpNGFr.cjs} +2 -2
- package/dist/{SubscriberGenerator-Bd-a7aiw.cjs.map → SubscriberGenerator-D_zpNGFr.cjs.map} +1 -1
- package/dist/SubscriberGenerator-Dtb3HS4i.d.cts +15 -0
- package/dist/api-B3SCEHPf.cjs +190 -0
- package/dist/api-B3SCEHPf.cjs.map +1 -0
- package/dist/api-BKIN0s0S.mjs +184 -0
- package/dist/api-BKIN0s0S.mjs.map +1 -0
- package/dist/build/index.cjs +11 -10
- package/dist/build/index.d.cts +7 -0
- package/dist/build/index.d.mts +7 -0
- package/dist/build/index.mjs +11 -10
- package/dist/build/manifests.cjs +1 -1
- package/dist/build/manifests.d.cts +13 -0
- package/dist/build/manifests.d.mts +13 -0
- package/dist/build/manifests.mjs +1 -1
- package/dist/build/providerResolver.cjs +1 -1
- package/dist/build/providerResolver.d.cts +23 -0
- package/dist/build/providerResolver.d.mts +23 -0
- package/dist/build/providerResolver.mjs +1 -1
- package/dist/build/types.d.cts +3 -0
- package/dist/build/types.d.mts +3 -0
- package/dist/{build-DyDgu_D1.mjs → build-B8C_qHir.mjs} +15 -13
- package/dist/build-B8C_qHir.mjs.map +1 -0
- package/dist/{build-CWtHnJMQ.cjs → build-D0Wr49bf.cjs} +15 -13
- package/dist/build-D0Wr49bf.cjs.map +1 -0
- package/dist/config-Ba-Gbpbc.d.cts +11 -0
- package/dist/config-Bq72aj8e.mjs +75 -0
- package/dist/config-Bq72aj8e.mjs.map +1 -0
- package/dist/config-CFls09Ey.cjs +93 -0
- package/dist/config-CFls09Ey.cjs.map +1 -0
- package/dist/config-CLEDqKO3.cjs +157 -0
- package/dist/config-CLEDqKO3.cjs.map +1 -0
- package/dist/config-DBsmMDhf.d.mts +11 -0
- package/dist/config-Dp8RonV_.mjs +151 -0
- package/dist/config-Dp8RonV_.mjs.map +1 -0
- package/dist/config.cjs +4 -2
- package/dist/config.d.cts +48 -0
- package/dist/config.d.mts +48 -0
- package/dist/config.mjs +2 -2
- package/dist/dev/index.cjs +10 -9
- package/dist/dev/index.d.cts +36 -0
- package/dist/dev/index.d.mts +36 -0
- package/dist/dev/index.mjs +10 -10
- package/dist/{dev-CpA8AQPX.mjs → dev-B734w3L1.mjs} +93 -49
- package/dist/dev-B734w3L1.mjs.map +1 -0
- package/dist/{dev-CgDYC4o8.cjs → dev-DHqYn8k4.cjs} +71 -21
- package/dist/dev-DHqYn8k4.cjs.map +1 -0
- package/dist/docker-5d8Yh5_X.cjs +119 -0
- package/dist/docker-5d8Yh5_X.cjs.map +1 -0
- package/dist/docker-DlUqdFle.mjs +113 -0
- package/dist/docker-DlUqdFle.mjs.map +1 -0
- package/dist/env-B-OKjgI4.cjs +144 -0
- package/dist/env-B-OKjgI4.cjs.map +1 -0
- package/dist/env-HfuJRlg5.d.cts +11 -0
- package/dist/env-nd-iQPYM.d.mts +11 -0
- package/dist/env-tv1HlZlw.mjs +138 -0
- package/dist/env-tv1HlZlw.mjs.map +1 -0
- package/dist/generators/CronGenerator.cjs +2 -2
- package/dist/generators/CronGenerator.d.cts +5 -0
- package/dist/generators/CronGenerator.d.mts +5 -0
- package/dist/generators/CronGenerator.mjs +2 -2
- package/dist/generators/EndpointGenerator.cjs +2 -2
- package/dist/generators/EndpointGenerator.d.cts +5 -0
- package/dist/generators/EndpointGenerator.d.mts +5 -0
- package/dist/generators/EndpointGenerator.mjs +2 -2
- package/dist/generators/FunctionGenerator.cjs +2 -2
- package/dist/generators/FunctionGenerator.d.cts +5 -0
- package/dist/generators/FunctionGenerator.d.mts +5 -0
- package/dist/generators/FunctionGenerator.mjs +2 -2
- package/dist/generators/Generator.cjs +1 -1
- package/dist/generators/Generator.d.cts +4 -0
- package/dist/generators/Generator.d.mts +4 -0
- package/dist/generators/Generator.mjs +1 -1
- package/dist/generators/OpenApiTsGenerator.cjs +1 -1
- package/dist/generators/OpenApiTsGenerator.d.cts +44 -0
- package/dist/generators/OpenApiTsGenerator.d.mts +44 -0
- package/dist/generators/OpenApiTsGenerator.mjs +1 -1
- package/dist/generators/SubscriberGenerator.cjs +2 -2
- package/dist/generators/SubscriberGenerator.d.cts +5 -0
- package/dist/generators/SubscriberGenerator.d.mts +5 -0
- package/dist/generators/SubscriberGenerator.mjs +2 -2
- package/dist/generators/index.cjs +6 -6
- package/dist/generators/index.d.cts +8 -0
- package/dist/generators/index.d.mts +8 -0
- package/dist/generators/index.mjs +6 -6
- package/dist/index-C523No_B.d.mts +64 -0
- package/dist/index-DrzN4xkQ.d.cts +64 -0
- package/dist/index.cjs +48 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +48 -16
- package/dist/index.mjs.map +1 -1
- package/dist/init/generators/config.cjs +3 -0
- package/dist/init/generators/config.d.cts +3 -0
- package/dist/init/generators/config.d.mts +3 -0
- package/dist/init/generators/config.mjs +3 -0
- package/dist/init/generators/docker.cjs +3 -0
- package/dist/init/generators/docker.d.cts +11 -0
- package/dist/init/generators/docker.d.mts +11 -0
- package/dist/init/generators/docker.mjs +3 -0
- package/dist/init/generators/env.cjs +3 -0
- package/dist/init/generators/env.d.cts +3 -0
- package/dist/init/generators/env.d.mts +3 -0
- package/dist/init/generators/env.mjs +3 -0
- package/dist/init/generators/index.cjs +9 -0
- package/dist/init/generators/index.d.cts +6 -0
- package/dist/init/generators/index.d.mts +6 -0
- package/dist/init/generators/index.mjs +6 -0
- package/dist/init/generators/models.cjs +3 -0
- package/dist/init/generators/models.d.cts +11 -0
- package/dist/init/generators/models.d.mts +11 -0
- package/dist/init/generators/models.mjs +3 -0
- package/dist/init/generators/monorepo.cjs +3 -0
- package/dist/init/generators/monorepo.d.cts +11 -0
- package/dist/init/generators/monorepo.d.mts +11 -0
- package/dist/init/generators/monorepo.mjs +3 -0
- package/dist/init/generators/package.cjs +3 -0
- package/dist/init/generators/package.d.cts +3 -0
- package/dist/init/generators/package.d.mts +3 -0
- package/dist/init/generators/package.mjs +3 -0
- package/dist/init/generators/source.cjs +3 -0
- package/dist/init/generators/source.d.cts +3 -0
- package/dist/init/generators/source.d.mts +3 -0
- package/dist/init/generators/source.mjs +3 -0
- package/dist/init/index.cjs +16 -0
- package/dist/init/index.d.cts +17 -0
- package/dist/init/index.d.mts +17 -0
- package/dist/init/index.mjs +16 -0
- package/dist/init/templates/api.cjs +3 -0
- package/dist/init/templates/api.d.cts +7 -0
- package/dist/init/templates/api.d.mts +7 -0
- package/dist/init/templates/api.mjs +3 -0
- package/dist/init/templates/index.cjs +10 -0
- package/dist/init/templates/index.d.cts +2 -0
- package/dist/init/templates/index.d.mts +2 -0
- package/dist/init/templates/index.mjs +7 -0
- package/dist/init/templates/minimal.cjs +3 -0
- package/dist/init/templates/minimal.d.cts +7 -0
- package/dist/init/templates/minimal.d.mts +7 -0
- package/dist/init/templates/minimal.mjs +3 -0
- package/dist/init/templates/serverless.cjs +3 -0
- package/dist/init/templates/serverless.d.cts +7 -0
- package/dist/init/templates/serverless.d.mts +7 -0
- package/dist/init/templates/serverless.mjs +3 -0
- package/dist/init/templates/worker.cjs +3 -0
- package/dist/init/templates/worker.d.cts +7 -0
- package/dist/init/templates/worker.d.mts +7 -0
- package/dist/init/templates/worker.mjs +3 -0
- package/dist/init/utils.cjs +7 -0
- package/dist/init/utils.d.cts +25 -0
- package/dist/init/utils.d.mts +25 -0
- package/dist/init/utils.mjs +3 -0
- package/dist/init-CtOnZn3G.mjs +145 -0
- package/dist/init-CtOnZn3G.mjs.map +1 -0
- package/dist/init-qLFsWR-R.cjs +151 -0
- package/dist/init-qLFsWR-R.cjs.map +1 -0
- package/dist/{manifests-C2eMoMUm.mjs → manifests-DIA_2QYd.mjs} +1 -1
- package/dist/{manifests-C2eMoMUm.mjs.map → manifests-DIA_2QYd.mjs.map} +1 -1
- package/dist/{manifests-CK1VV_pM.cjs → manifests-VJ9-2JpW.cjs} +1 -1
- package/dist/{manifests-CK1VV_pM.cjs.map → manifests-VJ9-2JpW.cjs.map} +1 -1
- package/dist/minimal-Bdhhpp7v.cjs +93 -0
- package/dist/minimal-Bdhhpp7v.cjs.map +1 -0
- package/dist/minimal-C4GsE45s.mjs +87 -0
- package/dist/minimal-C4GsE45s.mjs.map +1 -0
- package/dist/models-DyNwdOcz.cjs +121 -0
- package/dist/models-DyNwdOcz.cjs.map +1 -0
- package/dist/models-cvNg6Oea.mjs +115 -0
- package/dist/models-cvNg6Oea.mjs.map +1 -0
- package/dist/monorepo-Cknwzj5C.mjs +184 -0
- package/dist/monorepo-Cknwzj5C.mjs.map +1 -0
- package/dist/monorepo-sEK8gW59.cjs +190 -0
- package/dist/monorepo-sEK8gW59.cjs.map +1 -0
- package/dist/{openapi-DhK4b0lB.cjs → openapi-BQWPWyNB.cjs} +4 -4
- package/dist/{openapi-DhK4b0lB.cjs.map → openapi-BQWPWyNB.cjs.map} +1 -1
- package/dist/{openapi-DRTRGhTt.mjs → openapi-DBX8cJJ8.mjs} +4 -4
- package/dist/{openapi-DRTRGhTt.mjs.map → openapi-DBX8cJJ8.mjs.map} +1 -1
- package/dist/{openapi-react-query-D9Z7lh0p.cjs → openapi-react-query-DxHjXQvg.cjs} +1 -1
- package/dist/{openapi-react-query-D9Z7lh0p.cjs.map → openapi-react-query-DxHjXQvg.cjs.map} +1 -1
- package/dist/{openapi-react-query-MEBlYIM1.mjs → openapi-react-query-o7Mp1Jd5.mjs} +1 -1
- package/dist/{openapi-react-query-MEBlYIM1.mjs.map → openapi-react-query-o7Mp1Jd5.mjs.map} +1 -1
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.d.cts +11 -0
- package/dist/openapi-react-query.d.mts +11 -0
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +5 -5
- package/dist/openapi.d.cts +11 -0
- package/dist/openapi.d.mts +11 -0
- package/dist/openapi.mjs +5 -5
- package/dist/package-C7WhWU8m.d.mts +11 -0
- package/dist/package-CIfmeuSW.mjs +51 -0
- package/dist/package-CIfmeuSW.mjs.map +1 -0
- package/dist/package-DvWEMz6z.d.cts +11 -0
- package/dist/package-PP-o1nvq.cjs +57 -0
- package/dist/package-PP-o1nvq.cjs.map +1 -0
- package/dist/{providerResolver-B_TjNF0_.mjs → providerResolver-DEVKngbC.mjs} +1 -1
- package/dist/{providerResolver-B_TjNF0_.mjs.map → providerResolver-DEVKngbC.mjs.map} +1 -1
- package/dist/{providerResolver-DgvzNfP4.cjs → providerResolver-DOTbN9jo.cjs} +1 -1
- package/dist/{providerResolver-DgvzNfP4.cjs.map → providerResolver-DOTbN9jo.cjs.map} +1 -1
- package/dist/serverless-DkHBF2vC.mjs +108 -0
- package/dist/serverless-DkHBF2vC.mjs.map +1 -0
- package/dist/serverless-Yav3GRVz.cjs +114 -0
- package/dist/serverless-Yav3GRVz.cjs.map +1 -0
- package/dist/source-D6v2BnKT.d.mts +11 -0
- package/dist/source-D8fK9qRo.d.cts +11 -0
- package/dist/source-DT5Xhiob.cjs +17 -0
- package/dist/source-DT5Xhiob.cjs.map +1 -0
- package/dist/source-DnaH_MLA.mjs +11 -0
- package/dist/source-DnaH_MLA.mjs.map +1 -0
- package/dist/templates-CBFUwpBy.mjs +64 -0
- package/dist/templates-CBFUwpBy.mjs.map +1 -0
- package/dist/templates-DM_rtYYW.cjs +87 -0
- package/dist/templates-DM_rtYYW.cjs.map +1 -0
- package/dist/types-C4KITv-y.d.mts +51 -0
- package/dist/types-Cxl8-uwV.d.mts +129 -0
- package/dist/types-DB99_qIy.d.cts +129 -0
- package/dist/types-DLFN49M3.d.cts +51 -0
- package/dist/types.d.cts +2 -0
- package/dist/types.d.mts +2 -0
- package/dist/utils-BX3F4fT8.cjs +99 -0
- package/dist/utils-BX3F4fT8.cjs.map +1 -0
- package/dist/utils-C31-SWHP.mjs +69 -0
- package/dist/utils-C31-SWHP.mjs.map +1 -0
- package/dist/worker--8O5a3Hv.cjs +150 -0
- package/dist/worker--8O5a3Hv.cjs.map +1 -0
- package/dist/worker-Jme7uOOJ.mjs +144 -0
- package/dist/worker-Jme7uOOJ.mjs.map +1 -0
- package/package.json +11 -3
- package/src/__tests__/loadEnvFiles.spec.ts +131 -0
- package/src/build/index.ts +14 -16
- package/src/build/types.ts +5 -0
- package/src/config.ts +57 -0
- package/src/dev/index.ts +77 -17
- package/src/generators/EndpointGenerator.ts +37 -8
- package/src/index.ts +26 -0
- package/src/init/__tests__/generators.spec.ts +366 -0
- package/src/init/__tests__/init.spec.ts +341 -0
- package/src/init/__tests__/utils.spec.ts +104 -0
- package/src/init/generators/config.ts +192 -0
- package/src/init/generators/docker.ts +134 -0
- package/src/init/generators/env.ts +182 -0
- package/src/init/generators/index.ts +4 -0
- package/src/init/generators/models.ts +129 -0
- package/src/init/generators/monorepo.ts +211 -0
- package/src/init/generators/package.ts +81 -0
- package/src/init/generators/source.ts +15 -0
- package/src/init/index.ts +206 -0
- package/src/init/templates/api.ts +218 -0
- package/src/init/templates/index.ts +108 -0
- package/src/init/templates/minimal.ts +102 -0
- package/src/init/templates/serverless.ts +129 -0
- package/src/init/templates/worker.ts +169 -0
- package/src/init/utils.ts +98 -0
- package/src/types.ts +22 -2
- package/tsdown.config.ts +1 -1
- package/dist/EndpointGenerator-BxNCkus4.cjs.map +0 -1
- package/dist/EndpointGenerator-CzDhG7Or.mjs.map +0 -1
- package/dist/build-CWtHnJMQ.cjs.map +0 -1
- package/dist/build-DyDgu_D1.mjs.map +0 -1
- package/dist/config-AFmFKmU0.mjs +0 -30
- package/dist/config-AFmFKmU0.mjs.map +0 -1
- package/dist/config-BVIJpAsa.cjs +0 -36
- package/dist/config-BVIJpAsa.cjs.map +0 -1
- package/dist/dev-CgDYC4o8.cjs.map +0 -1
- package/dist/dev-CpA8AQPX.mjs.map +0 -1
- /package/dist/{generators-CEKtVh81.cjs → generators-3IemvCLk.cjs} +0 -0
- /package/dist/{generators-CsLujGXs.mjs → generators-FNpdfN6J.mjs} +0 -0
package/src/dev/index.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { type ChildProcess, spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
2
3
|
import { mkdir } from 'node:fs/promises';
|
|
3
4
|
import { createServer } from 'node:net';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
+
import { join, resolve } from 'node:path';
|
|
5
6
|
import chokidar from 'chokidar';
|
|
7
|
+
import { config as dotenvConfig } from 'dotenv';
|
|
6
8
|
import fg from 'fast-glob';
|
|
7
9
|
import { resolveProviders } from '../build/providerResolver';
|
|
8
10
|
import type { BuildContext, NormalizedTelescopeConfig } from '../build/types';
|
|
9
|
-
import { loadConfig } from '../config';
|
|
11
|
+
import { loadConfig, parseModuleConfig } from '../config';
|
|
10
12
|
import {
|
|
11
13
|
CronGenerator,
|
|
12
14
|
EndpointGenerator,
|
|
@@ -22,6 +24,39 @@ import type {
|
|
|
22
24
|
|
|
23
25
|
const logger = console;
|
|
24
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Load environment files
|
|
29
|
+
* @internal Exported for testing
|
|
30
|
+
*/
|
|
31
|
+
export function loadEnvFiles(
|
|
32
|
+
envConfig: string | string[] | undefined,
|
|
33
|
+
cwd: string = process.cwd(),
|
|
34
|
+
): { loaded: string[]; missing: string[] } {
|
|
35
|
+
const loaded: string[] = [];
|
|
36
|
+
const missing: string[] = [];
|
|
37
|
+
|
|
38
|
+
// Normalize to array
|
|
39
|
+
const envFiles = envConfig
|
|
40
|
+
? Array.isArray(envConfig)
|
|
41
|
+
? envConfig
|
|
42
|
+
: [envConfig]
|
|
43
|
+
: ['.env'];
|
|
44
|
+
|
|
45
|
+
// Load each env file in order (later files override earlier)
|
|
46
|
+
for (const envFile of envFiles) {
|
|
47
|
+
const envPath = resolve(cwd, envFile);
|
|
48
|
+
if (existsSync(envPath)) {
|
|
49
|
+
dotenvConfig({ path: envPath, override: true, quiet: true });
|
|
50
|
+
loaded.push(envFile);
|
|
51
|
+
} else if (envConfig) {
|
|
52
|
+
// Only report as missing if explicitly configured
|
|
53
|
+
missing.push(envFile);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { loaded, missing };
|
|
58
|
+
}
|
|
59
|
+
|
|
25
60
|
/**
|
|
26
61
|
* Check if a port is available
|
|
27
62
|
* @internal Exported for testing
|
|
@@ -79,6 +114,23 @@ export function normalizeTelescopeConfig(
|
|
|
79
114
|
return undefined;
|
|
80
115
|
}
|
|
81
116
|
|
|
117
|
+
// Handle string path (e.g., './src/config/telescope')
|
|
118
|
+
if (typeof config === 'string') {
|
|
119
|
+
const { path: telescopePath, importPattern: telescopeImportPattern } =
|
|
120
|
+
parseModuleConfig(config, 'telescope');
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
enabled: true,
|
|
124
|
+
telescopePath,
|
|
125
|
+
telescopeImportPattern,
|
|
126
|
+
path: '/__telescope',
|
|
127
|
+
ignore: [],
|
|
128
|
+
recordBody: true,
|
|
129
|
+
maxEntries: 1000,
|
|
130
|
+
websocket: true,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
82
134
|
// Default to enabled in development mode
|
|
83
135
|
const isEnabled =
|
|
84
136
|
config === true || config === undefined || config.enabled !== false;
|
|
@@ -106,8 +158,26 @@ export interface DevOptions {
|
|
|
106
158
|
}
|
|
107
159
|
|
|
108
160
|
export async function devCommand(options: DevOptions): Promise<void> {
|
|
161
|
+
// Load default .env file BEFORE loading config
|
|
162
|
+
// This ensures env vars are available when config and its dependencies are loaded
|
|
163
|
+
const defaultEnv = loadEnvFiles('.env');
|
|
164
|
+
if (defaultEnv.loaded.length > 0) {
|
|
165
|
+
logger.log(`📦 Loaded env: ${defaultEnv.loaded.join(', ')}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
109
168
|
const config = await loadConfig();
|
|
110
169
|
|
|
170
|
+
// Load any additional env files specified in config
|
|
171
|
+
if (config.env) {
|
|
172
|
+
const { loaded, missing } = loadEnvFiles(config.env);
|
|
173
|
+
if (loaded.length > 0) {
|
|
174
|
+
logger.log(`📦 Loaded env: ${loaded.join(', ')}`);
|
|
175
|
+
}
|
|
176
|
+
if (missing.length > 0) {
|
|
177
|
+
logger.warn(`⚠️ Missing env files: ${missing.join(', ')}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
111
181
|
// Force server provider for dev mode
|
|
112
182
|
const resolved = resolveProviders(config, { provider: 'server' });
|
|
113
183
|
|
|
@@ -124,21 +194,11 @@ export async function devCommand(options: DevOptions): Promise<void> {
|
|
|
124
194
|
}
|
|
125
195
|
logger.log(`Using envParser: ${config.envParser}`);
|
|
126
196
|
|
|
127
|
-
// Parse envParser configuration
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
? '{ envParser }'
|
|
133
|
-
: `{ ${envParserName} as envParser }`;
|
|
134
|
-
|
|
135
|
-
// Parse logger configuration
|
|
136
|
-
const [loggerPath, loggerName] = config.logger.split('#');
|
|
137
|
-
const loggerImportPattern = !loggerName
|
|
138
|
-
? 'logger'
|
|
139
|
-
: loggerName === 'logger'
|
|
140
|
-
? '{ logger }'
|
|
141
|
-
: `{ ${loggerName} as logger }`;
|
|
197
|
+
// Parse envParser and logger configuration
|
|
198
|
+
const { path: envParserPath, importPattern: envParserImportPattern } =
|
|
199
|
+
parseModuleConfig(config.envParser, 'envParser');
|
|
200
|
+
const { path: loggerPath, importPattern: loggerImportPattern } =
|
|
201
|
+
parseModuleConfig(config.logger, 'logger');
|
|
142
202
|
|
|
143
203
|
// Normalize telescope configuration
|
|
144
204
|
const telescope = normalizeTelescopeConfig(config.telescope);
|
|
@@ -336,10 +336,23 @@ export function setupEndpoints(
|
|
|
336
336
|
// Generate telescope imports and setup if enabled
|
|
337
337
|
const telescopeEnabled = context.telescope?.enabled;
|
|
338
338
|
const telescopeWebSocketEnabled = context.telescope?.websocket;
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
339
|
+
const usesExternalTelescope = !!context.telescope?.telescopePath;
|
|
340
|
+
|
|
341
|
+
// Generate imports based on whether telescope is external or inline
|
|
342
|
+
let telescopeImports = '';
|
|
343
|
+
if (telescopeEnabled) {
|
|
344
|
+
if (usesExternalTelescope) {
|
|
345
|
+
const relativeTelescopePath = relative(
|
|
346
|
+
dirname(appPath),
|
|
347
|
+
context.telescope!.telescopePath!,
|
|
348
|
+
);
|
|
349
|
+
telescopeImports = `import ${context.telescope!.telescopeImportPattern} from '${relativeTelescopePath}';
|
|
350
|
+
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
351
|
+
} else {
|
|
352
|
+
telescopeImports = `import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
353
|
+
import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
343
356
|
|
|
344
357
|
const telescopeWebSocketSetupCode = telescopeWebSocketEnabled
|
|
345
358
|
? `
|
|
@@ -375,8 +388,23 @@ import { createMiddleware, createUI } from '@geekmidas/telescope/hono';`
|
|
|
375
388
|
`
|
|
376
389
|
: '';
|
|
377
390
|
|
|
378
|
-
|
|
379
|
-
|
|
391
|
+
// Generate telescope setup - either use external instance or create inline
|
|
392
|
+
let telescopeSetup = '';
|
|
393
|
+
if (telescopeEnabled) {
|
|
394
|
+
if (usesExternalTelescope) {
|
|
395
|
+
// Use external telescope instance - no need to create one
|
|
396
|
+
telescopeSetup = `
|
|
397
|
+
${telescopeWebSocketSetupCode}
|
|
398
|
+
// Add telescope middleware (before endpoints to capture all requests)
|
|
399
|
+
honoApp.use('*', createMiddleware(telescope));
|
|
400
|
+
|
|
401
|
+
// Mount telescope UI
|
|
402
|
+
const telescopeUI = createUI(telescope);
|
|
403
|
+
honoApp.route('${context.telescope!.path}', telescopeUI);
|
|
404
|
+
`;
|
|
405
|
+
} else {
|
|
406
|
+
// Create inline telescope instance
|
|
407
|
+
telescopeSetup = `
|
|
380
408
|
// Setup Telescope for debugging/monitoring
|
|
381
409
|
const telescopeStorage = new InMemoryStorage({ maxEntries: ${context.telescope!.maxEntries} });
|
|
382
410
|
const telescope = new Telescope({
|
|
@@ -393,8 +421,9 @@ ${telescopeWebSocketSetupCode}
|
|
|
393
421
|
// Mount telescope UI
|
|
394
422
|
const telescopeUI = createUI(telescope);
|
|
395
423
|
honoApp.route('${context.telescope!.path}', telescopeUI);
|
|
396
|
-
|
|
397
|
-
|
|
424
|
+
`;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
398
427
|
|
|
399
428
|
const content = `/**
|
|
400
429
|
* Generated server application
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Command } from 'commander';
|
|
|
4
4
|
import pkg from '../package.json' assert { type: 'json' };
|
|
5
5
|
import { buildCommand } from './build/index.ts';
|
|
6
6
|
import { devCommand } from './dev/index.ts';
|
|
7
|
+
import { type InitOptions, initCommand } from './init/index.ts';
|
|
7
8
|
import { generateReactQueryCommand } from './openapi-react-query.ts';
|
|
8
9
|
import { openapiCommand } from './openapi.ts';
|
|
9
10
|
import type { LegacyProvider, MainProvider } from './types.ts';
|
|
@@ -16,6 +17,31 @@ program
|
|
|
16
17
|
.version(pkg.version)
|
|
17
18
|
.option('--cwd <path>', 'Change working directory');
|
|
18
19
|
|
|
20
|
+
program
|
|
21
|
+
.command('init')
|
|
22
|
+
.description('Scaffold a new project')
|
|
23
|
+
.argument('[name]', 'Project name')
|
|
24
|
+
.option(
|
|
25
|
+
'--template <template>',
|
|
26
|
+
'Project template (minimal, api, serverless, worker)',
|
|
27
|
+
)
|
|
28
|
+
.option('--skip-install', 'Skip dependency installation', false)
|
|
29
|
+
.option('-y, --yes', 'Skip prompts, use defaults', false)
|
|
30
|
+
.option('--monorepo', 'Setup as monorepo with packages/models', false)
|
|
31
|
+
.option('--api-path <path>', 'API app path in monorepo (default: apps/api)')
|
|
32
|
+
.action(async (name: string | undefined, options: InitOptions) => {
|
|
33
|
+
try {
|
|
34
|
+
const globalOptions = program.opts();
|
|
35
|
+
if (globalOptions.cwd) {
|
|
36
|
+
process.chdir(globalOptions.cwd);
|
|
37
|
+
}
|
|
38
|
+
await initCommand(name, options);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('Init failed:', (error as Error).message);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
19
45
|
program
|
|
20
46
|
.command('build')
|
|
21
47
|
.description('Build handlers from endpoints, functions, and crons')
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { generateConfigFiles } from '../generators/config.js';
|
|
3
|
+
import { generateDockerFiles } from '../generators/docker.js';
|
|
4
|
+
import { generateEnvFiles } from '../generators/env.js';
|
|
5
|
+
import { generateModelsPackage } from '../generators/models.js';
|
|
6
|
+
import { generateMonorepoFiles } from '../generators/monorepo.js';
|
|
7
|
+
import { generatePackageJson } from '../generators/package.js';
|
|
8
|
+
import type { TemplateOptions } from '../templates/index.js';
|
|
9
|
+
import { minimalTemplate } from '../templates/minimal.js';
|
|
10
|
+
import { serverlessTemplate } from '../templates/serverless.js';
|
|
11
|
+
import { workerTemplate } from '../templates/worker.js';
|
|
12
|
+
|
|
13
|
+
const baseOptions: TemplateOptions = {
|
|
14
|
+
name: 'test-project',
|
|
15
|
+
template: 'minimal',
|
|
16
|
+
telescope: true,
|
|
17
|
+
database: true,
|
|
18
|
+
routeStyle: 'file-based',
|
|
19
|
+
monorepo: false,
|
|
20
|
+
apiPath: '',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
describe('generatePackageJson', () => {
|
|
24
|
+
it('should generate package.json with correct name', () => {
|
|
25
|
+
const files = generatePackageJson(baseOptions, minimalTemplate);
|
|
26
|
+
expect(files).toHaveLength(1);
|
|
27
|
+
expect(files[0].path).toBe('package.json');
|
|
28
|
+
|
|
29
|
+
const pkg = JSON.parse(files[0].content);
|
|
30
|
+
expect(pkg.name).toBe('test-project');
|
|
31
|
+
expect(pkg.type).toBe('module');
|
|
32
|
+
expect(pkg.private).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should include telescope when enabled', () => {
|
|
36
|
+
const files = generatePackageJson(baseOptions, minimalTemplate);
|
|
37
|
+
const pkg = JSON.parse(files[0].content);
|
|
38
|
+
expect(pkg.dependencies['@geekmidas/telescope']).toBe('workspace:*');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should include database dependencies when enabled', () => {
|
|
42
|
+
const files = generatePackageJson(baseOptions, minimalTemplate);
|
|
43
|
+
const pkg = JSON.parse(files[0].content);
|
|
44
|
+
expect(pkg.dependencies['@geekmidas/db']).toBe('workspace:*');
|
|
45
|
+
expect(pkg.dependencies['kysely']).toBeDefined();
|
|
46
|
+
expect(pkg.dependencies['pg']).toBeDefined();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should exclude telescope when disabled', () => {
|
|
50
|
+
const options = { ...baseOptions, telescope: false };
|
|
51
|
+
const files = generatePackageJson(options, minimalTemplate);
|
|
52
|
+
const pkg = JSON.parse(files[0].content);
|
|
53
|
+
expect(pkg.dependencies['@geekmidas/telescope']).toBeUndefined();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should use workspace:* for @geekmidas packages', () => {
|
|
57
|
+
const files = generatePackageJson(baseOptions, minimalTemplate);
|
|
58
|
+
const pkg = JSON.parse(files[0].content);
|
|
59
|
+
expect(pkg.dependencies['@geekmidas/constructs']).toBe('workspace:*');
|
|
60
|
+
expect(pkg.dependencies['@geekmidas/envkit']).toBe('workspace:*');
|
|
61
|
+
expect(pkg.dependencies['@geekmidas/logger']).toBe('workspace:*');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should use tilde versions for external packages', () => {
|
|
65
|
+
const files = generatePackageJson(baseOptions, minimalTemplate);
|
|
66
|
+
const pkg = JSON.parse(files[0].content);
|
|
67
|
+
expect(pkg.dependencies['hono']).toMatch(/^~/);
|
|
68
|
+
expect(pkg.dependencies['pino']).toMatch(/^~/);
|
|
69
|
+
expect(pkg.devDependencies['typescript']).toMatch(/^~/);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should include biome and turbo for non-monorepo', () => {
|
|
73
|
+
const files = generatePackageJson(baseOptions, minimalTemplate);
|
|
74
|
+
const pkg = JSON.parse(files[0].content);
|
|
75
|
+
expect(pkg.devDependencies['@biomejs/biome']).toBeDefined();
|
|
76
|
+
expect(pkg.devDependencies['turbo']).toBeDefined();
|
|
77
|
+
expect(pkg.scripts['lint']).toBeDefined();
|
|
78
|
+
expect(pkg.scripts['fmt']).toBeDefined();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should exclude biome and turbo for monorepo apps', () => {
|
|
82
|
+
const options: TemplateOptions = {
|
|
83
|
+
...baseOptions,
|
|
84
|
+
monorepo: true,
|
|
85
|
+
apiPath: 'apps/api',
|
|
86
|
+
};
|
|
87
|
+
const files = generatePackageJson(options, minimalTemplate);
|
|
88
|
+
const pkg = JSON.parse(files[0].content);
|
|
89
|
+
expect(pkg.devDependencies['@biomejs/biome']).toBeUndefined();
|
|
90
|
+
expect(pkg.devDependencies['turbo']).toBeUndefined();
|
|
91
|
+
expect(pkg.scripts['lint']).toBeUndefined();
|
|
92
|
+
expect(pkg.scripts['fmt']).toBeUndefined();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should include models package for monorepo apps', () => {
|
|
96
|
+
const options: TemplateOptions = {
|
|
97
|
+
...baseOptions,
|
|
98
|
+
monorepo: true,
|
|
99
|
+
apiPath: 'apps/api',
|
|
100
|
+
};
|
|
101
|
+
const files = generatePackageJson(options, minimalTemplate);
|
|
102
|
+
const pkg = JSON.parse(files[0].content);
|
|
103
|
+
expect(pkg.dependencies['@test-project/models']).toBe('workspace:*');
|
|
104
|
+
expect(pkg.dependencies['zod']).toBeUndefined(); // zod is in models
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should use scoped package name for monorepo apps', () => {
|
|
108
|
+
const options: TemplateOptions = {
|
|
109
|
+
...baseOptions,
|
|
110
|
+
monorepo: true,
|
|
111
|
+
apiPath: 'apps/api',
|
|
112
|
+
};
|
|
113
|
+
const files = generatePackageJson(options, minimalTemplate);
|
|
114
|
+
const pkg = JSON.parse(files[0].content);
|
|
115
|
+
expect(pkg.name).toBe('@test-project/api');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('generateConfigFiles', () => {
|
|
120
|
+
it('should generate gkm.config.ts and tsconfig.json for non-monorepo', () => {
|
|
121
|
+
const files = generateConfigFiles(baseOptions, minimalTemplate);
|
|
122
|
+
const paths = files.map((f) => f.path);
|
|
123
|
+
expect(paths).toContain('gkm.config.ts');
|
|
124
|
+
expect(paths).toContain('tsconfig.json');
|
|
125
|
+
expect(paths).toContain('biome.json');
|
|
126
|
+
expect(paths).toContain('turbo.json');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should only generate gkm.config.ts and tsconfig.json for monorepo', () => {
|
|
130
|
+
const options: TemplateOptions = {
|
|
131
|
+
...baseOptions,
|
|
132
|
+
monorepo: true,
|
|
133
|
+
apiPath: 'apps/api',
|
|
134
|
+
};
|
|
135
|
+
const files = generateConfigFiles(options, minimalTemplate);
|
|
136
|
+
const paths = files.map((f) => f.path);
|
|
137
|
+
expect(paths).toContain('gkm.config.ts');
|
|
138
|
+
expect(paths).toContain('tsconfig.json');
|
|
139
|
+
expect(paths).not.toContain('biome.json');
|
|
140
|
+
expect(paths).not.toContain('turbo.json');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should include telescope config when enabled', () => {
|
|
144
|
+
const files = generateConfigFiles(baseOptions, minimalTemplate);
|
|
145
|
+
const gkmConfig = files.find((f) => f.path === 'gkm.config.ts');
|
|
146
|
+
expect(gkmConfig?.content).toContain('telescope');
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should include functions config for serverless template', () => {
|
|
150
|
+
const options = { ...baseOptions, template: 'serverless' as const };
|
|
151
|
+
const files = generateConfigFiles(options, serverlessTemplate);
|
|
152
|
+
const gkmConfig = files.find((f) => f.path === 'gkm.config.ts');
|
|
153
|
+
expect(gkmConfig?.content).toContain('functions');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should include paths config for monorepo apps', () => {
|
|
157
|
+
const options: TemplateOptions = {
|
|
158
|
+
...baseOptions,
|
|
159
|
+
monorepo: true,
|
|
160
|
+
apiPath: 'apps/api',
|
|
161
|
+
};
|
|
162
|
+
const files = generateConfigFiles(options, minimalTemplate);
|
|
163
|
+
const tsConfig = files.find((f) => f.path === 'tsconfig.json');
|
|
164
|
+
const config = JSON.parse(tsConfig!.content);
|
|
165
|
+
expect(config.extends).toBe('../../tsconfig.json');
|
|
166
|
+
expect(config.compilerOptions.paths).toBeDefined();
|
|
167
|
+
expect(config.compilerOptions.paths['@test-project/*']).toBeDefined();
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe('generateEnvFiles', () => {
|
|
172
|
+
it('should generate all env files for non-monorepo', () => {
|
|
173
|
+
const files = generateEnvFiles(baseOptions, minimalTemplate);
|
|
174
|
+
const paths = files.map((f) => f.path);
|
|
175
|
+
expect(paths).toContain('.env');
|
|
176
|
+
expect(paths).toContain('.env.example');
|
|
177
|
+
expect(paths).toContain('.env.development');
|
|
178
|
+
expect(paths).toContain('.env.test');
|
|
179
|
+
expect(paths).toContain('.gitignore');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should not generate .gitignore for monorepo', () => {
|
|
183
|
+
const options: TemplateOptions = {
|
|
184
|
+
...baseOptions,
|
|
185
|
+
monorepo: true,
|
|
186
|
+
apiPath: 'apps/api',
|
|
187
|
+
};
|
|
188
|
+
const files = generateEnvFiles(options, minimalTemplate);
|
|
189
|
+
const paths = files.map((f) => f.path);
|
|
190
|
+
expect(paths).not.toContain('.gitignore');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should include DATABASE_URL when database is enabled', () => {
|
|
194
|
+
const files = generateEnvFiles(baseOptions, minimalTemplate);
|
|
195
|
+
const envFile = files.find((f) => f.path === '.env');
|
|
196
|
+
expect(envFile?.content).toContain('DATABASE_URL');
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should include RABBITMQ_URL for worker template', () => {
|
|
200
|
+
const options = { ...baseOptions, template: 'worker' as const };
|
|
201
|
+
const files = generateEnvFiles(options, workerTemplate);
|
|
202
|
+
const envFile = files.find((f) => f.path === '.env');
|
|
203
|
+
expect(envFile?.content).toContain('RABBITMQ_URL');
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
describe('generateDockerFiles', () => {
|
|
208
|
+
it('should generate docker-compose.yml', () => {
|
|
209
|
+
const files = generateDockerFiles(baseOptions, minimalTemplate);
|
|
210
|
+
expect(files).toHaveLength(1);
|
|
211
|
+
expect(files[0].path).toBe('docker-compose.yml');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should include postgres when database is enabled', () => {
|
|
215
|
+
const files = generateDockerFiles(baseOptions, minimalTemplate);
|
|
216
|
+
expect(files[0].content).toContain('postgres');
|
|
217
|
+
expect(files[0].content).toContain('5432');
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('should include redis', () => {
|
|
221
|
+
const files = generateDockerFiles(baseOptions, minimalTemplate);
|
|
222
|
+
expect(files[0].content).toContain('redis');
|
|
223
|
+
expect(files[0].content).toContain('6379');
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('should include serverless-redis-http for serverless template', () => {
|
|
227
|
+
const options = { ...baseOptions, template: 'serverless' as const };
|
|
228
|
+
const files = generateDockerFiles(options, serverlessTemplate);
|
|
229
|
+
expect(files[0].content).toContain('hiett/serverless-redis-http');
|
|
230
|
+
expect(files[0].content).toContain('8079');
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('should include rabbitmq for worker template', () => {
|
|
234
|
+
const options = { ...baseOptions, template: 'worker' as const };
|
|
235
|
+
const files = generateDockerFiles(options, workerTemplate);
|
|
236
|
+
expect(files[0].content).toContain('rabbitmq');
|
|
237
|
+
expect(files[0].content).toContain('5672');
|
|
238
|
+
expect(files[0].content).toContain('15672');
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('generateMonorepoFiles', () => {
|
|
243
|
+
it('should return empty array for non-monorepo', () => {
|
|
244
|
+
const files = generateMonorepoFiles(baseOptions, minimalTemplate);
|
|
245
|
+
expect(files).toHaveLength(0);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('should generate root files for monorepo', () => {
|
|
249
|
+
const options: TemplateOptions = {
|
|
250
|
+
...baseOptions,
|
|
251
|
+
monorepo: true,
|
|
252
|
+
apiPath: 'apps/api',
|
|
253
|
+
};
|
|
254
|
+
const files = generateMonorepoFiles(options, minimalTemplate);
|
|
255
|
+
const paths = files.map((f) => f.path);
|
|
256
|
+
expect(paths).toContain('package.json');
|
|
257
|
+
expect(paths).toContain('pnpm-workspace.yaml');
|
|
258
|
+
expect(paths).toContain('tsconfig.json');
|
|
259
|
+
expect(paths).toContain('biome.json');
|
|
260
|
+
expect(paths).toContain('turbo.json');
|
|
261
|
+
expect(paths).toContain('.gitignore');
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('should include correct workspace paths', () => {
|
|
265
|
+
const options: TemplateOptions = {
|
|
266
|
+
...baseOptions,
|
|
267
|
+
monorepo: true,
|
|
268
|
+
apiPath: 'apps/api',
|
|
269
|
+
};
|
|
270
|
+
const files = generateMonorepoFiles(options, minimalTemplate);
|
|
271
|
+
const workspace = files.find((f) => f.path === 'pnpm-workspace.yaml');
|
|
272
|
+
expect(workspace?.content).toContain("'apps/*'");
|
|
273
|
+
expect(workspace?.content).toContain("'packages/*'");
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('should include root scripts', () => {
|
|
277
|
+
const options: TemplateOptions = {
|
|
278
|
+
...baseOptions,
|
|
279
|
+
monorepo: true,
|
|
280
|
+
apiPath: 'apps/api',
|
|
281
|
+
};
|
|
282
|
+
const files = generateMonorepoFiles(options, minimalTemplate);
|
|
283
|
+
const pkgJson = files.find((f) => f.path === 'package.json');
|
|
284
|
+
const pkg = JSON.parse(pkgJson!.content);
|
|
285
|
+
expect(pkg.scripts.dev).toBe('turbo dev');
|
|
286
|
+
expect(pkg.scripts.build).toBe('turbo build');
|
|
287
|
+
expect(pkg.scripts.lint).toBe('biome lint .');
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
describe('generateModelsPackage', () => {
|
|
292
|
+
it('should return empty array for non-monorepo', () => {
|
|
293
|
+
const files = generateModelsPackage(baseOptions);
|
|
294
|
+
expect(files).toHaveLength(0);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it('should generate models package for monorepo', () => {
|
|
298
|
+
const options: TemplateOptions = {
|
|
299
|
+
...baseOptions,
|
|
300
|
+
monorepo: true,
|
|
301
|
+
apiPath: 'apps/api',
|
|
302
|
+
};
|
|
303
|
+
const files = generateModelsPackage(options);
|
|
304
|
+
const paths = files.map((f) => f.path);
|
|
305
|
+
expect(paths).toContain('packages/models/package.json');
|
|
306
|
+
expect(paths).toContain('packages/models/tsconfig.json');
|
|
307
|
+
expect(paths).toContain('packages/models/src/index.ts');
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('should use correct package name', () => {
|
|
311
|
+
const options: TemplateOptions = {
|
|
312
|
+
...baseOptions,
|
|
313
|
+
monorepo: true,
|
|
314
|
+
apiPath: 'apps/api',
|
|
315
|
+
};
|
|
316
|
+
const files = generateModelsPackage(options);
|
|
317
|
+
const pkgJson = files.find(
|
|
318
|
+
(f) => f.path === 'packages/models/package.json',
|
|
319
|
+
);
|
|
320
|
+
const pkg = JSON.parse(pkgJson!.content);
|
|
321
|
+
expect(pkg.name).toBe('@test-project/models');
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should include zod as dependency', () => {
|
|
325
|
+
const options: TemplateOptions = {
|
|
326
|
+
...baseOptions,
|
|
327
|
+
monorepo: true,
|
|
328
|
+
apiPath: 'apps/api',
|
|
329
|
+
};
|
|
330
|
+
const files = generateModelsPackage(options);
|
|
331
|
+
const pkgJson = files.find(
|
|
332
|
+
(f) => f.path === 'packages/models/package.json',
|
|
333
|
+
);
|
|
334
|
+
const pkg = JSON.parse(pkgJson!.content);
|
|
335
|
+
expect(pkg.dependencies.zod).toBeDefined();
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it('should include example schemas', () => {
|
|
339
|
+
const options: TemplateOptions = {
|
|
340
|
+
...baseOptions,
|
|
341
|
+
monorepo: true,
|
|
342
|
+
apiPath: 'apps/api',
|
|
343
|
+
};
|
|
344
|
+
const files = generateModelsPackage(options);
|
|
345
|
+
const indexTs = files.find(
|
|
346
|
+
(f) => f.path === 'packages/models/src/index.ts',
|
|
347
|
+
);
|
|
348
|
+
expect(indexTs?.content).toContain('userSchema');
|
|
349
|
+
expect(indexTs?.content).toContain('paginationSchema');
|
|
350
|
+
expect(indexTs?.content).toContain("import { z } from 'zod'");
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('should extend root tsconfig', () => {
|
|
354
|
+
const options: TemplateOptions = {
|
|
355
|
+
...baseOptions,
|
|
356
|
+
monorepo: true,
|
|
357
|
+
apiPath: 'apps/api',
|
|
358
|
+
};
|
|
359
|
+
const files = generateModelsPackage(options);
|
|
360
|
+
const tsConfig = files.find(
|
|
361
|
+
(f) => f.path === 'packages/models/tsconfig.json',
|
|
362
|
+
);
|
|
363
|
+
const config = JSON.parse(tsConfig!.content);
|
|
364
|
+
expect(config.extends).toBe('../../tsconfig.json');
|
|
365
|
+
});
|
|
366
|
+
});
|