zephyr-agent 0.0.54 → 0.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/build-context/detect-monorepo.d.ts +14 -0
- package/dist/lib/build-context/detect-monorepo.js +109 -0
- package/dist/lib/build-context/detect-monorepo.js.map +1 -0
- package/dist/lib/build-context/ze-util-get-git-info.js +280 -18
- package/dist/lib/build-context/ze-util-get-git-info.js.map +1 -1
- package/dist/lib/build-context/ze-util-read-package-json.js +5 -0
- package/dist/lib/build-context/ze-util-read-package-json.js.map +1 -1
- package/dist/lib/deployment/common-upload.strategy.d.ts +2 -0
- package/dist/lib/deployment/{cloudflare.strategy.js → common-upload.strategy.js} +3 -3
- package/dist/lib/deployment/common-upload.strategy.js.map +1 -0
- package/dist/lib/deployment/get-upload-strategy.js +3 -4
- package/dist/lib/deployment/get-upload-strategy.js.map +1 -1
- package/dist/lib/deployment/index.d.ts +2 -3
- package/dist/lib/deployment/index.js +5 -4
- package/dist/lib/deployment/index.js.map +1 -1
- package/dist/lib/deployment/upload-base/index.d.ts +2 -0
- package/dist/lib/deployment/upload-base/index.js +6 -0
- package/dist/lib/deployment/upload-base/index.js.map +1 -0
- package/dist/lib/errors/zephyr-error.js +4 -1
- package/dist/lib/errors/zephyr-error.js.map +1 -1
- package/dist/lib/node-persist/app-deploy-result-cache.d.ts +8 -5
- package/dist/lib/node-persist/app-deploy-result-cache.js +19 -0
- package/dist/lib/node-persist/app-deploy-result-cache.js.map +1 -1
- package/dist/lib/node-persist/storage-keys.js +1 -1
- package/dist/lib/node-persist/storage-keys.js.map +1 -1
- package/dist/lib/node-persist/upload-provider-options.d.ts +3 -5
- package/dist/lib/node-persist/upload-provider-options.js +1 -0
- package/dist/lib/node-persist/upload-provider-options.js.map +1 -1
- package/dist/lib/transformers/ze-build-snapshot.js +13 -1
- package/dist/lib/transformers/ze-build-snapshot.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/zephyr-engine/index.js +12 -4
- package/dist/zephyr-engine/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/lib/deployment/cloudflare.strategy.d.ts +0 -2
- package/dist/lib/deployment/cloudflare.strategy.js.map +0 -1
- package/dist/lib/deployment/fastly.strategy.d.ts +0 -2
- package/dist/lib/deployment/fastly.strategy.js +0 -18
- package/dist/lib/deployment/fastly.strategy.js.map +0 -1
- package/dist/lib/deployment/netlify.strategy.d.ts +0 -2
- package/dist/lib/deployment/netlify.strategy.js +0 -17
- package/dist/lib/deployment/netlify.strategy.js.map +0 -1
package/README.md
CHANGED
|
@@ -95,6 +95,105 @@ interface ZephyrAgentConfig {
|
|
|
95
95
|
}
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
+
### Git Repository Requirements
|
|
99
|
+
|
|
100
|
+
**IMPORTANT**: Zephyr requires a properly initialized Git repository with a remote origin for production deployments.
|
|
101
|
+
|
|
102
|
+
#### Git Information Handling
|
|
103
|
+
|
|
104
|
+
When Zephyr cannot find a Git repository with remote origin, it will:
|
|
105
|
+
|
|
106
|
+
1. **Automatic Package.json-Based Naming**:
|
|
107
|
+
|
|
108
|
+
- Extract organization, project, and app names from your `package.json`
|
|
109
|
+
- Use authenticated user's username as the organization for personal Zephyr org
|
|
110
|
+
- Follow intelligent naming conventions based on package structure
|
|
111
|
+
- No user prompts or environment variables required
|
|
112
|
+
|
|
113
|
+
2. **Enhanced Naming Logic**:
|
|
114
|
+
- **Scoped packages** (`@scope/name`): project = scope, app = name
|
|
115
|
+
- **With root package.json**:
|
|
116
|
+
- If root is scoped (`@scope/name`): project = scope, app = current package name
|
|
117
|
+
- Otherwise: project = root package name, app = current package name
|
|
118
|
+
- **Fallback to directory name**: If no root package.json found, uses directory name as project
|
|
119
|
+
- **Single package**: project = app = package name
|
|
120
|
+
- **Organization**: Uses authenticated user's username (sanitized for URL safety)
|
|
121
|
+
|
|
122
|
+
#### Example Scenarios
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Recommended: Proper Git setup
|
|
126
|
+
git init
|
|
127
|
+
git remote add origin git@github.com:YOUR_ORG/YOUR_REPO.git
|
|
128
|
+
git add . && git commit -m "Initial commit"
|
|
129
|
+
npm run build # Works perfectly with full Git context
|
|
130
|
+
|
|
131
|
+
# Automatic fallback (works seamlessly)
|
|
132
|
+
# No git repository - uses package.json naming
|
|
133
|
+
npm run build # Automatically determines naming from package.json
|
|
134
|
+
|
|
135
|
+
# Examples of automatic naming:
|
|
136
|
+
# package.json: { "name": "@my-company/my-app" }
|
|
137
|
+
# → org: "jwt-username", project: "my-company", app: "my-app"
|
|
138
|
+
|
|
139
|
+
# package.json: { "name": "my-project" } (no root package.json)
|
|
140
|
+
# → org: "jwt-username", project: "my-project", app: "my-project"
|
|
141
|
+
|
|
142
|
+
# package.json: { "name": "my-app" } (root package.json: { "name": "my-workspace" })
|
|
143
|
+
# → org: "jwt-username", project: "my-workspace", app: "my-app"
|
|
144
|
+
|
|
145
|
+
# package.json: { "name": "my-app" } (root package.json: { "name": "@company/monorepo" })
|
|
146
|
+
# → org: "jwt-username", project: "company", app: "my-app"
|
|
147
|
+
|
|
148
|
+
# package.json: { "name": "my-app" } (no root package.json found)
|
|
149
|
+
# → org: "jwt-username", project: "current-directory-name", app: "my-app"
|
|
150
|
+
|
|
151
|
+
# Special characters in username get sanitized:
|
|
152
|
+
# Username: "Néstor López" → org: "n-stor-l-pez"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### Why Git is Required
|
|
156
|
+
|
|
157
|
+
Zephyr uses Git information to:
|
|
158
|
+
|
|
159
|
+
- Determine organization and project structure
|
|
160
|
+
- Track deployment versions and commits
|
|
161
|
+
- Enable collaboration features
|
|
162
|
+
- Provide proper deployment metadata
|
|
163
|
+
|
|
164
|
+
Without Git, Zephyr cannot guarantee proper functionality, especially for:
|
|
165
|
+
|
|
166
|
+
- Production deployments
|
|
167
|
+
- Team collaboration
|
|
168
|
+
- Version tracking
|
|
169
|
+
- Rollback capabilities
|
|
170
|
+
|
|
171
|
+
#### Package.json-Based Naming (Non-Git Environments)
|
|
172
|
+
|
|
173
|
+
When Git is not available (e.g., AI coding tools, quick prototypes), Zephyr automatically extracts naming information from your `package.json` structure:
|
|
174
|
+
|
|
175
|
+
**Automatic Organization Detection:**
|
|
176
|
+
|
|
177
|
+
- Uses the authenticated user's name from your authentication token
|
|
178
|
+
- Requires valid authentication to determine organization
|
|
179
|
+
|
|
180
|
+
**Project and App Naming Logic:**
|
|
181
|
+
|
|
182
|
+
1. **Scoped Package** (`@company/app-name`):
|
|
183
|
+
|
|
184
|
+
- Project: `company` (scope without @)
|
|
185
|
+
- App: `app-name`
|
|
186
|
+
|
|
187
|
+
2. **Monorepo Structure** (root `package.json` exists):
|
|
188
|
+
|
|
189
|
+
- If root is scoped (`@company/monorepo`): Project = `company`, App = current package name
|
|
190
|
+
- Otherwise: Project = root package name, App = current package name
|
|
191
|
+
- If no root package.json found: Project = current directory name, App = current package name
|
|
192
|
+
|
|
193
|
+
3. **Single Package**:
|
|
194
|
+
- Project: Package name
|
|
195
|
+
- App: Package name
|
|
196
|
+
|
|
98
197
|
## Internal APIs
|
|
99
198
|
|
|
100
199
|
### Build Context API
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
export { onIndexHtmlResolved, resolveIndexHtml } from './lib/hacks/resolve-index-html';
|
|
2
2
|
export { getPartialAssetMap, removePartialAssetMap, savePartialAssetMap, } from './lib/node-persist/partial-assets-map';
|
|
3
|
-
export {
|
|
3
|
+
export { ZeErrors, ZephyrError } from './lib/errors';
|
|
4
|
+
export { getAllAppDeployResults, getAllDeployedApps, getAppDeployResult, type DeployResult, } from './lib/node-persist/app-deploy-result-cache';
|
|
4
5
|
export { ze_log } from './lib/logging';
|
|
5
6
|
export { logFn } from './lib/logging/ze-log-event';
|
|
7
|
+
export { applyBaseHrefToAssets, normalizeBasePath, } from './lib/transformers/ze-basehref-handler';
|
|
8
|
+
export { zeBuildAssets } from './lib/transformers/ze-build-assets';
|
|
6
9
|
export { buildAssetsMap, type ZeBuildAssetsMap, } from './lib/transformers/ze-build-assets-map';
|
|
7
10
|
export { zeBuildDashData } from './lib/transformers/ze-build-dash-data';
|
|
8
|
-
export { zeBuildAssets } from './lib/transformers/ze-build-assets';
|
|
9
|
-
export { normalizeBasePath, applyBaseHrefToAssets, } from './lib/transformers/ze-basehref-handler';
|
|
10
11
|
export { DEFAULT_AUTH_COMPLETION_TIMEOUT_MS, TOKEN_EXPIRY } from './lib/auth/auth-flags';
|
|
11
|
-
export {
|
|
12
|
-
export type { ZeResolvedDependency } from './zephyr-engine/resolve_remote_dependency';
|
|
12
|
+
export { is_zephyr_dependency_pair, readPackageJson, ZephyrEngine, type ZeDependencyPair, type ZephyrDependencies, type ZephyrEngineOptions, } from './zephyr-engine';
|
|
13
13
|
export type { Platform } from './zephyr-engine';
|
|
14
|
+
export type { ZeResolvedDependency } from './zephyr-engine/resolve_remote_dependency';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.ZephyrEngine = exports.readPackageJson = exports.is_zephyr_dependency_pair = exports.TOKEN_EXPIRY = exports.DEFAULT_AUTH_COMPLETION_TIMEOUT_MS = exports.zeBuildDashData = exports.buildAssetsMap = exports.zeBuildAssets = exports.normalizeBasePath = exports.applyBaseHrefToAssets = exports.logFn = exports.ze_log = exports.getAppDeployResult = exports.getAllDeployedApps = exports.getAllAppDeployResults = exports.ZephyrError = exports.ZeErrors = exports.savePartialAssetMap = exports.removePartialAssetMap = exports.getPartialAssetMap = exports.resolveIndexHtml = exports.onIndexHtmlResolved = void 0;
|
|
4
4
|
// hack for angular
|
|
5
5
|
var resolve_index_html_1 = require("./lib/hacks/resolve-index-html");
|
|
6
6
|
Object.defineProperty(exports, "onIndexHtmlResolved", { enumerable: true, get: function () { return resolve_index_html_1.onIndexHtmlResolved; } });
|
|
@@ -12,30 +12,35 @@ Object.defineProperty(exports, "removePartialAssetMap", { enumerable: true, get:
|
|
|
12
12
|
Object.defineProperty(exports, "savePartialAssetMap", { enumerable: true, get: function () { return partial_assets_map_1.savePartialAssetMap; } });
|
|
13
13
|
// errors
|
|
14
14
|
var errors_1 = require("./lib/errors");
|
|
15
|
-
Object.defineProperty(exports, "ZephyrError", { enumerable: true, get: function () { return errors_1.ZephyrError; } });
|
|
16
15
|
Object.defineProperty(exports, "ZeErrors", { enumerable: true, get: function () { return errors_1.ZeErrors; } });
|
|
16
|
+
Object.defineProperty(exports, "ZephyrError", { enumerable: true, get: function () { return errors_1.ZephyrError; } });
|
|
17
|
+
// deploy result
|
|
18
|
+
var app_deploy_result_cache_1 = require("./lib/node-persist/app-deploy-result-cache");
|
|
19
|
+
Object.defineProperty(exports, "getAllAppDeployResults", { enumerable: true, get: function () { return app_deploy_result_cache_1.getAllAppDeployResults; } });
|
|
20
|
+
Object.defineProperty(exports, "getAllDeployedApps", { enumerable: true, get: function () { return app_deploy_result_cache_1.getAllDeployedApps; } });
|
|
21
|
+
Object.defineProperty(exports, "getAppDeployResult", { enumerable: true, get: function () { return app_deploy_result_cache_1.getAppDeployResult; } });
|
|
17
22
|
// logger
|
|
18
23
|
var logging_1 = require("./lib/logging");
|
|
19
24
|
Object.defineProperty(exports, "ze_log", { enumerable: true, get: function () { return logging_1.ze_log; } });
|
|
20
25
|
var ze_log_event_1 = require("./lib/logging/ze-log-event");
|
|
21
26
|
Object.defineProperty(exports, "logFn", { enumerable: true, get: function () { return ze_log_event_1.logFn; } });
|
|
22
27
|
// default transformers
|
|
28
|
+
var ze_basehref_handler_1 = require("./lib/transformers/ze-basehref-handler");
|
|
29
|
+
Object.defineProperty(exports, "applyBaseHrefToAssets", { enumerable: true, get: function () { return ze_basehref_handler_1.applyBaseHrefToAssets; } });
|
|
30
|
+
Object.defineProperty(exports, "normalizeBasePath", { enumerable: true, get: function () { return ze_basehref_handler_1.normalizeBasePath; } });
|
|
31
|
+
var ze_build_assets_1 = require("./lib/transformers/ze-build-assets");
|
|
32
|
+
Object.defineProperty(exports, "zeBuildAssets", { enumerable: true, get: function () { return ze_build_assets_1.zeBuildAssets; } });
|
|
23
33
|
var ze_build_assets_map_1 = require("./lib/transformers/ze-build-assets-map");
|
|
24
34
|
Object.defineProperty(exports, "buildAssetsMap", { enumerable: true, get: function () { return ze_build_assets_map_1.buildAssetsMap; } });
|
|
25
35
|
var ze_build_dash_data_1 = require("./lib/transformers/ze-build-dash-data");
|
|
26
36
|
Object.defineProperty(exports, "zeBuildDashData", { enumerable: true, get: function () { return ze_build_dash_data_1.zeBuildDashData; } });
|
|
27
|
-
var ze_build_assets_1 = require("./lib/transformers/ze-build-assets");
|
|
28
|
-
Object.defineProperty(exports, "zeBuildAssets", { enumerable: true, get: function () { return ze_build_assets_1.zeBuildAssets; } });
|
|
29
|
-
var ze_basehref_handler_1 = require("./lib/transformers/ze-basehref-handler");
|
|
30
|
-
Object.defineProperty(exports, "normalizeBasePath", { enumerable: true, get: function () { return ze_basehref_handler_1.normalizeBasePath; } });
|
|
31
|
-
Object.defineProperty(exports, "applyBaseHrefToAssets", { enumerable: true, get: function () { return ze_basehref_handler_1.applyBaseHrefToAssets; } });
|
|
32
37
|
// Auth related exports
|
|
33
38
|
var auth_flags_1 = require("./lib/auth/auth-flags");
|
|
34
39
|
Object.defineProperty(exports, "DEFAULT_AUTH_COMPLETION_TIMEOUT_MS", { enumerable: true, get: function () { return auth_flags_1.DEFAULT_AUTH_COMPLETION_TIMEOUT_MS; } });
|
|
35
40
|
Object.defineProperty(exports, "TOKEN_EXPIRY", { enumerable: true, get: function () { return auth_flags_1.TOKEN_EXPIRY; } });
|
|
36
41
|
// Zephyr Edge is the main class which should be used
|
|
37
42
|
var zephyr_engine_1 = require("./zephyr-engine");
|
|
38
|
-
Object.defineProperty(exports, "ZephyrEngine", { enumerable: true, get: function () { return zephyr_engine_1.ZephyrEngine; } });
|
|
39
43
|
Object.defineProperty(exports, "is_zephyr_dependency_pair", { enumerable: true, get: function () { return zephyr_engine_1.is_zephyr_dependency_pair; } });
|
|
40
44
|
Object.defineProperty(exports, "readPackageJson", { enumerable: true, get: function () { return zephyr_engine_1.readPackageJson; } });
|
|
45
|
+
Object.defineProperty(exports, "ZephyrEngine", { enumerable: true, get: function () { return zephyr_engine_1.ZephyrEngine; } });
|
|
41
46
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mBAAmB;AACnB,qEAAuF;AAA9E,yHAAA,mBAAmB,OAAA;AAAE,sHAAA,gBAAgB,OAAA;AAC9C,sBAAsB;AACtB,4EAI+C;AAH7C,wHAAA,kBAAkB,OAAA;AAClB,2HAAA,qBAAqB,OAAA;AACrB,yHAAA,mBAAmB,OAAA;AAGrB,SAAS;AACT,uCAAqD;AAA5C,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mBAAmB;AACnB,qEAAuF;AAA9E,yHAAA,mBAAmB,OAAA;AAAE,sHAAA,gBAAgB,OAAA;AAC9C,sBAAsB;AACtB,4EAI+C;AAH7C,wHAAA,kBAAkB,OAAA;AAClB,2HAAA,qBAAqB,OAAA;AACrB,yHAAA,mBAAmB,OAAA;AAGrB,SAAS;AACT,uCAAqD;AAA5C,kGAAA,QAAQ,OAAA;AAAE,qGAAA,WAAW,OAAA;AAE9B,gBAAgB;AAChB,sFAKoD;AAJlD,iIAAA,sBAAsB,OAAA;AACtB,6HAAA,kBAAkB,OAAA;AAClB,6HAAA,kBAAkB,OAAA;AAIpB,SAAS;AACT,yCAAuC;AAA9B,iGAAA,MAAM,OAAA;AACf,2DAAmD;AAA1C,qGAAA,KAAK,OAAA;AAEd,uBAAuB;AACvB,8EAGgD;AAF9C,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AAEnB,sEAAmE;AAA1D,gHAAA,aAAa,OAAA;AACtB,8EAGgD;AAF9C,qHAAA,cAAc,OAAA;AAGhB,4EAAwE;AAA/D,qHAAA,eAAe,OAAA;AAExB,uBAAuB;AACvB,oDAAyF;AAAhF,gIAAA,kCAAkC,OAAA;AAAE,0GAAA,YAAY,OAAA;AAEzD,qDAAqD;AACrD,iDAOyB;AANvB,0HAAA,yBAAyB,OAAA;AACzB,gHAAA,eAAe,OAAA;AACf,6GAAA,YAAY,OAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type MonorepoType = 'pnpm' | 'yarn' | 'npm' | 'lerna' | 'nx' | 'rush' | 'none';
|
|
2
|
+
export interface MonorepoInfo {
|
|
3
|
+
type: MonorepoType;
|
|
4
|
+
root: string;
|
|
5
|
+
configFile?: string;
|
|
6
|
+
workspaces?: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Detects if the current project is part of a monorepo and returns information about it.
|
|
10
|
+
* Traverses up the directory tree looking for monorepo configuration files.
|
|
11
|
+
*/
|
|
12
|
+
export declare function detectMonorepo(startPath: string): Promise<MonorepoInfo>;
|
|
13
|
+
/** Gets the root package.json from a monorepo root directory */
|
|
14
|
+
export declare function getMonorepoRootPackageJson(monorepoRoot: string): Promise<Record<string, unknown> | null>;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectMonorepo = detectMonorepo;
|
|
4
|
+
exports.getMonorepoRootPackageJson = getMonorepoRootPackageJson;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const promises_1 = require("node:fs/promises");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const debug_1 = require("../logging/debug");
|
|
9
|
+
const MONOREPO_CONFIG_FILES = [
|
|
10
|
+
{ file: 'pnpm-workspace.yaml', type: 'pnpm' },
|
|
11
|
+
{ file: 'pnpm-workspace.yml', type: 'pnpm' },
|
|
12
|
+
{ file: 'lerna.json', type: 'lerna' },
|
|
13
|
+
{ file: 'nx.json', type: 'nx' },
|
|
14
|
+
{ file: 'rush.json', type: 'rush' },
|
|
15
|
+
];
|
|
16
|
+
const MAX_TRAVERSAL_DEPTH = 10;
|
|
17
|
+
/**
|
|
18
|
+
* Detects if the current project is part of a monorepo and returns information about it.
|
|
19
|
+
* Traverses up the directory tree looking for monorepo configuration files.
|
|
20
|
+
*/
|
|
21
|
+
async function detectMonorepo(startPath) {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
let currentDir = (0, node_path_1.resolve)(startPath);
|
|
24
|
+
let depth = 0;
|
|
25
|
+
while (depth < MAX_TRAVERSAL_DEPTH) {
|
|
26
|
+
// Check for specific monorepo config files
|
|
27
|
+
for (const config of MONOREPO_CONFIG_FILES) {
|
|
28
|
+
const configPath = (0, node_path_1.join)(currentDir, config.file);
|
|
29
|
+
if (fileExists(configPath)) {
|
|
30
|
+
debug_1.ze_log.misc(`Found ${config.type} monorepo config at ${configPath}`);
|
|
31
|
+
return {
|
|
32
|
+
type: config.type,
|
|
33
|
+
root: currentDir,
|
|
34
|
+
configFile: configPath,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Check for package.json with workspaces
|
|
39
|
+
const packageJsonPath = (0, node_path_1.join)(currentDir, 'package.json');
|
|
40
|
+
if (fileExists(packageJsonPath)) {
|
|
41
|
+
try {
|
|
42
|
+
const content = await (0, promises_1.readFile)(packageJsonPath, 'utf8');
|
|
43
|
+
const packageJson = JSON.parse(content);
|
|
44
|
+
// Check for npm/yarn workspaces
|
|
45
|
+
if (packageJson.workspaces) {
|
|
46
|
+
debug_1.ze_log.misc(`Found ${((_a = packageJson.packageManager) === null || _a === void 0 ? void 0 : _a.startsWith('yarn')) ? 'yarn' : 'npm'} workspaces at ${packageJsonPath}`);
|
|
47
|
+
return {
|
|
48
|
+
type: ((_b = packageJson.packageManager) === null || _b === void 0 ? void 0 : _b.startsWith('yarn')) ? 'yarn' : 'npm',
|
|
49
|
+
root: currentDir,
|
|
50
|
+
configFile: packageJsonPath,
|
|
51
|
+
workspaces: Array.isArray(packageJson.workspaces)
|
|
52
|
+
? packageJson.workspaces
|
|
53
|
+
: packageJson.workspaces.packages || [],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// Check for .yarnrc.yml in the same directory (Yarn Berry)
|
|
57
|
+
const yarnrcPath = (0, node_path_1.join)(currentDir, '.yarnrc.yml');
|
|
58
|
+
if (fileExists(yarnrcPath)) {
|
|
59
|
+
debug_1.ze_log.misc(`Found Yarn Berry workspace at ${currentDir}`);
|
|
60
|
+
return {
|
|
61
|
+
type: 'yarn',
|
|
62
|
+
root: currentDir,
|
|
63
|
+
configFile: yarnrcPath,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
debug_1.ze_log.misc(`Error reading package.json at ${packageJsonPath}:`, error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Check if we've reached the root
|
|
72
|
+
const parentDir = (0, node_path_1.resolve)(currentDir, '..');
|
|
73
|
+
if (parentDir === currentDir) {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
currentDir = parentDir;
|
|
77
|
+
depth++;
|
|
78
|
+
}
|
|
79
|
+
debug_1.ze_log.misc('No monorepo configuration found');
|
|
80
|
+
return {
|
|
81
|
+
type: 'none',
|
|
82
|
+
root: startPath,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Gets the root package.json from a monorepo root directory */
|
|
86
|
+
async function getMonorepoRootPackageJson(monorepoRoot) {
|
|
87
|
+
const packageJsonPath = (0, node_path_1.join)(monorepoRoot, 'package.json');
|
|
88
|
+
if (!fileExists(packageJsonPath)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const content = await (0, promises_1.readFile)(packageJsonPath, 'utf8');
|
|
93
|
+
return JSON.parse(content);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
debug_1.ze_log.misc(`Error reading root package.json at ${packageJsonPath}:`, error);
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function fileExists(path) {
|
|
101
|
+
try {
|
|
102
|
+
(0, node_fs_1.accessSync)(path, node_fs_1.constants.F_OK);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
catch (_a) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=detect-monorepo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-monorepo.js","sourceRoot":"","sources":["../../../src/lib/build-context/detect-monorepo.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,35 +4,87 @@ exports.getGitInfo = getGitInfo;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const is_ci_1 = tslib_1.__importDefault(require("is-ci"));
|
|
6
6
|
const node_child_process_1 = require("node:child_process");
|
|
7
|
-
const
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
8
|
const node_util_1 = require("node:util");
|
|
9
|
+
const zephyr_edge_contract_1 = require("zephyr-edge-contract");
|
|
10
|
+
const login_1 = require("../auth/login");
|
|
9
11
|
const errors_1 = require("../errors");
|
|
12
|
+
const http_request_1 = require("../http/http-request");
|
|
10
13
|
const logging_1 = require("../logging");
|
|
14
|
+
const ze_log_event_1 = require("../logging/ze-log-event");
|
|
11
15
|
const secret_token_1 = require("../node-persist/secret-token");
|
|
16
|
+
const token_1 = require("../node-persist/token");
|
|
12
17
|
const git_provider_utils_1 = require("./git-provider-utils");
|
|
18
|
+
const detect_monorepo_1 = require("./detect-monorepo");
|
|
19
|
+
const ze_util_read_package_json_1 = require("./ze-util-read-package-json");
|
|
13
20
|
const exec = (0, node_util_1.promisify)(node_child_process_1.exec);
|
|
21
|
+
/** Generate branch name for non-git contexts */
|
|
22
|
+
function generateBranchName(context, userId) {
|
|
23
|
+
const timestamp = new Date().toISOString().replace(/\D/g, '');
|
|
24
|
+
const userSuffix = userId ? `-${userId.slice(0, 8)}` : '';
|
|
25
|
+
return `${context}${userSuffix}-${timestamp}`;
|
|
26
|
+
}
|
|
14
27
|
/** Loads the git information from the current repository. */
|
|
15
28
|
async function getGitInfo() {
|
|
29
|
+
// Always gather fresh git info for build accuracy
|
|
30
|
+
return await gatherGitInfo();
|
|
31
|
+
}
|
|
32
|
+
/** Internal function that actually gathers git information. */
|
|
33
|
+
async function gatherGitInfo() {
|
|
16
34
|
const hasToken = (0, secret_token_1.hasSecretToken)();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
try {
|
|
36
|
+
const { name, email, remoteOrigin, branch, commit, tags, stdout } = await loadGitInfo(hasToken);
|
|
37
|
+
if (!hasToken && (!name || !email)) {
|
|
38
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_USERNAME_EMAIL, {
|
|
39
|
+
data: { stdout },
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const app = parseGitUrl(remoteOrigin, stdout);
|
|
43
|
+
const gitInfo = {
|
|
44
|
+
git: { name, email, branch, commit, tags },
|
|
45
|
+
app,
|
|
46
|
+
};
|
|
47
|
+
logging_1.ze_log.git('Loaded: git info', gitInfo);
|
|
48
|
+
return gitInfo;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// In CI environments, fail immediately if git info is not available
|
|
52
|
+
if (is_ci_1.default) {
|
|
53
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
54
|
+
message: 'Git repository information is required in CI environments',
|
|
55
|
+
cause: error,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// If git repo info is not available, try global git config
|
|
59
|
+
(0, ze_log_event_1.logFn)('warn', 'Git repository not found. Zephyr REQUIRES a git repository with remote origin.');
|
|
60
|
+
(0, ze_log_event_1.logFn)('warn', 'Manual configuration is NOT recommended and WILL cause errors in production.');
|
|
61
|
+
(0, ze_log_event_1.logFn)('warn', '');
|
|
62
|
+
(0, ze_log_event_1.logFn)('warn', 'To properly use Zephyr, you MUST:');
|
|
63
|
+
(0, ze_log_event_1.logFn)('warn', '1. Initialize git: git init');
|
|
64
|
+
(0, ze_log_event_1.logFn)('warn', '2. Add remote: git remote add origin git@github.com:ORG/REPO.git');
|
|
65
|
+
(0, ze_log_event_1.logFn)('warn', '3. Commit your changes: git add . && git commit -m "Initial commit"');
|
|
66
|
+
(0, ze_log_event_1.logFn)('warn', '');
|
|
67
|
+
(0, ze_log_event_1.logFn)('warn', 'Alternative: Use our CLI for automatic setup: npx create-zephyr-apps');
|
|
68
|
+
(0, ze_log_event_1.logFn)('warn', '📝 Documentation: https://docs.zephyr-cloud.io');
|
|
69
|
+
logging_1.ze_log.git('Git repository not found, falling back to global git config');
|
|
70
|
+
try {
|
|
71
|
+
const globalGitInfo = await loadGlobalGitInfo();
|
|
72
|
+
return globalGitInfo;
|
|
73
|
+
}
|
|
74
|
+
catch (_a) {
|
|
75
|
+
// If global git config also fails, use defaults
|
|
76
|
+
(0, ze_log_event_1.logFn)('warn', 'Global git config not found, using auto-generated defaults');
|
|
77
|
+
logging_1.ze_log.git('Global git config not found, using auto-generated defaults');
|
|
78
|
+
const fallbackInfo = await getFallbackGitInfo();
|
|
79
|
+
return fallbackInfo;
|
|
80
|
+
}
|
|
22
81
|
}
|
|
23
|
-
const app = parseGitUrl(remoteOrigin, stdout);
|
|
24
|
-
const gitInfo = {
|
|
25
|
-
git: { name, email, branch, commit, tags },
|
|
26
|
-
app,
|
|
27
|
-
};
|
|
28
|
-
logging_1.ze_log.git('Loaded: git info', gitInfo);
|
|
29
|
-
return gitInfo;
|
|
30
82
|
}
|
|
83
|
+
// Static delimiter that's unique enough to avoid conflicts with git output
|
|
84
|
+
const GIT_OUTPUT_DELIMITER = '---ZEPHYR-GIT-DELIMITER-8f3a2b1c---';
|
|
31
85
|
/** Loads all data in a single command to avoid multiple executions. */
|
|
32
86
|
async function loadGitInfo(hasSecretToken) {
|
|
33
87
|
const automated = is_ci_1.default || hasSecretToken;
|
|
34
|
-
// ensures multi line output on errors doesn't break the parsing
|
|
35
|
-
const delimiter = (0, node_crypto_1.randomUUID)().repeat(2);
|
|
36
88
|
const command = [
|
|
37
89
|
// Inside CI environments, the last committer should be the actor
|
|
38
90
|
// and not the actual logged git user which sometimes might just be a bot
|
|
@@ -43,12 +95,12 @@ async function loadGitInfo(hasSecretToken) {
|
|
|
43
95
|
'git rev-parse --abbrev-ref HEAD',
|
|
44
96
|
'git rev-parse HEAD',
|
|
45
97
|
'git tag --points-at HEAD',
|
|
46
|
-
].join(` && echo ${
|
|
98
|
+
].join(` && echo ${GIT_OUTPUT_DELIMITER} && `);
|
|
47
99
|
try {
|
|
48
100
|
const { stdout } = await exec(command);
|
|
49
101
|
const [name, email, remoteOrigin, branch, commit, tagsOutput] = stdout
|
|
50
102
|
.trim()
|
|
51
|
-
.split(
|
|
103
|
+
.split(GIT_OUTPUT_DELIMITER)
|
|
52
104
|
.map((x) => x.trim());
|
|
53
105
|
// Parse tags - if multiple tags point to HEAD, they'll be on separate lines
|
|
54
106
|
const tags = tagsOutput ? tagsOutput.split('\n').filter(Boolean) : [];
|
|
@@ -66,7 +118,7 @@ async function loadGitInfo(hasSecretToken) {
|
|
|
66
118
|
const error = cause;
|
|
67
119
|
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
68
120
|
cause,
|
|
69
|
-
data: { command, delimiter },
|
|
121
|
+
data: { command, delimiter: GIT_OUTPUT_DELIMITER },
|
|
70
122
|
message: (error === null || error === void 0 ? void 0 : error.stderr) || error.message,
|
|
71
123
|
});
|
|
72
124
|
}
|
|
@@ -104,4 +156,214 @@ function parseGitUrl(remoteOrigin, stdout) {
|
|
|
104
156
|
});
|
|
105
157
|
}
|
|
106
158
|
}
|
|
159
|
+
/** Try to load git info from global git config */
|
|
160
|
+
async function loadGlobalGitInfo() {
|
|
161
|
+
var _a, _b;
|
|
162
|
+
try {
|
|
163
|
+
const [nameResult, emailResult] = await Promise.all([
|
|
164
|
+
exec('git config --global user.name').catch(() => ({ stdout: '' })),
|
|
165
|
+
exec('git config --global user.email').catch(() => ({ stdout: '' })),
|
|
166
|
+
]);
|
|
167
|
+
const name = (_a = nameResult.stdout) === null || _a === void 0 ? void 0 : _a.trim();
|
|
168
|
+
const email = (_b = emailResult.stdout) === null || _b === void 0 ? void 0 : _b.trim();
|
|
169
|
+
if (!name && !email) {
|
|
170
|
+
(0, ze_log_event_1.logFn)('warn', 'Global git config incomplete: both name and email are missing. Falling back to API user info.');
|
|
171
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
172
|
+
message: 'Global git config incomplete: both name and email are missing',
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
if (!name) {
|
|
176
|
+
(0, ze_log_event_1.logFn)('warn', 'Global git config incomplete: user name is missing. Run: git config --global user.name "Your Name". Falling back to API user info.');
|
|
177
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
178
|
+
message: 'Global git config incomplete: user name is missing',
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (!email) {
|
|
182
|
+
(0, ze_log_event_1.logFn)('warn', 'Global git config incomplete: user email is missing. Run: git config --global user.email "your@email.com". Falling back to API user info.');
|
|
183
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
184
|
+
message: 'Global git config incomplete: user email is missing',
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const { org, project } = await getAppNamingFromPackageJson(name);
|
|
188
|
+
const gitInfo = {
|
|
189
|
+
git: {
|
|
190
|
+
name,
|
|
191
|
+
email,
|
|
192
|
+
branch: generateBranchName('global-git'),
|
|
193
|
+
commit: 'no-git-commit',
|
|
194
|
+
tags: [],
|
|
195
|
+
},
|
|
196
|
+
app: {
|
|
197
|
+
org,
|
|
198
|
+
project,
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
logging_1.ze_log.git('Using global git config (no local repository)', gitInfo);
|
|
202
|
+
(0, ze_log_event_1.logFn)('warn', 'Configuration accepted for THIS BUILD ONLY.');
|
|
203
|
+
(0, ze_log_event_1.logFn)('warn', 'This manual configuration will NOT work for production deployments.');
|
|
204
|
+
(0, ze_log_event_1.logFn)('warn', 'Zephyr REQUIRES a proper git repository with remote origin to function correctly.');
|
|
205
|
+
(0, ze_log_event_1.logFn)('warn', 'Please set up git before your next deployment: https://docs.zephyr-cloud.io');
|
|
206
|
+
return gitInfo;
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
210
|
+
message: 'Failed to load global git config',
|
|
211
|
+
cause: error,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/** Get user info from API endpoint instead of JWT decoding */
|
|
216
|
+
async function getUserInfoFromAPI() {
|
|
217
|
+
const token = await (0, token_1.getToken)();
|
|
218
|
+
if (!token || !(0, login_1.isTokenStillValid)(token, 60)) {
|
|
219
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
220
|
+
message: 'No valid authentication token found. Please login first.',
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
const [ok, cause, response] = await (0, http_request_1.makeRequest)({
|
|
224
|
+
path: '/v2/user/me',
|
|
225
|
+
base: (0, zephyr_edge_contract_1.ZE_API_ENDPOINT)(),
|
|
226
|
+
query: {},
|
|
227
|
+
});
|
|
228
|
+
if (!ok) {
|
|
229
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
230
|
+
message: 'Failed to get user information from API. Please ensure you are logged in with a valid token.',
|
|
231
|
+
cause,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
const userData = response.value;
|
|
235
|
+
logging_1.ze_log.git('Retrieved user info from API:', {
|
|
236
|
+
name: userData.name,
|
|
237
|
+
email: userData.email,
|
|
238
|
+
});
|
|
239
|
+
return userData;
|
|
240
|
+
}
|
|
241
|
+
/** Generate fallback git info when git is completely unavailable */
|
|
242
|
+
async function getFallbackGitInfo() {
|
|
243
|
+
let userInfo;
|
|
244
|
+
try {
|
|
245
|
+
userInfo = await getUserInfoFromAPI();
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
logging_1.ze_log.git('Failed to get user info from API:', error);
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
const gitName = userInfo.name;
|
|
252
|
+
const gitEmail = userInfo.email;
|
|
253
|
+
if (is_ci_1.default) {
|
|
254
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
255
|
+
message: 'Git repository information is required in CI environments. Please ensure your CI workflow includes git repository with proper remote origin.',
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
const { org, project } = await getAppNamingFromPackageJson(userInfo.name);
|
|
259
|
+
const gitInfo = {
|
|
260
|
+
git: {
|
|
261
|
+
name: gitName,
|
|
262
|
+
email: gitEmail,
|
|
263
|
+
branch: generateBranchName('no-git', userInfo.id),
|
|
264
|
+
commit: `fallback-deployment-${Date.now()}`,
|
|
265
|
+
tags: [`deployed-by:${userInfo.id}`],
|
|
266
|
+
},
|
|
267
|
+
app: {
|
|
268
|
+
org,
|
|
269
|
+
project,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
logging_1.ze_log.git('Using fallback git info (git not available)', gitInfo);
|
|
273
|
+
(0, ze_log_event_1.logFn)('warn', `Using organization "${org}" from authenticated user.`);
|
|
274
|
+
(0, ze_log_event_1.logFn)('warn', 'Configuration accepted for THIS BUILD ONLY.');
|
|
275
|
+
(0, ze_log_event_1.logFn)('warn', 'This manual configuration will NOT work for production deployments.');
|
|
276
|
+
(0, ze_log_event_1.logFn)('warn', 'Zephyr REQUIRES a proper git repository with remote origin to function correctly.');
|
|
277
|
+
(0, ze_log_event_1.logFn)('warn', 'Please set up git before your next deployment: https://docs.zephyr-cloud.io');
|
|
278
|
+
return gitInfo;
|
|
279
|
+
}
|
|
280
|
+
/** Sanitize string for use as org/project name */
|
|
281
|
+
function sanitizeName(name) {
|
|
282
|
+
return name.replace(/[^a-zA-Z0-9-]/g, '-').toLowerCase();
|
|
283
|
+
}
|
|
284
|
+
/** Get current directory name as project name */
|
|
285
|
+
function getCurrentDirectoryName() {
|
|
286
|
+
const cwd = process.cwd();
|
|
287
|
+
const dirName = cwd.split(node_path_1.sep).pop() || 'untitled-project';
|
|
288
|
+
return sanitizeName(dirName);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Extract org, project, and app names from package.json structure for non-git
|
|
292
|
+
* environments
|
|
293
|
+
*/
|
|
294
|
+
async function getAppNamingFromPackageJson(tokenUserName) {
|
|
295
|
+
try {
|
|
296
|
+
const packageJson = await (0, ze_util_read_package_json_1.getPackageJson)(process.cwd());
|
|
297
|
+
const packageName = packageJson.name;
|
|
298
|
+
// Require JWT username for org - no fallback to avoid build loss
|
|
299
|
+
if (!tokenUserName) {
|
|
300
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
301
|
+
message: 'Unable to determine organization: no authenticated user found. Please ensure you are logged in with a valid token.',
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const org = sanitizeName(tokenUserName);
|
|
305
|
+
if (packageName.includes('@')) {
|
|
306
|
+
// Scoped package: @scope/name -> project: scope, app: name
|
|
307
|
+
const [scope, name] = packageName.split('/');
|
|
308
|
+
return {
|
|
309
|
+
org,
|
|
310
|
+
project: scope.replace('@', ''),
|
|
311
|
+
app: name,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
// Check if we're in a monorepo
|
|
315
|
+
const monorepoInfo = await (0, detect_monorepo_1.detectMonorepo)(process.cwd());
|
|
316
|
+
if (monorepoInfo.type !== 'none') {
|
|
317
|
+
// We're in a monorepo
|
|
318
|
+
const rootPackageJson = await (0, detect_monorepo_1.getMonorepoRootPackageJson)(monorepoInfo.root);
|
|
319
|
+
if (rootPackageJson && rootPackageJson['name']) {
|
|
320
|
+
const rootName = rootPackageJson['name'];
|
|
321
|
+
// If root package is scoped, use the scope as project
|
|
322
|
+
if (rootName.includes('@')) {
|
|
323
|
+
const [scope] = rootName.split('/');
|
|
324
|
+
return {
|
|
325
|
+
org,
|
|
326
|
+
project: scope.replace('@', ''),
|
|
327
|
+
app: packageName,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
// Use root package name as project
|
|
331
|
+
return {
|
|
332
|
+
org,
|
|
333
|
+
project: sanitizeName(rootName),
|
|
334
|
+
app: packageName,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
// No root package.json or no name - use monorepo root directory name
|
|
339
|
+
const rootDirName = monorepoInfo.root.split(node_path_1.sep).pop() || 'monorepo';
|
|
340
|
+
return {
|
|
341
|
+
org,
|
|
342
|
+
project: sanitizeName(rootDirName),
|
|
343
|
+
app: packageName,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Not in a monorepo - single package
|
|
348
|
+
return {
|
|
349
|
+
org,
|
|
350
|
+
project: packageName,
|
|
351
|
+
app: packageName,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
catch (_a) {
|
|
355
|
+
// No package.json: use directory name
|
|
356
|
+
const dirName = getCurrentDirectoryName();
|
|
357
|
+
if (!tokenUserName) {
|
|
358
|
+
throw new errors_1.ZephyrError(errors_1.ZeErrors.ERR_NO_GIT_INFO, {
|
|
359
|
+
message: 'Unable to determine organization: no authenticated user found and no package.json available. Please ensure you are logged in with a valid token.',
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
org: sanitizeName(tokenUserName),
|
|
364
|
+
project: dirName,
|
|
365
|
+
app: dirName,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
}
|
|
107
369
|
//# sourceMappingURL=ze-util-get-git-info.js.map
|