@geekmidas/cli 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{SSMStateProvider-C4wp4AZe.mjs → SSMStateProvider-BjCi_58g.mjs} +16 -7
  3. package/dist/SSMStateProvider-BjCi_58g.mjs.map +1 -0
  4. package/dist/{SSMStateProvider-BxAPU99a.cjs → SSMStateProvider-D79o_JjM.cjs} +16 -7
  5. package/dist/SSMStateProvider-D79o_JjM.cjs.map +1 -0
  6. package/dist/{config-C6awcFBx.mjs → config-BQ4a36Rq.mjs} +2 -2
  7. package/dist/{config-C6awcFBx.mjs.map → config-BQ4a36Rq.mjs.map} +1 -1
  8. package/dist/{config-BGeJsW1r.cjs → config-Bayob8pB.cjs} +2 -2
  9. package/dist/{config-BGeJsW1r.cjs.map → config-Bayob8pB.cjs.map} +1 -1
  10. package/dist/config.cjs +2 -2
  11. package/dist/config.d.cts +1 -1
  12. package/dist/config.d.mts +1 -1
  13. package/dist/config.mjs +2 -2
  14. package/dist/{index-KFEbMIRa.d.mts → index-Bi9vGQJy.d.mts} +61 -13
  15. package/dist/index-Bi9vGQJy.d.mts.map +1 -0
  16. package/dist/{index-B5rGIc4g.d.cts → index-CufAAnge.d.cts} +61 -13
  17. package/dist/index-CufAAnge.d.cts.map +1 -0
  18. package/dist/index.cjs +14 -9
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.mjs +14 -9
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/{openapi-D1KXv2Ml.cjs → openapi-BZP8jkI4.cjs} +2 -2
  23. package/dist/{openapi-D1KXv2Ml.cjs.map → openapi-BZP8jkI4.cjs.map} +1 -1
  24. package/dist/{openapi-BMFmLnX6.mjs → openapi-DrbBWq0s.mjs} +2 -2
  25. package/dist/{openapi-BMFmLnX6.mjs.map → openapi-DrbBWq0s.mjs.map} +1 -1
  26. package/dist/openapi.cjs +3 -3
  27. package/dist/openapi.mjs +3 -3
  28. package/dist/workspace/index.cjs +2 -1
  29. package/dist/workspace/index.d.cts +2 -2
  30. package/dist/workspace/index.d.mts +2 -2
  31. package/dist/workspace/index.mjs +2 -2
  32. package/dist/{workspace-BFRUOOrh.cjs → workspace-BMJE18LV.cjs} +46 -6
  33. package/dist/workspace-BMJE18LV.cjs.map +1 -0
  34. package/dist/{workspace-DAxG3_H2.mjs → workspace-CASoZOjs.mjs} +41 -7
  35. package/dist/workspace-CASoZOjs.mjs.map +1 -0
  36. package/package.json +4 -4
  37. package/src/deploy/SSMStateProvider.ts +20 -7
  38. package/src/deploy/StateProvider.ts +1 -1
  39. package/src/deploy/__tests__/CachedStateProvider.spec.ts +7 -0
  40. package/src/deploy/__tests__/LocalStateProvider.spec.ts +4 -0
  41. package/src/deploy/__tests__/SSMStateProvider.spec.ts +20 -8
  42. package/src/deploy/__tests__/dns-verification.spec.ts +1 -1
  43. package/src/deploy/__tests__/env-resolver.spec.ts +9 -9
  44. package/src/deploy/__tests__/state-e2e.spec.ts +387 -0
  45. package/src/deploy/__tests__/state.spec.ts +53 -29
  46. package/src/deploy/index.ts +6 -1
  47. package/src/deploy/state.ts +4 -0
  48. package/src/init/__tests__/init.spec.ts +10 -1
  49. package/src/init/versions.ts +1 -1
  50. package/src/secrets/__tests__/storage.spec.ts +6 -2
  51. package/src/workspace/__tests__/index.spec.ts +129 -0
  52. package/src/workspace/index.ts +44 -0
  53. package/src/workspace/schema.ts +17 -6
  54. package/src/workspace/types.ts +26 -9
  55. package/dist/SSMStateProvider-BxAPU99a.cjs.map +0 -1
  56. package/dist/SSMStateProvider-C4wp4AZe.mjs.map +0 -1
  57. package/dist/index-B5rGIc4g.d.cts.map +0 -1
  58. package/dist/index-KFEbMIRa.d.mts.map +0 -1
  59. package/dist/workspace-BFRUOOrh.cjs.map +0 -1
  60. package/dist/workspace-DAxG3_H2.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @geekmidas/cli
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 🔥 [`43d4451`](https://github.com/geekmidas/toolbox/commit/43d44510f1077ecdf0c64ae56c8d2d97d446cea2) Thanks [@geekmidas](https://github.com/geekmidas)! - Remove projectId from workspace config and move to state
8
+
9
+ ## 1.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - ✨ [`3b6d7d9`](https://github.com/geekmidas/toolbox/commit/3b6d7d9ed41dc08675395d937248a8ab754af9e1) Thanks [@geekmidas](https://github.com/geekmidas)! - Add state provider configuration to workspace config
14
+
3
15
  ## 1.0.2
4
16
 
5
17
  ### Patch Changes
@@ -7,12 +7,21 @@ import { GetParameterCommand, ParameterNotFound, PutParameterCommand, SSMClient
7
7
  * Stores state as encrypted SecureString parameters.
8
8
  * Parameter path: /gkm/{workspaceName}/{stage}/state
9
9
  */
10
- var SSMStateProvider = class {
11
- client;
12
- workspaceName;
13
- constructor(options) {
14
- this.workspaceName = options.workspaceName;
15
- this.client = new SSMClient({ region: options.region });
10
+ var SSMStateProvider = class SSMStateProvider {
11
+ constructor(workspaceName, client) {
12
+ this.workspaceName = workspaceName;
13
+ this.client = client;
14
+ }
15
+ /**
16
+ * Create an SSMStateProvider with a new SSMClient.
17
+ */
18
+ static create(options) {
19
+ const client = new SSMClient({
20
+ region: options.region,
21
+ credentials: options.credentials,
22
+ endpoint: options.endpoint
23
+ });
24
+ return new SSMStateProvider(options.workspaceName, client);
16
25
  }
17
26
  /**
18
27
  * Get the SSM parameter name for a stage.
@@ -49,4 +58,4 @@ var SSMStateProvider = class {
49
58
 
50
59
  //#endregion
51
60
  export { SSMStateProvider };
52
- //# sourceMappingURL=SSMStateProvider-C4wp4AZe.mjs.map
61
+ //# sourceMappingURL=SSMStateProvider-BjCi_58g.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSMStateProvider-BjCi_58g.mjs","names":["workspaceName: string","client: SSMClient","options: SSMStateProviderOptions","stage: string","state: DokployStageState"],"sources":["../src/deploy/SSMStateProvider.ts"],"sourcesContent":["/**\n * AWS SSM Parameter Store State Provider\n *\n * Stores deployment state as SecureString parameters in AWS SSM.\n * Uses AWS-managed KMS key for encryption (free tier).\n *\n * Parameter naming: /gkm/{workspaceName}/{stage}/state\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n\ttype SSMClientConfig,\n} from '@aws-sdk/client-ssm';\nimport type { AwsRegion, StateProvider } from './StateProvider';\nimport type { DokployStageState } from './state';\n\nexport interface SSMStateProviderOptions {\n\t/** Workspace name (used in parameter path) */\n\tworkspaceName: string;\n\t/** AWS region */\n\tregion?: AwsRegion;\n\t/** AWS credentials (optional - uses default credential chain if not provided) */\n\tcredentials?: SSMClientConfig['credentials'];\n\t/** Custom endpoint (for LocalStack or other S3-compatible services) */\n\tendpoint?: string;\n}\n\n/**\n * AWS SSM Parameter Store state provider.\n *\n * Stores state as encrypted SecureString parameters.\n * Parameter path: /gkm/{workspaceName}/{stage}/state\n */\nexport class SSMStateProvider implements StateProvider {\n\tconstructor(\n\t\treadonly workspaceName: string,\n\t\tprivate readonly client: SSMClient,\n\t) {}\n\n\t/**\n\t * Create an SSMStateProvider with a new SSMClient.\n\t */\n\tstatic create(options: SSMStateProviderOptions): SSMStateProvider {\n\t\tconst client = new SSMClient({\n\t\t\tregion: options.region,\n\t\t\tcredentials: options.credentials,\n\t\t\tendpoint: options.endpoint,\n\t\t});\n\n\t\treturn new SSMStateProvider(options.workspaceName, client);\n\t}\n\n\t/**\n\t * Get the SSM parameter name for a stage.\n\t */\n\tprivate getParameterName(stage: string): string {\n\t\treturn `/gkm/${this.workspaceName}/${stage}/state`;\n\t}\n\n\tasync read(stage: string): Promise<DokployStageState | null> {\n\t\tconst parameterName = this.getParameterName(stage);\n\n\t\ttry {\n\t\t\tconst response = await this.client.send(\n\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\tName: parameterName,\n\t\t\t\t\tWithDecryption: true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tif (!response.Parameter?.Value) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn JSON.parse(response.Parameter.Value) as DokployStageState;\n\t\t} catch (error) {\n\t\t\t// Parameter doesn't exist - return null (new deployment)\n\t\t\tif (error instanceof ParameterNotFound) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Re-throw other errors (permission denied, network, etc.)\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync write(stage: string, state: DokployStageState): Promise<void> {\n\t\tconst parameterName = this.getParameterName(stage);\n\n\t\t// Update last deployed timestamp\n\t\tstate.lastDeployedAt = new Date().toISOString();\n\n\t\tawait this.client.send(\n\t\t\tnew PutParameterCommand({\n\t\t\t\tName: parameterName,\n\t\t\t\tValue: JSON.stringify(state),\n\t\t\t\tType: 'SecureString',\n\t\t\t\tOverwrite: true,\n\t\t\t\tDescription: `GKM deployment state for ${this.workspaceName}/${stage}`,\n\t\t\t}),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;AAoCA,IAAa,mBAAb,MAAa,iBAA0C;CACtD,YACUA,eACQC,QAChB;EAFQ;EACQ;CACd;;;;CAKJ,OAAO,OAAOC,SAAoD;EACjE,MAAM,SAAS,IAAI,UAAU;GAC5B,QAAQ,QAAQ;GAChB,aAAa,QAAQ;GACrB,UAAU,QAAQ;EAClB;AAED,SAAO,IAAI,iBAAiB,QAAQ,eAAe;CACnD;;;;CAKD,AAAQ,iBAAiBC,OAAuB;AAC/C,UAAQ,OAAO,KAAK,cAAc,GAAG,MAAM;CAC3C;CAED,MAAM,KAAKA,OAAkD;EAC5D,MAAM,gBAAgB,KAAK,iBAAiB,MAAM;AAElD,MAAI;GACH,MAAM,WAAW,MAAM,KAAK,OAAO,KAClC,IAAI,oBAAoB;IACvB,MAAM;IACN,gBAAgB;GAChB,GACD;AAED,QAAK,SAAS,WAAW,MACxB,QAAO;AAGR,UAAO,KAAK,MAAM,SAAS,UAAU,MAAM;EAC3C,SAAQ,OAAO;AAEf,OAAI,iBAAiB,kBACpB,QAAO;AAIR,SAAM;EACN;CACD;CAED,MAAM,MAAMA,OAAeC,OAAyC;EACnE,MAAM,gBAAgB,KAAK,iBAAiB,MAAM;AAGlD,QAAM,iBAAiB,qBAAI,QAAO,aAAa;AAE/C,QAAM,KAAK,OAAO,KACjB,IAAI,oBAAoB;GACvB,MAAM;GACN,OAAO,KAAK,UAAU,MAAM;GAC5B,MAAM;GACN,WAAW;GACX,cAAc,2BAA2B,KAAK,cAAc,GAAG,MAAM;EACrE,GACD;CACD;AACD"}
@@ -8,12 +8,21 @@ const __aws_sdk_client_ssm = require_chunk.__toESM(require("@aws-sdk/client-ssm"
8
8
  * Stores state as encrypted SecureString parameters.
9
9
  * Parameter path: /gkm/{workspaceName}/{stage}/state
10
10
  */
11
- var SSMStateProvider = class {
12
- client;
13
- workspaceName;
14
- constructor(options) {
15
- this.workspaceName = options.workspaceName;
16
- this.client = new __aws_sdk_client_ssm.SSMClient({ region: options.region });
11
+ var SSMStateProvider = class SSMStateProvider {
12
+ constructor(workspaceName, client) {
13
+ this.workspaceName = workspaceName;
14
+ this.client = client;
15
+ }
16
+ /**
17
+ * Create an SSMStateProvider with a new SSMClient.
18
+ */
19
+ static create(options) {
20
+ const client = new __aws_sdk_client_ssm.SSMClient({
21
+ region: options.region,
22
+ credentials: options.credentials,
23
+ endpoint: options.endpoint
24
+ });
25
+ return new SSMStateProvider(options.workspaceName, client);
17
26
  }
18
27
  /**
19
28
  * Get the SSM parameter name for a stage.
@@ -50,4 +59,4 @@ var SSMStateProvider = class {
50
59
 
51
60
  //#endregion
52
61
  exports.SSMStateProvider = SSMStateProvider;
53
- //# sourceMappingURL=SSMStateProvider-BxAPU99a.cjs.map
62
+ //# sourceMappingURL=SSMStateProvider-D79o_JjM.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSMStateProvider-D79o_JjM.cjs","names":["workspaceName: string","client: SSMClient","options: SSMStateProviderOptions","SSMClient","stage: string","GetParameterCommand","ParameterNotFound","state: DokployStageState","PutParameterCommand"],"sources":["../src/deploy/SSMStateProvider.ts"],"sourcesContent":["/**\n * AWS SSM Parameter Store State Provider\n *\n * Stores deployment state as SecureString parameters in AWS SSM.\n * Uses AWS-managed KMS key for encryption (free tier).\n *\n * Parameter naming: /gkm/{workspaceName}/{stage}/state\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n\ttype SSMClientConfig,\n} from '@aws-sdk/client-ssm';\nimport type { AwsRegion, StateProvider } from './StateProvider';\nimport type { DokployStageState } from './state';\n\nexport interface SSMStateProviderOptions {\n\t/** Workspace name (used in parameter path) */\n\tworkspaceName: string;\n\t/** AWS region */\n\tregion?: AwsRegion;\n\t/** AWS credentials (optional - uses default credential chain if not provided) */\n\tcredentials?: SSMClientConfig['credentials'];\n\t/** Custom endpoint (for LocalStack or other S3-compatible services) */\n\tendpoint?: string;\n}\n\n/**\n * AWS SSM Parameter Store state provider.\n *\n * Stores state as encrypted SecureString parameters.\n * Parameter path: /gkm/{workspaceName}/{stage}/state\n */\nexport class SSMStateProvider implements StateProvider {\n\tconstructor(\n\t\treadonly workspaceName: string,\n\t\tprivate readonly client: SSMClient,\n\t) {}\n\n\t/**\n\t * Create an SSMStateProvider with a new SSMClient.\n\t */\n\tstatic create(options: SSMStateProviderOptions): SSMStateProvider {\n\t\tconst client = new SSMClient({\n\t\t\tregion: options.region,\n\t\t\tcredentials: options.credentials,\n\t\t\tendpoint: options.endpoint,\n\t\t});\n\n\t\treturn new SSMStateProvider(options.workspaceName, client);\n\t}\n\n\t/**\n\t * Get the SSM parameter name for a stage.\n\t */\n\tprivate getParameterName(stage: string): string {\n\t\treturn `/gkm/${this.workspaceName}/${stage}/state`;\n\t}\n\n\tasync read(stage: string): Promise<DokployStageState | null> {\n\t\tconst parameterName = this.getParameterName(stage);\n\n\t\ttry {\n\t\t\tconst response = await this.client.send(\n\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\tName: parameterName,\n\t\t\t\t\tWithDecryption: true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tif (!response.Parameter?.Value) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn JSON.parse(response.Parameter.Value) as DokployStageState;\n\t\t} catch (error) {\n\t\t\t// Parameter doesn't exist - return null (new deployment)\n\t\t\tif (error instanceof ParameterNotFound) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Re-throw other errors (permission denied, network, etc.)\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync write(stage: string, state: DokployStageState): Promise<void> {\n\t\tconst parameterName = this.getParameterName(stage);\n\n\t\t// Update last deployed timestamp\n\t\tstate.lastDeployedAt = new Date().toISOString();\n\n\t\tawait this.client.send(\n\t\t\tnew PutParameterCommand({\n\t\t\t\tName: parameterName,\n\t\t\t\tValue: JSON.stringify(state),\n\t\t\t\tType: 'SecureString',\n\t\t\t\tOverwrite: true,\n\t\t\t\tDescription: `GKM deployment state for ${this.workspaceName}/${stage}`,\n\t\t\t}),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;AAoCA,IAAa,mBAAb,MAAa,iBAA0C;CACtD,YACUA,eACQC,QAChB;EAFQ;EACQ;CACd;;;;CAKJ,OAAO,OAAOC,SAAoD;EACjE,MAAM,SAAS,IAAIC,+BAAU;GAC5B,QAAQ,QAAQ;GAChB,aAAa,QAAQ;GACrB,UAAU,QAAQ;EAClB;AAED,SAAO,IAAI,iBAAiB,QAAQ,eAAe;CACnD;;;;CAKD,AAAQ,iBAAiBC,OAAuB;AAC/C,UAAQ,OAAO,KAAK,cAAc,GAAG,MAAM;CAC3C;CAED,MAAM,KAAKA,OAAkD;EAC5D,MAAM,gBAAgB,KAAK,iBAAiB,MAAM;AAElD,MAAI;GACH,MAAM,WAAW,MAAM,KAAK,OAAO,KAClC,IAAIC,yCAAoB;IACvB,MAAM;IACN,gBAAgB;GAChB,GACD;AAED,QAAK,SAAS,WAAW,MACxB,QAAO;AAGR,UAAO,KAAK,MAAM,SAAS,UAAU,MAAM;EAC3C,SAAQ,OAAO;AAEf,OAAI,iBAAiBC,uCACpB,QAAO;AAIR,SAAM;EACN;CACD;CAED,MAAM,MAAMF,OAAeG,OAAyC;EACnE,MAAM,gBAAgB,KAAK,iBAAiB,MAAM;AAGlD,QAAM,iBAAiB,qBAAI,QAAO,aAAa;AAE/C,QAAM,KAAK,OAAO,KACjB,IAAIC,yCAAoB;GACvB,MAAM;GACN,OAAO,KAAK,UAAU,MAAM;GAC5B,MAAM;GACN,WAAW;GACX,cAAc,2BAA2B,KAAK,cAAc,GAAG,MAAM;EACrE,GACD;CACD;AACD"}
@@ -1,4 +1,4 @@
1
- import { getAppGkmConfig, isWorkspaceConfig, processConfig } from "./workspace-DAxG3_H2.mjs";
1
+ import { getAppGkmConfig, isWorkspaceConfig, processConfig } from "./workspace-CASoZOjs.mjs";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import { dirname, join, parse } from "node:path";
4
4
 
@@ -186,4 +186,4 @@ async function loadAppConfig(cwd = process.cwd()) {
186
186
 
187
187
  //#endregion
188
188
  export { defineConfig, getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceConfig, parseModuleConfig };
189
- //# sourceMappingURL=config-C6awcFBx.mjs.map
189
+ //# sourceMappingURL=config-BQ4a36Rq.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-C6awcFBx.mjs","names":["config: GkmConfig","configString: string","defaultAlias: string","cwd: string"],"sources":["../src/config.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, parse } from 'node:path';\nimport type { GkmConfig } from './types.js';\nimport {\n\tgetAppGkmConfig,\n\tisWorkspaceConfig,\n\ttype LoadedConfig,\n\ttype NormalizedAppConfig,\n\ttype NormalizedWorkspace,\n\tprocessConfig,\n\ttype WorkspaceConfig,\n} from './workspace/index.js';\n\nexport type { GkmConfig } from './types.js';\nexport type { LoadedConfig, WorkspaceConfig } from './workspace/index.js';\nexport { defineWorkspace } from './workspace/index.js';\n/**\n * Define GKM configuration with full TypeScript support.\n * This is an identity function that provides type safety and autocomplete.\n *\n * @example\n * ```ts\n * // gkm.config.ts\n * import { defineConfig } from '@geekmidas/cli/config';\n *\n * export default defineConfig({\n * routes: './src/endpoints/**\\/*.ts',\n * envParser: './src/config/env',\n * logger: './src/config/logger',\n * telescope: true,\n * });\n * ```\n */\nexport function defineConfig(config: GkmConfig): GkmConfig {\n\treturn config;\n}\n\nexport interface ParsedModuleConfig {\n\tpath: string;\n\timportPattern: string;\n}\n\n/**\n * Parse a module config string into path and import pattern.\n *\n * @param configString - Config string in format \"./path/to/module\" or \"./path/to/module#exportName\"\n * @param defaultAlias - The default alias name to use if no export name specified\n * @returns Object with path and import pattern\n *\n * @example\n * parseModuleConfig('./src/config/env', 'envParser')\n * // { path: './src/config/env', importPattern: 'envParser' }\n *\n * parseModuleConfig('./src/config/env#envParser', 'envParser')\n * // { path: './src/config/env', importPattern: '{ envParser }' }\n *\n * parseModuleConfig('./src/config/env#myEnv', 'envParser')\n * // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }\n */\nexport function parseModuleConfig(\n\tconfigString: string,\n\tdefaultAlias: string,\n): ParsedModuleConfig {\n\tconst parts = configString.split('#');\n\tconst path = parts[0] ?? configString;\n\tconst exportName = parts[1];\n\tconst importPattern = !exportName\n\t\t? defaultAlias\n\t\t: exportName === defaultAlias\n\t\t\t? `{ ${defaultAlias} }`\n\t\t\t: `{ ${exportName} as ${defaultAlias} }`;\n\n\treturn { path, importPattern };\n}\n\nexport interface ConfigDiscoveryResult {\n\tconfigPath: string;\n\tworkspaceRoot: string;\n}\n\n/**\n * Find and return the path to the config file.\n *\n * Resolution order:\n * 1. GKM_CONFIG_PATH env var (set by workspace dev command)\n * 2. Walk up directory tree from cwd\n */\nfunction findConfigPath(cwd: string): ConfigDiscoveryResult {\n\tconst files = ['gkm.config.json', 'gkm.config.ts', 'gkm.config.js'];\n\n\t// Check GKM_CONFIG_PATH env var first (set by workspace dev command)\n\tconst envConfigPath = process.env.GKM_CONFIG_PATH;\n\tif (envConfigPath && existsSync(envConfigPath)) {\n\t\treturn {\n\t\t\tconfigPath: envConfigPath,\n\t\t\tworkspaceRoot: dirname(envConfigPath),\n\t\t};\n\t}\n\n\t// Walk up directory tree to find config\n\tlet currentDir = cwd;\n\tconst { root } = parse(currentDir);\n\n\twhile (currentDir !== root) {\n\t\tfor (const file of files) {\n\t\t\tconst configPath = join(currentDir, file);\n\t\t\tif (existsSync(configPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tconfigPath,\n\t\t\t\t\tworkspaceRoot: currentDir,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tcurrentDir = dirname(currentDir);\n\t}\n\n\tthrow new Error(\n\t\t'Configuration file not found. Please create gkm.config.json, gkm.config.ts, or gkm.config.js in the project root.',\n\t);\n}\n\n/**\n * Get app name from package.json in the given directory.\n * Handles scoped packages by extracting the name after the scope.\n *\n * @example\n * getAppNameFromCwd('/path/to/apps/api')\n * // package.json: { \"name\": \"@myorg/api\" }\n * // Returns: 'api'\n */\nexport function getAppNameFromCwd(cwd: string = process.cwd()): string | null {\n\tconst packageJsonPath = join(cwd, 'package.json');\n\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\t\tconst name = packageJson.name as string | undefined;\n\n\t\tif (!name) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Handle scoped packages: @scope/name -> name\n\t\tif (name.startsWith('@') && name.includes('/')) {\n\t\t\treturn name.split('/')[1] ?? null;\n\t\t}\n\n\t\treturn name;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\ninterface RawConfigResult {\n\tconfig: GkmConfig | WorkspaceConfig;\n\tworkspaceRoot: string;\n}\n\n/**\n * Load raw configuration from file.\n */\nasync function loadRawConfig(cwd: string): Promise<RawConfigResult> {\n\tconst { configPath, workspaceRoot } = findConfigPath(cwd);\n\n\ttry {\n\t\tconst config = await import(configPath);\n\t\treturn {\n\t\t\tconfig: config.default,\n\t\t\tworkspaceRoot,\n\t\t};\n\t} catch (error) {\n\t\tthrow new Error(`Failed to load config: ${(error as Error).message}`);\n\t}\n}\n\n/**\n * Load configuration file (single-app format).\n * For backwards compatibility with existing code.\n *\n * @deprecated Use loadWorkspaceConfig for new code\n */\nexport async function loadConfig(\n\tcwd: string = process.cwd(),\n): Promise<GkmConfig> {\n\tconst { config } = await loadRawConfig(cwd);\n\n\t// If it's a workspace config, throw an error\n\tif (isWorkspaceConfig(config)) {\n\t\tthrow new Error(\n\t\t\t'Workspace configuration detected. Use loadWorkspaceConfig() instead.',\n\t\t);\n\t}\n\n\treturn config;\n}\n\n/**\n * Load configuration file and process it as a workspace.\n * Works with both single-app and workspace configurations.\n *\n * Single-app configs are automatically wrapped as a workspace with one app.\n *\n * @example\n * ```ts\n * const { type, workspace } = await loadWorkspaceConfig();\n *\n * if (type === 'workspace') {\n * console.log('Multi-app workspace:', workspace.apps);\n * } else {\n * console.log('Single app wrapped as workspace');\n * }\n * ```\n */\nexport async function loadWorkspaceConfig(\n\tcwd: string = process.cwd(),\n): Promise<LoadedConfig> {\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\treturn processConfig(config, workspaceRoot);\n}\n\nexport interface AppConfigResult {\n\tappName: string;\n\tapp: NormalizedAppConfig;\n\tgkmConfig: GkmConfig;\n\tworkspace: NormalizedWorkspace;\n\tworkspaceRoot: string;\n\tappRoot: string;\n}\n\n/**\n * Load app-specific configuration from workspace.\n * Uses the app name from package.json to find the correct app config.\n *\n * @example\n * ```ts\n * // From apps/api directory with package.json: { \"name\": \"@myorg/api\" }\n * const { app, workspace, workspaceRoot } = await loadAppConfig();\n * console.log(app.routes); // './src/endpoints/**\\/*.ts'\n * ```\n */\nexport async function loadAppConfig(\n\tcwd: string = process.cwd(),\n): Promise<AppConfigResult> {\n\tconst appName = getAppNameFromCwd(cwd);\n\n\tif (!appName) {\n\t\tthrow new Error(\n\t\t\t'Could not determine app name. Ensure package.json exists with a \"name\" field.',\n\t\t);\n\t}\n\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\tconst loadedConfig = processConfig(config, workspaceRoot);\n\n\t// Find the app in workspace (apps is a Record<string, NormalizedAppConfig>)\n\tconst app = loadedConfig.workspace.apps[appName];\n\n\tif (!app) {\n\t\tconst availableApps = Object.keys(loadedConfig.workspace.apps).join(', ');\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" not found in workspace config. Available apps: ${availableApps}. ` +\n\t\t\t\t`Ensure the package.json name matches the app key in gkm.config.ts.`,\n\t\t);\n\t}\n\n\t// Get the app's GKM config using the helper\n\tconst gkmConfig = getAppGkmConfig(loadedConfig.workspace, appName);\n\n\tif (!gkmConfig) {\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" is not a backend app and cannot be run with gkm dev.`,\n\t\t);\n\t}\n\n\treturn {\n\t\tappName,\n\t\tapp,\n\t\tgkmConfig,\n\t\tworkspace: loadedConfig.workspace,\n\t\tworkspaceRoot,\n\t\tappRoot: join(workspaceRoot, app.path),\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config-BQ4a36Rq.mjs","names":["config: GkmConfig","configString: string","defaultAlias: string","cwd: string"],"sources":["../src/config.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, parse } from 'node:path';\nimport type { GkmConfig } from './types.js';\nimport {\n\tgetAppGkmConfig,\n\tisWorkspaceConfig,\n\ttype LoadedConfig,\n\ttype NormalizedAppConfig,\n\ttype NormalizedWorkspace,\n\tprocessConfig,\n\ttype WorkspaceConfig,\n} from './workspace/index.js';\n\nexport type { GkmConfig } from './types.js';\nexport type { LoadedConfig, WorkspaceConfig } from './workspace/index.js';\nexport { defineWorkspace } from './workspace/index.js';\n/**\n * Define GKM configuration with full TypeScript support.\n * This is an identity function that provides type safety and autocomplete.\n *\n * @example\n * ```ts\n * // gkm.config.ts\n * import { defineConfig } from '@geekmidas/cli/config';\n *\n * export default defineConfig({\n * routes: './src/endpoints/**\\/*.ts',\n * envParser: './src/config/env',\n * logger: './src/config/logger',\n * telescope: true,\n * });\n * ```\n */\nexport function defineConfig(config: GkmConfig): GkmConfig {\n\treturn config;\n}\n\nexport interface ParsedModuleConfig {\n\tpath: string;\n\timportPattern: string;\n}\n\n/**\n * Parse a module config string into path and import pattern.\n *\n * @param configString - Config string in format \"./path/to/module\" or \"./path/to/module#exportName\"\n * @param defaultAlias - The default alias name to use if no export name specified\n * @returns Object with path and import pattern\n *\n * @example\n * parseModuleConfig('./src/config/env', 'envParser')\n * // { path: './src/config/env', importPattern: 'envParser' }\n *\n * parseModuleConfig('./src/config/env#envParser', 'envParser')\n * // { path: './src/config/env', importPattern: '{ envParser }' }\n *\n * parseModuleConfig('./src/config/env#myEnv', 'envParser')\n * // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }\n */\nexport function parseModuleConfig(\n\tconfigString: string,\n\tdefaultAlias: string,\n): ParsedModuleConfig {\n\tconst parts = configString.split('#');\n\tconst path = parts[0] ?? configString;\n\tconst exportName = parts[1];\n\tconst importPattern = !exportName\n\t\t? defaultAlias\n\t\t: exportName === defaultAlias\n\t\t\t? `{ ${defaultAlias} }`\n\t\t\t: `{ ${exportName} as ${defaultAlias} }`;\n\n\treturn { path, importPattern };\n}\n\nexport interface ConfigDiscoveryResult {\n\tconfigPath: string;\n\tworkspaceRoot: string;\n}\n\n/**\n * Find and return the path to the config file.\n *\n * Resolution order:\n * 1. GKM_CONFIG_PATH env var (set by workspace dev command)\n * 2. Walk up directory tree from cwd\n */\nfunction findConfigPath(cwd: string): ConfigDiscoveryResult {\n\tconst files = ['gkm.config.json', 'gkm.config.ts', 'gkm.config.js'];\n\n\t// Check GKM_CONFIG_PATH env var first (set by workspace dev command)\n\tconst envConfigPath = process.env.GKM_CONFIG_PATH;\n\tif (envConfigPath && existsSync(envConfigPath)) {\n\t\treturn {\n\t\t\tconfigPath: envConfigPath,\n\t\t\tworkspaceRoot: dirname(envConfigPath),\n\t\t};\n\t}\n\n\t// Walk up directory tree to find config\n\tlet currentDir = cwd;\n\tconst { root } = parse(currentDir);\n\n\twhile (currentDir !== root) {\n\t\tfor (const file of files) {\n\t\t\tconst configPath = join(currentDir, file);\n\t\t\tif (existsSync(configPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tconfigPath,\n\t\t\t\t\tworkspaceRoot: currentDir,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tcurrentDir = dirname(currentDir);\n\t}\n\n\tthrow new Error(\n\t\t'Configuration file not found. Please create gkm.config.json, gkm.config.ts, or gkm.config.js in the project root.',\n\t);\n}\n\n/**\n * Get app name from package.json in the given directory.\n * Handles scoped packages by extracting the name after the scope.\n *\n * @example\n * getAppNameFromCwd('/path/to/apps/api')\n * // package.json: { \"name\": \"@myorg/api\" }\n * // Returns: 'api'\n */\nexport function getAppNameFromCwd(cwd: string = process.cwd()): string | null {\n\tconst packageJsonPath = join(cwd, 'package.json');\n\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\t\tconst name = packageJson.name as string | undefined;\n\n\t\tif (!name) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Handle scoped packages: @scope/name -> name\n\t\tif (name.startsWith('@') && name.includes('/')) {\n\t\t\treturn name.split('/')[1] ?? null;\n\t\t}\n\n\t\treturn name;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\ninterface RawConfigResult {\n\tconfig: GkmConfig | WorkspaceConfig;\n\tworkspaceRoot: string;\n}\n\n/**\n * Load raw configuration from file.\n */\nasync function loadRawConfig(cwd: string): Promise<RawConfigResult> {\n\tconst { configPath, workspaceRoot } = findConfigPath(cwd);\n\n\ttry {\n\t\tconst config = await import(configPath);\n\t\treturn {\n\t\t\tconfig: config.default,\n\t\t\tworkspaceRoot,\n\t\t};\n\t} catch (error) {\n\t\tthrow new Error(`Failed to load config: ${(error as Error).message}`);\n\t}\n}\n\n/**\n * Load configuration file (single-app format).\n * For backwards compatibility with existing code.\n *\n * @deprecated Use loadWorkspaceConfig for new code\n */\nexport async function loadConfig(\n\tcwd: string = process.cwd(),\n): Promise<GkmConfig> {\n\tconst { config } = await loadRawConfig(cwd);\n\n\t// If it's a workspace config, throw an error\n\tif (isWorkspaceConfig(config)) {\n\t\tthrow new Error(\n\t\t\t'Workspace configuration detected. Use loadWorkspaceConfig() instead.',\n\t\t);\n\t}\n\n\treturn config;\n}\n\n/**\n * Load configuration file and process it as a workspace.\n * Works with both single-app and workspace configurations.\n *\n * Single-app configs are automatically wrapped as a workspace with one app.\n *\n * @example\n * ```ts\n * const { type, workspace } = await loadWorkspaceConfig();\n *\n * if (type === 'workspace') {\n * console.log('Multi-app workspace:', workspace.apps);\n * } else {\n * console.log('Single app wrapped as workspace');\n * }\n * ```\n */\nexport async function loadWorkspaceConfig(\n\tcwd: string = process.cwd(),\n): Promise<LoadedConfig> {\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\treturn processConfig(config, workspaceRoot);\n}\n\nexport interface AppConfigResult {\n\tappName: string;\n\tapp: NormalizedAppConfig;\n\tgkmConfig: GkmConfig;\n\tworkspace: NormalizedWorkspace;\n\tworkspaceRoot: string;\n\tappRoot: string;\n}\n\n/**\n * Load app-specific configuration from workspace.\n * Uses the app name from package.json to find the correct app config.\n *\n * @example\n * ```ts\n * // From apps/api directory with package.json: { \"name\": \"@myorg/api\" }\n * const { app, workspace, workspaceRoot } = await loadAppConfig();\n * console.log(app.routes); // './src/endpoints/**\\/*.ts'\n * ```\n */\nexport async function loadAppConfig(\n\tcwd: string = process.cwd(),\n): Promise<AppConfigResult> {\n\tconst appName = getAppNameFromCwd(cwd);\n\n\tif (!appName) {\n\t\tthrow new Error(\n\t\t\t'Could not determine app name. Ensure package.json exists with a \"name\" field.',\n\t\t);\n\t}\n\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\tconst loadedConfig = processConfig(config, workspaceRoot);\n\n\t// Find the app in workspace (apps is a Record<string, NormalizedAppConfig>)\n\tconst app = loadedConfig.workspace.apps[appName];\n\n\tif (!app) {\n\t\tconst availableApps = Object.keys(loadedConfig.workspace.apps).join(', ');\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" not found in workspace config. Available apps: ${availableApps}. ` +\n\t\t\t\t`Ensure the package.json name matches the app key in gkm.config.ts.`,\n\t\t);\n\t}\n\n\t// Get the app's GKM config using the helper\n\tconst gkmConfig = getAppGkmConfig(loadedConfig.workspace, appName);\n\n\tif (!gkmConfig) {\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" is not a backend app and cannot be run with gkm dev.`,\n\t\t);\n\t}\n\n\treturn {\n\t\tappName,\n\t\tapp,\n\t\tgkmConfig,\n\t\tworkspace: loadedConfig.workspace,\n\t\tworkspaceRoot,\n\t\tappRoot: join(workspaceRoot, app.path),\n\t};\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require('./chunk-CUT6urMc.cjs');
2
- const require_workspace = require('./workspace-BFRUOOrh.cjs');
2
+ const require_workspace = require('./workspace-BMJE18LV.cjs');
3
3
  const node_fs = require_chunk.__toESM(require("node:fs"));
4
4
  const node_path = require_chunk.__toESM(require("node:path"));
5
5
 
@@ -222,4 +222,4 @@ Object.defineProperty(exports, 'parseModuleConfig', {
222
222
  return parseModuleConfig;
223
223
  }
224
224
  });
225
- //# sourceMappingURL=config-BGeJsW1r.cjs.map
225
+ //# sourceMappingURL=config-Bayob8pB.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-BGeJsW1r.cjs","names":["config: GkmConfig","configString: string","defaultAlias: string","cwd: string"],"sources":["../src/config.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, parse } from 'node:path';\nimport type { GkmConfig } from './types.js';\nimport {\n\tgetAppGkmConfig,\n\tisWorkspaceConfig,\n\ttype LoadedConfig,\n\ttype NormalizedAppConfig,\n\ttype NormalizedWorkspace,\n\tprocessConfig,\n\ttype WorkspaceConfig,\n} from './workspace/index.js';\n\nexport type { GkmConfig } from './types.js';\nexport type { LoadedConfig, WorkspaceConfig } from './workspace/index.js';\nexport { defineWorkspace } from './workspace/index.js';\n/**\n * Define GKM configuration with full TypeScript support.\n * This is an identity function that provides type safety and autocomplete.\n *\n * @example\n * ```ts\n * // gkm.config.ts\n * import { defineConfig } from '@geekmidas/cli/config';\n *\n * export default defineConfig({\n * routes: './src/endpoints/**\\/*.ts',\n * envParser: './src/config/env',\n * logger: './src/config/logger',\n * telescope: true,\n * });\n * ```\n */\nexport function defineConfig(config: GkmConfig): GkmConfig {\n\treturn config;\n}\n\nexport interface ParsedModuleConfig {\n\tpath: string;\n\timportPattern: string;\n}\n\n/**\n * Parse a module config string into path and import pattern.\n *\n * @param configString - Config string in format \"./path/to/module\" or \"./path/to/module#exportName\"\n * @param defaultAlias - The default alias name to use if no export name specified\n * @returns Object with path and import pattern\n *\n * @example\n * parseModuleConfig('./src/config/env', 'envParser')\n * // { path: './src/config/env', importPattern: 'envParser' }\n *\n * parseModuleConfig('./src/config/env#envParser', 'envParser')\n * // { path: './src/config/env', importPattern: '{ envParser }' }\n *\n * parseModuleConfig('./src/config/env#myEnv', 'envParser')\n * // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }\n */\nexport function parseModuleConfig(\n\tconfigString: string,\n\tdefaultAlias: string,\n): ParsedModuleConfig {\n\tconst parts = configString.split('#');\n\tconst path = parts[0] ?? configString;\n\tconst exportName = parts[1];\n\tconst importPattern = !exportName\n\t\t? defaultAlias\n\t\t: exportName === defaultAlias\n\t\t\t? `{ ${defaultAlias} }`\n\t\t\t: `{ ${exportName} as ${defaultAlias} }`;\n\n\treturn { path, importPattern };\n}\n\nexport interface ConfigDiscoveryResult {\n\tconfigPath: string;\n\tworkspaceRoot: string;\n}\n\n/**\n * Find and return the path to the config file.\n *\n * Resolution order:\n * 1. GKM_CONFIG_PATH env var (set by workspace dev command)\n * 2. Walk up directory tree from cwd\n */\nfunction findConfigPath(cwd: string): ConfigDiscoveryResult {\n\tconst files = ['gkm.config.json', 'gkm.config.ts', 'gkm.config.js'];\n\n\t// Check GKM_CONFIG_PATH env var first (set by workspace dev command)\n\tconst envConfigPath = process.env.GKM_CONFIG_PATH;\n\tif (envConfigPath && existsSync(envConfigPath)) {\n\t\treturn {\n\t\t\tconfigPath: envConfigPath,\n\t\t\tworkspaceRoot: dirname(envConfigPath),\n\t\t};\n\t}\n\n\t// Walk up directory tree to find config\n\tlet currentDir = cwd;\n\tconst { root } = parse(currentDir);\n\n\twhile (currentDir !== root) {\n\t\tfor (const file of files) {\n\t\t\tconst configPath = join(currentDir, file);\n\t\t\tif (existsSync(configPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tconfigPath,\n\t\t\t\t\tworkspaceRoot: currentDir,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tcurrentDir = dirname(currentDir);\n\t}\n\n\tthrow new Error(\n\t\t'Configuration file not found. Please create gkm.config.json, gkm.config.ts, or gkm.config.js in the project root.',\n\t);\n}\n\n/**\n * Get app name from package.json in the given directory.\n * Handles scoped packages by extracting the name after the scope.\n *\n * @example\n * getAppNameFromCwd('/path/to/apps/api')\n * // package.json: { \"name\": \"@myorg/api\" }\n * // Returns: 'api'\n */\nexport function getAppNameFromCwd(cwd: string = process.cwd()): string | null {\n\tconst packageJsonPath = join(cwd, 'package.json');\n\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\t\tconst name = packageJson.name as string | undefined;\n\n\t\tif (!name) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Handle scoped packages: @scope/name -> name\n\t\tif (name.startsWith('@') && name.includes('/')) {\n\t\t\treturn name.split('/')[1] ?? null;\n\t\t}\n\n\t\treturn name;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\ninterface RawConfigResult {\n\tconfig: GkmConfig | WorkspaceConfig;\n\tworkspaceRoot: string;\n}\n\n/**\n * Load raw configuration from file.\n */\nasync function loadRawConfig(cwd: string): Promise<RawConfigResult> {\n\tconst { configPath, workspaceRoot } = findConfigPath(cwd);\n\n\ttry {\n\t\tconst config = await import(configPath);\n\t\treturn {\n\t\t\tconfig: config.default,\n\t\t\tworkspaceRoot,\n\t\t};\n\t} catch (error) {\n\t\tthrow new Error(`Failed to load config: ${(error as Error).message}`);\n\t}\n}\n\n/**\n * Load configuration file (single-app format).\n * For backwards compatibility with existing code.\n *\n * @deprecated Use loadWorkspaceConfig for new code\n */\nexport async function loadConfig(\n\tcwd: string = process.cwd(),\n): Promise<GkmConfig> {\n\tconst { config } = await loadRawConfig(cwd);\n\n\t// If it's a workspace config, throw an error\n\tif (isWorkspaceConfig(config)) {\n\t\tthrow new Error(\n\t\t\t'Workspace configuration detected. Use loadWorkspaceConfig() instead.',\n\t\t);\n\t}\n\n\treturn config;\n}\n\n/**\n * Load configuration file and process it as a workspace.\n * Works with both single-app and workspace configurations.\n *\n * Single-app configs are automatically wrapped as a workspace with one app.\n *\n * @example\n * ```ts\n * const { type, workspace } = await loadWorkspaceConfig();\n *\n * if (type === 'workspace') {\n * console.log('Multi-app workspace:', workspace.apps);\n * } else {\n * console.log('Single app wrapped as workspace');\n * }\n * ```\n */\nexport async function loadWorkspaceConfig(\n\tcwd: string = process.cwd(),\n): Promise<LoadedConfig> {\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\treturn processConfig(config, workspaceRoot);\n}\n\nexport interface AppConfigResult {\n\tappName: string;\n\tapp: NormalizedAppConfig;\n\tgkmConfig: GkmConfig;\n\tworkspace: NormalizedWorkspace;\n\tworkspaceRoot: string;\n\tappRoot: string;\n}\n\n/**\n * Load app-specific configuration from workspace.\n * Uses the app name from package.json to find the correct app config.\n *\n * @example\n * ```ts\n * // From apps/api directory with package.json: { \"name\": \"@myorg/api\" }\n * const { app, workspace, workspaceRoot } = await loadAppConfig();\n * console.log(app.routes); // './src/endpoints/**\\/*.ts'\n * ```\n */\nexport async function loadAppConfig(\n\tcwd: string = process.cwd(),\n): Promise<AppConfigResult> {\n\tconst appName = getAppNameFromCwd(cwd);\n\n\tif (!appName) {\n\t\tthrow new Error(\n\t\t\t'Could not determine app name. Ensure package.json exists with a \"name\" field.',\n\t\t);\n\t}\n\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\tconst loadedConfig = processConfig(config, workspaceRoot);\n\n\t// Find the app in workspace (apps is a Record<string, NormalizedAppConfig>)\n\tconst app = loadedConfig.workspace.apps[appName];\n\n\tif (!app) {\n\t\tconst availableApps = Object.keys(loadedConfig.workspace.apps).join(', ');\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" not found in workspace config. Available apps: ${availableApps}. ` +\n\t\t\t\t`Ensure the package.json name matches the app key in gkm.config.ts.`,\n\t\t);\n\t}\n\n\t// Get the app's GKM config using the helper\n\tconst gkmConfig = getAppGkmConfig(loadedConfig.workspace, appName);\n\n\tif (!gkmConfig) {\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" is not a backend app and cannot be run with gkm dev.`,\n\t\t);\n\t}\n\n\treturn {\n\t\tappName,\n\t\tapp,\n\t\tgkmConfig,\n\t\tworkspace: loadedConfig.workspace,\n\t\tworkspaceRoot,\n\t\tappRoot: join(workspaceRoot, app.path),\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config-Bayob8pB.cjs","names":["config: GkmConfig","configString: string","defaultAlias: string","cwd: string"],"sources":["../src/config.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, parse } from 'node:path';\nimport type { GkmConfig } from './types.js';\nimport {\n\tgetAppGkmConfig,\n\tisWorkspaceConfig,\n\ttype LoadedConfig,\n\ttype NormalizedAppConfig,\n\ttype NormalizedWorkspace,\n\tprocessConfig,\n\ttype WorkspaceConfig,\n} from './workspace/index.js';\n\nexport type { GkmConfig } from './types.js';\nexport type { LoadedConfig, WorkspaceConfig } from './workspace/index.js';\nexport { defineWorkspace } from './workspace/index.js';\n/**\n * Define GKM configuration with full TypeScript support.\n * This is an identity function that provides type safety and autocomplete.\n *\n * @example\n * ```ts\n * // gkm.config.ts\n * import { defineConfig } from '@geekmidas/cli/config';\n *\n * export default defineConfig({\n * routes: './src/endpoints/**\\/*.ts',\n * envParser: './src/config/env',\n * logger: './src/config/logger',\n * telescope: true,\n * });\n * ```\n */\nexport function defineConfig(config: GkmConfig): GkmConfig {\n\treturn config;\n}\n\nexport interface ParsedModuleConfig {\n\tpath: string;\n\timportPattern: string;\n}\n\n/**\n * Parse a module config string into path and import pattern.\n *\n * @param configString - Config string in format \"./path/to/module\" or \"./path/to/module#exportName\"\n * @param defaultAlias - The default alias name to use if no export name specified\n * @returns Object with path and import pattern\n *\n * @example\n * parseModuleConfig('./src/config/env', 'envParser')\n * // { path: './src/config/env', importPattern: 'envParser' }\n *\n * parseModuleConfig('./src/config/env#envParser', 'envParser')\n * // { path: './src/config/env', importPattern: '{ envParser }' }\n *\n * parseModuleConfig('./src/config/env#myEnv', 'envParser')\n * // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }\n */\nexport function parseModuleConfig(\n\tconfigString: string,\n\tdefaultAlias: string,\n): ParsedModuleConfig {\n\tconst parts = configString.split('#');\n\tconst path = parts[0] ?? configString;\n\tconst exportName = parts[1];\n\tconst importPattern = !exportName\n\t\t? defaultAlias\n\t\t: exportName === defaultAlias\n\t\t\t? `{ ${defaultAlias} }`\n\t\t\t: `{ ${exportName} as ${defaultAlias} }`;\n\n\treturn { path, importPattern };\n}\n\nexport interface ConfigDiscoveryResult {\n\tconfigPath: string;\n\tworkspaceRoot: string;\n}\n\n/**\n * Find and return the path to the config file.\n *\n * Resolution order:\n * 1. GKM_CONFIG_PATH env var (set by workspace dev command)\n * 2. Walk up directory tree from cwd\n */\nfunction findConfigPath(cwd: string): ConfigDiscoveryResult {\n\tconst files = ['gkm.config.json', 'gkm.config.ts', 'gkm.config.js'];\n\n\t// Check GKM_CONFIG_PATH env var first (set by workspace dev command)\n\tconst envConfigPath = process.env.GKM_CONFIG_PATH;\n\tif (envConfigPath && existsSync(envConfigPath)) {\n\t\treturn {\n\t\t\tconfigPath: envConfigPath,\n\t\t\tworkspaceRoot: dirname(envConfigPath),\n\t\t};\n\t}\n\n\t// Walk up directory tree to find config\n\tlet currentDir = cwd;\n\tconst { root } = parse(currentDir);\n\n\twhile (currentDir !== root) {\n\t\tfor (const file of files) {\n\t\t\tconst configPath = join(currentDir, file);\n\t\t\tif (existsSync(configPath)) {\n\t\t\t\treturn {\n\t\t\t\t\tconfigPath,\n\t\t\t\t\tworkspaceRoot: currentDir,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tcurrentDir = dirname(currentDir);\n\t}\n\n\tthrow new Error(\n\t\t'Configuration file not found. Please create gkm.config.json, gkm.config.ts, or gkm.config.js in the project root.',\n\t);\n}\n\n/**\n * Get app name from package.json in the given directory.\n * Handles scoped packages by extracting the name after the scope.\n *\n * @example\n * getAppNameFromCwd('/path/to/apps/api')\n * // package.json: { \"name\": \"@myorg/api\" }\n * // Returns: 'api'\n */\nexport function getAppNameFromCwd(cwd: string = process.cwd()): string | null {\n\tconst packageJsonPath = join(cwd, 'package.json');\n\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\t\tconst name = packageJson.name as string | undefined;\n\n\t\tif (!name) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Handle scoped packages: @scope/name -> name\n\t\tif (name.startsWith('@') && name.includes('/')) {\n\t\t\treturn name.split('/')[1] ?? null;\n\t\t}\n\n\t\treturn name;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\ninterface RawConfigResult {\n\tconfig: GkmConfig | WorkspaceConfig;\n\tworkspaceRoot: string;\n}\n\n/**\n * Load raw configuration from file.\n */\nasync function loadRawConfig(cwd: string): Promise<RawConfigResult> {\n\tconst { configPath, workspaceRoot } = findConfigPath(cwd);\n\n\ttry {\n\t\tconst config = await import(configPath);\n\t\treturn {\n\t\t\tconfig: config.default,\n\t\t\tworkspaceRoot,\n\t\t};\n\t} catch (error) {\n\t\tthrow new Error(`Failed to load config: ${(error as Error).message}`);\n\t}\n}\n\n/**\n * Load configuration file (single-app format).\n * For backwards compatibility with existing code.\n *\n * @deprecated Use loadWorkspaceConfig for new code\n */\nexport async function loadConfig(\n\tcwd: string = process.cwd(),\n): Promise<GkmConfig> {\n\tconst { config } = await loadRawConfig(cwd);\n\n\t// If it's a workspace config, throw an error\n\tif (isWorkspaceConfig(config)) {\n\t\tthrow new Error(\n\t\t\t'Workspace configuration detected. Use loadWorkspaceConfig() instead.',\n\t\t);\n\t}\n\n\treturn config;\n}\n\n/**\n * Load configuration file and process it as a workspace.\n * Works with both single-app and workspace configurations.\n *\n * Single-app configs are automatically wrapped as a workspace with one app.\n *\n * @example\n * ```ts\n * const { type, workspace } = await loadWorkspaceConfig();\n *\n * if (type === 'workspace') {\n * console.log('Multi-app workspace:', workspace.apps);\n * } else {\n * console.log('Single app wrapped as workspace');\n * }\n * ```\n */\nexport async function loadWorkspaceConfig(\n\tcwd: string = process.cwd(),\n): Promise<LoadedConfig> {\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\treturn processConfig(config, workspaceRoot);\n}\n\nexport interface AppConfigResult {\n\tappName: string;\n\tapp: NormalizedAppConfig;\n\tgkmConfig: GkmConfig;\n\tworkspace: NormalizedWorkspace;\n\tworkspaceRoot: string;\n\tappRoot: string;\n}\n\n/**\n * Load app-specific configuration from workspace.\n * Uses the app name from package.json to find the correct app config.\n *\n * @example\n * ```ts\n * // From apps/api directory with package.json: { \"name\": \"@myorg/api\" }\n * const { app, workspace, workspaceRoot } = await loadAppConfig();\n * console.log(app.routes); // './src/endpoints/**\\/*.ts'\n * ```\n */\nexport async function loadAppConfig(\n\tcwd: string = process.cwd(),\n): Promise<AppConfigResult> {\n\tconst appName = getAppNameFromCwd(cwd);\n\n\tif (!appName) {\n\t\tthrow new Error(\n\t\t\t'Could not determine app name. Ensure package.json exists with a \"name\" field.',\n\t\t);\n\t}\n\n\tconst { config, workspaceRoot } = await loadRawConfig(cwd);\n\tconst loadedConfig = processConfig(config, workspaceRoot);\n\n\t// Find the app in workspace (apps is a Record<string, NormalizedAppConfig>)\n\tconst app = loadedConfig.workspace.apps[appName];\n\n\tif (!app) {\n\t\tconst availableApps = Object.keys(loadedConfig.workspace.apps).join(', ');\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" not found in workspace config. Available apps: ${availableApps}. ` +\n\t\t\t\t`Ensure the package.json name matches the app key in gkm.config.ts.`,\n\t\t);\n\t}\n\n\t// Get the app's GKM config using the helper\n\tconst gkmConfig = getAppGkmConfig(loadedConfig.workspace, appName);\n\n\tif (!gkmConfig) {\n\t\tthrow new Error(\n\t\t\t`App \"${appName}\" is not a backend app and cannot be run with gkm dev.`,\n\t\t);\n\t}\n\n\treturn {\n\t\tappName,\n\t\tapp,\n\t\tgkmConfig,\n\t\tworkspace: loadedConfig.workspace,\n\t\tworkspaceRoot,\n\t\tappRoot: join(workspaceRoot, app.path),\n\t};\n}\n"],"mappings":"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"}
package/dist/config.cjs CHANGED
@@ -1,5 +1,5 @@
1
- const require_workspace = require('./workspace-BFRUOOrh.cjs');
2
- const require_config = require('./config-BGeJsW1r.cjs');
1
+ const require_workspace = require('./workspace-BMJE18LV.cjs');
2
+ const require_config = require('./config-Bayob8pB.cjs');
3
3
 
4
4
  exports.defineConfig = require_config.defineConfig;
5
5
  exports.defineWorkspace = require_workspace.defineWorkspace;
package/dist/config.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { GkmConfig } from "./types-l53qUmGt.cjs";
2
- import { LoadedConfig, NormalizedAppConfig, NormalizedWorkspace, WorkspaceConfig, defineWorkspace } from "./index-B5rGIc4g.cjs";
2
+ import { LoadedConfig, NormalizedAppConfig, NormalizedWorkspace, WorkspaceConfig, defineWorkspace } from "./index-CufAAnge.cjs";
3
3
 
4
4
  //#region src/config.d.ts
5
5
 
package/dist/config.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { GkmConfig } from "./types-BldpmqQX.mjs";
2
- import { LoadedConfig, NormalizedAppConfig, NormalizedWorkspace, WorkspaceConfig, defineWorkspace } from "./index-KFEbMIRa.mjs";
2
+ import { LoadedConfig, NormalizedAppConfig, NormalizedWorkspace, WorkspaceConfig, defineWorkspace } from "./index-Bi9vGQJy.mjs";
3
3
 
4
4
  //#region src/config.d.ts
5
5
 
package/dist/config.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { defineWorkspace } from "./workspace-DAxG3_H2.mjs";
2
- import { defineConfig, getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceConfig, parseModuleConfig } from "./config-C6awcFBx.mjs";
1
+ import { defineWorkspace } from "./workspace-CASoZOjs.mjs";
2
+ import { defineConfig, getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceConfig, parseModuleConfig } from "./config-BQ4a36Rq.mjs";
3
3
 
4
4
  export { defineConfig, defineWorkspace, getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceConfig, parseModuleConfig };
@@ -29,6 +29,8 @@ interface DnsVerificationRecord {
29
29
  interface DokployStageState {
30
30
  provider: 'dokploy';
31
31
  stage: string;
32
+ /** Dokploy project ID - created on first deploy */
33
+ projectId: string;
32
34
  environmentId: string;
33
35
  applications: Record<string, string>;
34
36
  services: {
@@ -332,10 +334,11 @@ declare const WorkspaceConfigSchema: z.ZodObject<{
332
334
  cloudflare: "cloudflare";
333
335
  }>>;
334
336
  dokploy: z.ZodOptional<z.ZodObject<{
335
- endpoint: z.ZodURL;
336
- projectId: z.ZodString;
337
+ endpoint: z.ZodOptional<z.ZodURL>;
338
+ endpoints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodURL>>;
337
339
  registry: z.ZodOptional<z.ZodString>;
338
340
  registryId: z.ZodOptional<z.ZodString>;
341
+ domains: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
339
342
  }, z.core.$strip>>;
340
343
  dns: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
341
344
  provider: z.ZodLiteral<"hostinger">;
@@ -734,28 +737,38 @@ type AppDomainConfig = string | Record<string, string>;
734
737
  *
735
738
  * Configures how the workspace is deployed to a Dokploy server.
736
739
  * One workspace maps to one Dokploy project with stage-based environments.
740
+ * Project IDs are stored in deploy state (not config) and created on first deploy.
737
741
  *
738
- * @example
742
+ * @example Single endpoint for all stages:
739
743
  * ```ts
740
744
  * deploy: {
741
745
  * default: 'dokploy',
742
746
  * dokploy: {
743
747
  * endpoint: 'https://dokploy.myserver.com',
744
- * projectId: 'proj_abc123',
745
748
  * registry: 'ghcr.io/myorg',
746
- * domains: {
747
- * development: 'dev.myapp.com',
748
- * production: 'myapp.com',
749
+ * },
750
+ * }
751
+ * ```
752
+ *
753
+ * @example Per-stage endpoints (different Dokploy servers):
754
+ * ```ts
755
+ * deploy: {
756
+ * default: 'dokploy',
757
+ * dokploy: {
758
+ * endpoints: {
759
+ * development: 'https://dev-dokploy.myserver.com',
760
+ * production: 'https://dokploy.myserver.com',
749
761
  * },
762
+ * registry: 'ghcr.io/myorg',
750
763
  * },
751
764
  * }
752
765
  * ```
753
766
  */
754
767
  interface DokployWorkspaceConfig {
755
- /** Dokploy API endpoint (e.g., 'https://dokploy.myserver.com') */
756
- endpoint: string;
757
- /** Project ID in Dokploy (auto-created on first deploy) */
758
- projectId: string;
768
+ /** Dokploy API endpoint for all stages */
769
+ endpoint?: string;
770
+ /** Per-stage Dokploy API endpoints (overrides endpoint) */
771
+ endpoints?: Record<string, string>;
759
772
  /** Container registry for Docker images (e.g., 'ghcr.io/myorg') */
760
773
  registry?: string;
761
774
  /** Registry ID in Dokploy (auto-configured) */
@@ -1205,6 +1218,8 @@ type WorkspaceInput<TApps extends AppsRecord> = {
1205
1218
  services?: ServicesConfig;
1206
1219
  /** Encrypted secrets configuration */
1207
1220
  secrets?: SecretsConfig;
1221
+ /** State provider configuration (local filesystem by default, or SSM for team collaboration) */
1222
+ state?: StateConfig;
1208
1223
  };
1209
1224
  /**
1210
1225
  * Extract app names from apps record.
@@ -1222,6 +1237,7 @@ type InferredWorkspaceConfig<TApps extends AppsRecord> = {
1222
1237
  deploy?: DeployConfig;
1223
1238
  services?: ServicesConfig;
1224
1239
  secrets?: SecretsConfig;
1240
+ state?: StateConfig;
1225
1241
  };
1226
1242
  /** @deprecated Use WorkspaceInput */
1227
1243
 
@@ -1313,6 +1329,8 @@ interface WorkspaceConfig {
1313
1329
  services?: ServicesConfig;
1314
1330
  /** Encrypted secrets configuration */
1315
1331
  secrets?: SecretsConfig;
1332
+ /** State provider configuration (local filesystem by default, or SSM for team collaboration) */
1333
+ state?: StateConfig;
1316
1334
  }
1317
1335
  /**
1318
1336
  * Normalized app configuration with resolved defaults.
@@ -1462,8 +1480,38 @@ declare function getAppBuildOrder(workspace: NormalizedWorkspace): string[];
1462
1480
  * Each dependency gets a {DEP_NAME}_URL variable.
1463
1481
  */
1464
1482
  declare function getDependencyEnvVars(workspace: NormalizedWorkspace, appName: string, urlPrefix?: string): Record<string, string>;
1483
+ /**
1484
+ * Resolve the Dokploy endpoint for a specific stage.
1485
+ *
1486
+ * Uses per-stage endpoint from `endpoints` if available,
1487
+ * otherwise falls back to the global `endpoint`.
1488
+ *
1489
+ * @param dokployConfig - Dokploy workspace configuration
1490
+ * @param stage - Deployment stage (e.g., 'development', 'production')
1491
+ * @returns The endpoint URL for the stage, or undefined if not configured
1492
+ *
1493
+ * @example
1494
+ * ```ts
1495
+ * // With per-stage endpoints
1496
+ * const config = {
1497
+ * endpoints: {
1498
+ * development: 'https://dev.dokploy.example.com:3000',
1499
+ * production: 'https://prod.dokploy.example.com:3000',
1500
+ * },
1501
+ * };
1502
+ * getEndpointForStage(config, 'production'); // => 'https://prod.dokploy.example.com:3000'
1503
+ *
1504
+ * // With single endpoint
1505
+ * const config = { endpoint: 'https://dokploy.example.com:3000' };
1506
+ * getEndpointForStage(config, 'production'); // => 'https://dokploy.example.com:3000'
1507
+ * ```
1508
+ */
1509
+ declare function getEndpointForStage(dokployConfig: {
1510
+ endpoint?: string;
1511
+ endpoints?: Record<string, string>;
1512
+ } | undefined, stage: string): string | undefined;
1465
1513
  //# sourceMappingURL=index.d.ts.map
1466
1514
 
1467
1515
  //#endregion
1468
- export { AppConfig, AppConfigInput, AppInput, AppsRecord, BackendFramework, ClientConfig, ConstrainedApps, DeployConfig, DeployTarget, DokployWorkspaceConfig, FrontendFramework, InferAppNames, InferredWorkspaceConfig, LoadedConfig, MailServiceConfig, ModelsConfig, NormalizedAppConfig, NormalizedWorkspace, PHASE_2_DEPLOY_TARGETS, SUPPORTED_DEPLOY_TARGETS, SecretsConfig, ServiceImageConfig, ServicesConfig, SharedConfig, WorkspaceConfig, WorkspaceConfigSchema, WorkspaceInput, defineWorkspace, formatValidationErrors, getAppBuildOrder, getAppGkmConfig, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported, isPhase2DeployTarget, isWorkspaceConfig, normalizeWorkspace, processConfig, safeValidateWorkspaceConfig, validateWorkspaceConfig, wrapSingleAppAsWorkspace };
1469
- //# sourceMappingURL=index-KFEbMIRa.d.mts.map
1516
+ export { AppConfig, AppConfigInput, AppInput, AppsRecord, BackendFramework, ClientConfig, ConstrainedApps, DeployConfig, DeployTarget, DokployWorkspaceConfig, FrontendFramework, InferAppNames, InferredWorkspaceConfig, LoadedConfig, MailServiceConfig, ModelsConfig, NormalizedAppConfig, NormalizedWorkspace, PHASE_2_DEPLOY_TARGETS, SUPPORTED_DEPLOY_TARGETS, SecretsConfig, ServiceImageConfig, ServicesConfig, SharedConfig, WorkspaceConfig, WorkspaceConfigSchema, WorkspaceInput, defineWorkspace, formatValidationErrors, getAppBuildOrder, getAppGkmConfig, getDependencyEnvVars, getDeployTargetError, getEndpointForStage, isDeployTargetSupported, isPhase2DeployTarget, isWorkspaceConfig, normalizeWorkspace, processConfig, safeValidateWorkspaceConfig, validateWorkspaceConfig, wrapSingleAppAsWorkspace };
1517
+ //# sourceMappingURL=index-Bi9vGQJy.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Bi9vGQJy.d.mts","names":[],"sources":["../src/deploy/state.ts","../src/deploy/StateProvider.ts","../src/workspace/schema.ts","../src/workspace/types.ts","../src/workspace/index.ts"],"sourcesContent":[],"mappings":"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"}
@@ -29,6 +29,8 @@ interface DnsVerificationRecord {
29
29
  interface DokployStageState {
30
30
  provider: 'dokploy';
31
31
  stage: string;
32
+ /** Dokploy project ID - created on first deploy */
33
+ projectId: string;
32
34
  environmentId: string;
33
35
  applications: Record<string, string>;
34
36
  services: {
@@ -332,10 +334,11 @@ declare const WorkspaceConfigSchema: z.ZodObject<{
332
334
  cloudflare: "cloudflare";
333
335
  }>>;
334
336
  dokploy: z.ZodOptional<z.ZodObject<{
335
- endpoint: z.ZodURL;
336
- projectId: z.ZodString;
337
+ endpoint: z.ZodOptional<z.ZodURL>;
338
+ endpoints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodURL>>;
337
339
  registry: z.ZodOptional<z.ZodString>;
338
340
  registryId: z.ZodOptional<z.ZodString>;
341
+ domains: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
339
342
  }, z.core.$strip>>;
340
343
  dns: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
341
344
  provider: z.ZodLiteral<"hostinger">;
@@ -734,28 +737,38 @@ type AppDomainConfig = string | Record<string, string>;
734
737
  *
735
738
  * Configures how the workspace is deployed to a Dokploy server.
736
739
  * One workspace maps to one Dokploy project with stage-based environments.
740
+ * Project IDs are stored in deploy state (not config) and created on first deploy.
737
741
  *
738
- * @example
742
+ * @example Single endpoint for all stages:
739
743
  * ```ts
740
744
  * deploy: {
741
745
  * default: 'dokploy',
742
746
  * dokploy: {
743
747
  * endpoint: 'https://dokploy.myserver.com',
744
- * projectId: 'proj_abc123',
745
748
  * registry: 'ghcr.io/myorg',
746
- * domains: {
747
- * development: 'dev.myapp.com',
748
- * production: 'myapp.com',
749
+ * },
750
+ * }
751
+ * ```
752
+ *
753
+ * @example Per-stage endpoints (different Dokploy servers):
754
+ * ```ts
755
+ * deploy: {
756
+ * default: 'dokploy',
757
+ * dokploy: {
758
+ * endpoints: {
759
+ * development: 'https://dev-dokploy.myserver.com',
760
+ * production: 'https://dokploy.myserver.com',
749
761
  * },
762
+ * registry: 'ghcr.io/myorg',
750
763
  * },
751
764
  * }
752
765
  * ```
753
766
  */
754
767
  interface DokployWorkspaceConfig {
755
- /** Dokploy API endpoint (e.g., 'https://dokploy.myserver.com') */
756
- endpoint: string;
757
- /** Project ID in Dokploy (auto-created on first deploy) */
758
- projectId: string;
768
+ /** Dokploy API endpoint for all stages */
769
+ endpoint?: string;
770
+ /** Per-stage Dokploy API endpoints (overrides endpoint) */
771
+ endpoints?: Record<string, string>;
759
772
  /** Container registry for Docker images (e.g., 'ghcr.io/myorg') */
760
773
  registry?: string;
761
774
  /** Registry ID in Dokploy (auto-configured) */
@@ -1205,6 +1218,8 @@ type WorkspaceInput<TApps extends AppsRecord> = {
1205
1218
  services?: ServicesConfig;
1206
1219
  /** Encrypted secrets configuration */
1207
1220
  secrets?: SecretsConfig;
1221
+ /** State provider configuration (local filesystem by default, or SSM for team collaboration) */
1222
+ state?: StateConfig;
1208
1223
  };
1209
1224
  /**
1210
1225
  * Extract app names from apps record.
@@ -1222,6 +1237,7 @@ type InferredWorkspaceConfig<TApps extends AppsRecord> = {
1222
1237
  deploy?: DeployConfig;
1223
1238
  services?: ServicesConfig;
1224
1239
  secrets?: SecretsConfig;
1240
+ state?: StateConfig;
1225
1241
  };
1226
1242
  /** @deprecated Use WorkspaceInput */
1227
1243
 
@@ -1313,6 +1329,8 @@ interface WorkspaceConfig {
1313
1329
  services?: ServicesConfig;
1314
1330
  /** Encrypted secrets configuration */
1315
1331
  secrets?: SecretsConfig;
1332
+ /** State provider configuration (local filesystem by default, or SSM for team collaboration) */
1333
+ state?: StateConfig;
1316
1334
  }
1317
1335
  /**
1318
1336
  * Normalized app configuration with resolved defaults.
@@ -1462,8 +1480,38 @@ declare function getAppBuildOrder(workspace: NormalizedWorkspace): string[];
1462
1480
  * Each dependency gets a {DEP_NAME}_URL variable.
1463
1481
  */
1464
1482
  declare function getDependencyEnvVars(workspace: NormalizedWorkspace, appName: string, urlPrefix?: string): Record<string, string>;
1483
+ /**
1484
+ * Resolve the Dokploy endpoint for a specific stage.
1485
+ *
1486
+ * Uses per-stage endpoint from `endpoints` if available,
1487
+ * otherwise falls back to the global `endpoint`.
1488
+ *
1489
+ * @param dokployConfig - Dokploy workspace configuration
1490
+ * @param stage - Deployment stage (e.g., 'development', 'production')
1491
+ * @returns The endpoint URL for the stage, or undefined if not configured
1492
+ *
1493
+ * @example
1494
+ * ```ts
1495
+ * // With per-stage endpoints
1496
+ * const config = {
1497
+ * endpoints: {
1498
+ * development: 'https://dev.dokploy.example.com:3000',
1499
+ * production: 'https://prod.dokploy.example.com:3000',
1500
+ * },
1501
+ * };
1502
+ * getEndpointForStage(config, 'production'); // => 'https://prod.dokploy.example.com:3000'
1503
+ *
1504
+ * // With single endpoint
1505
+ * const config = { endpoint: 'https://dokploy.example.com:3000' };
1506
+ * getEndpointForStage(config, 'production'); // => 'https://dokploy.example.com:3000'
1507
+ * ```
1508
+ */
1509
+ declare function getEndpointForStage(dokployConfig: {
1510
+ endpoint?: string;
1511
+ endpoints?: Record<string, string>;
1512
+ } | undefined, stage: string): string | undefined;
1465
1513
  //# sourceMappingURL=index.d.ts.map
1466
1514
 
1467
1515
  //#endregion
1468
- export { AppConfig, AppConfigInput, AppInput, AppsRecord, BackendFramework, ClientConfig, ConstrainedApps, DeployConfig, DeployTarget, DokployWorkspaceConfig, FrontendFramework, InferAppNames, InferredWorkspaceConfig, LoadedConfig, MailServiceConfig, ModelsConfig, NormalizedAppConfig, NormalizedWorkspace, PHASE_2_DEPLOY_TARGETS, SUPPORTED_DEPLOY_TARGETS, SecretsConfig, ServiceImageConfig, ServicesConfig, SharedConfig, WorkspaceConfig, WorkspaceConfigSchema, WorkspaceInput, defineWorkspace, formatValidationErrors, getAppBuildOrder, getAppGkmConfig, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported, isPhase2DeployTarget, isWorkspaceConfig, normalizeWorkspace, processConfig, safeValidateWorkspaceConfig, validateWorkspaceConfig, wrapSingleAppAsWorkspace };
1469
- //# sourceMappingURL=index-B5rGIc4g.d.cts.map
1516
+ export { AppConfig, AppConfigInput, AppInput, AppsRecord, BackendFramework, ClientConfig, ConstrainedApps, DeployConfig, DeployTarget, DokployWorkspaceConfig, FrontendFramework, InferAppNames, InferredWorkspaceConfig, LoadedConfig, MailServiceConfig, ModelsConfig, NormalizedAppConfig, NormalizedWorkspace, PHASE_2_DEPLOY_TARGETS, SUPPORTED_DEPLOY_TARGETS, SecretsConfig, ServiceImageConfig, ServicesConfig, SharedConfig, WorkspaceConfig, WorkspaceConfigSchema, WorkspaceInput, defineWorkspace, formatValidationErrors, getAppBuildOrder, getAppGkmConfig, getDependencyEnvVars, getDeployTargetError, getEndpointForStage, isDeployTargetSupported, isPhase2DeployTarget, isWorkspaceConfig, normalizeWorkspace, processConfig, safeValidateWorkspaceConfig, validateWorkspaceConfig, wrapSingleAppAsWorkspace };
1517
+ //# sourceMappingURL=index-CufAAnge.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CufAAnge.d.cts","names":[],"sources":["../src/deploy/state.ts","../src/deploy/StateProvider.ts","../src/workspace/schema.ts","../src/workspace/types.ts","../src/workspace/index.ts"],"sourcesContent":[],"mappings":"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"}