naro-cli 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ZHVBIQBE.js → chunk-TYBC3YSK.js} +47 -17
- package/dist/deploy.d.ts +3 -0
- package/dist/deploy.js +1 -1
- package/dist/git-info.d.ts +10 -0
- package/dist/index.js +4 -1
- package/package.json +3 -3
|
@@ -9,7 +9,7 @@ var __export = (target, all) => {
|
|
|
9
9
|
import { existsSync as existsSync6 } from "fs";
|
|
10
10
|
import { cp, mkdtemp as mkdtemp2, readFile as readFile7, rm as rm2 } from "fs/promises";
|
|
11
11
|
import { tmpdir as tmpdir2 } from "os";
|
|
12
|
-
import { basename, dirname, join as join15 } from "path";
|
|
12
|
+
import { basename, dirname, join as join15, resolve as resolve4 } from "path";
|
|
13
13
|
import { fileURLToPath } from "url";
|
|
14
14
|
|
|
15
15
|
// ../../packages/build/src/artifact-upload.ts
|
|
@@ -173,6 +173,16 @@ import { join as join8 } from "path";
|
|
|
173
173
|
var MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|
174
174
|
var MAX_ARTIFACT_BYTES = 64 * 1024 * 1024;
|
|
175
175
|
|
|
176
|
+
// ../../packages/core/src/deployment.ts
|
|
177
|
+
var PHASES = [
|
|
178
|
+
"QUEUED",
|
|
179
|
+
"CLONING",
|
|
180
|
+
"INSTALLING",
|
|
181
|
+
"BUILDING",
|
|
182
|
+
"DEPLOYING"
|
|
183
|
+
];
|
|
184
|
+
var ACTIVE_STATUSES = new Set(PHASES);
|
|
185
|
+
|
|
176
186
|
// ../../packages/core/src/errors.ts
|
|
177
187
|
var DeploymentError = class extends Error {
|
|
178
188
|
code;
|
|
@@ -15178,21 +15188,39 @@ function contentType(path) {
|
|
|
15178
15188
|
return "application/javascript";
|
|
15179
15189
|
case ".json":
|
|
15180
15190
|
return "application/json";
|
|
15191
|
+
case ".map":
|
|
15192
|
+
return "application/json";
|
|
15193
|
+
case ".webmanifest":
|
|
15194
|
+
return "application/manifest+json";
|
|
15195
|
+
case ".txt":
|
|
15196
|
+
return "text/plain; charset=utf-8";
|
|
15197
|
+
case ".xml":
|
|
15198
|
+
return "application/xml";
|
|
15181
15199
|
case ".svg":
|
|
15182
15200
|
return "image/svg+xml";
|
|
15183
15201
|
case ".wasm":
|
|
15184
15202
|
return "application/wasm";
|
|
15203
|
+
case ".ico":
|
|
15204
|
+
return "image/x-icon";
|
|
15185
15205
|
case ".png":
|
|
15186
15206
|
return "image/png";
|
|
15187
15207
|
case ".jpg":
|
|
15188
15208
|
case ".jpeg":
|
|
15189
15209
|
return "image/jpeg";
|
|
15210
|
+
case ".gif":
|
|
15211
|
+
return "image/gif";
|
|
15190
15212
|
case ".webp":
|
|
15191
15213
|
return "image/webp";
|
|
15214
|
+
case ".avif":
|
|
15215
|
+
return "image/avif";
|
|
15192
15216
|
case ".woff":
|
|
15193
15217
|
return "font/woff";
|
|
15194
15218
|
case ".woff2":
|
|
15195
15219
|
return "font/woff2";
|
|
15220
|
+
case ".ttf":
|
|
15221
|
+
return "font/ttf";
|
|
15222
|
+
case ".otf":
|
|
15223
|
+
return "font/otf";
|
|
15196
15224
|
default:
|
|
15197
15225
|
return "application/octet-stream";
|
|
15198
15226
|
}
|
|
@@ -15961,8 +15989,8 @@ var FAIL_HTML = "<html><body><p>Login failed. You can close this tab and return
|
|
|
15961
15989
|
async function startCallbackServer() {
|
|
15962
15990
|
let resolveCode;
|
|
15963
15991
|
let rejectCode;
|
|
15964
|
-
const codePromise = new Promise((
|
|
15965
|
-
resolveCode =
|
|
15992
|
+
const codePromise = new Promise((resolve5, reject) => {
|
|
15993
|
+
resolveCode = resolve5;
|
|
15966
15994
|
rejectCode = reject;
|
|
15967
15995
|
});
|
|
15968
15996
|
const server = createServer((req, res) => {
|
|
@@ -15989,7 +16017,7 @@ async function startCallbackServer() {
|
|
|
15989
16017
|
res.end(DONE_HTML);
|
|
15990
16018
|
resolveCode(code);
|
|
15991
16019
|
});
|
|
15992
|
-
await new Promise((
|
|
16020
|
+
await new Promise((resolve5) => server.listen(0, "127.0.0.1", resolve5));
|
|
15993
16021
|
const port = server.address().port;
|
|
15994
16022
|
return {
|
|
15995
16023
|
port,
|
|
@@ -16421,7 +16449,7 @@ var DeploymentsApi = class {
|
|
|
16421
16449
|
async wait(deploymentId, options = {}) {
|
|
16422
16450
|
const intervalMs = options.intervalMs ?? 2500;
|
|
16423
16451
|
const timeoutMs = options.timeoutMs ?? 15 * 6e4;
|
|
16424
|
-
const sleep = options.sleep ?? ((ms) => new Promise((
|
|
16452
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms)));
|
|
16425
16453
|
const startedAt = Date.now();
|
|
16426
16454
|
let lastStatus = null;
|
|
16427
16455
|
let lastSequence = -1;
|
|
@@ -16930,10 +16958,10 @@ var SUPPORTED_REMOTE = [
|
|
|
16930
16958
|
/^ssh:\/\/[^\s]+$/,
|
|
16931
16959
|
/^git@[A-Za-z0-9.-]+:[A-Za-z0-9._/-]+(\.git)?$/
|
|
16932
16960
|
];
|
|
16933
|
-
var defaultExec = (args, cwd) => new Promise((
|
|
16961
|
+
var defaultExec = (args, cwd) => new Promise((resolve5, reject) => {
|
|
16934
16962
|
execFile("git", args, { cwd }, (error51, stdout) => {
|
|
16935
16963
|
if (error51) reject(error51);
|
|
16936
|
-
else
|
|
16964
|
+
else resolve5(stdout);
|
|
16937
16965
|
});
|
|
16938
16966
|
});
|
|
16939
16967
|
async function tryExec(exec, args, cwd) {
|
|
@@ -16951,9 +16979,11 @@ async function detectGitInfo(dir, exec = defaultExec) {
|
|
|
16951
16979
|
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
16952
16980
|
dir
|
|
16953
16981
|
);
|
|
16982
|
+
const prefix = await tryExec(exec, ["rev-parse", "--show-prefix"], dir);
|
|
16954
16983
|
return {
|
|
16955
16984
|
repositoryUrl: remote !== null && SUPPORTED_REMOTE.some((re) => re.test(remote)) ? remote : null,
|
|
16956
|
-
branch: branch !== null && branch !== "HEAD" ? branch : null
|
|
16985
|
+
branch: branch !== null && branch !== "HEAD" ? branch : null,
|
|
16986
|
+
prefix: prefix === null ? null : prefix.replace(/\/+$/, "") || null
|
|
16957
16987
|
};
|
|
16958
16988
|
}
|
|
16959
16989
|
|
|
@@ -17081,7 +17111,7 @@ function eventsObserver(cp2, deploymentId, token, fetchImpl = fetch) {
|
|
|
17081
17111
|
} catch (error51) {
|
|
17082
17112
|
lastError = error51;
|
|
17083
17113
|
await new Promise(
|
|
17084
|
-
(
|
|
17114
|
+
(resolve5) => setTimeout(resolve5, 500 * (attempt + 1))
|
|
17085
17115
|
);
|
|
17086
17116
|
}
|
|
17087
17117
|
}
|
|
@@ -17172,11 +17202,12 @@ function localDependencies(sourceDir) {
|
|
|
17172
17202
|
async function deployDirectory(sourceDir, options, log2) {
|
|
17173
17203
|
const cpUrl = controlPlaneUrl();
|
|
17174
17204
|
const production = options.production ?? false;
|
|
17175
|
-
const
|
|
17205
|
+
const appRoot = options.rootDirectory ? resolve4(sourceDir, options.rootDirectory) : sourceDir;
|
|
17206
|
+
const framework = detectFramework2(appRoot);
|
|
17176
17207
|
if (!framework.deployable && !options.force) {
|
|
17177
17208
|
throw new NaroError(
|
|
17178
17209
|
"FRAMEWORK_UNSUPPORTED",
|
|
17179
|
-
framework.framework === "unknown" ?
|
|
17210
|
+
framework.framework === "unknown" ? `No supported framework detected in ${appRoot}. Naro deploys Next.js, Vite, Create React App, and static sites \u2014 run this inside one of those projects, or point at it with --root <dir>.` : `${framework.name} projects are not deployable on Naro yet.`,
|
|
17180
17211
|
{ details: { framework: framework.framework } }
|
|
17181
17212
|
);
|
|
17182
17213
|
}
|
|
@@ -17193,9 +17224,10 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
17193
17224
|
getAccessToken: () => auth.getAccessToken(),
|
|
17194
17225
|
...options.fetch ? { fetch: options.fetch } : {}
|
|
17195
17226
|
});
|
|
17196
|
-
const name = slugify2(options.name ?? await projectName(
|
|
17197
|
-
const git = await detectGitInfo(sourceDir);
|
|
17227
|
+
const name = slugify2(options.name ?? await projectName(appRoot));
|
|
17228
|
+
const git = await (options.gitInfo ?? detectGitInfo)(sourceDir);
|
|
17198
17229
|
const branch = options.branch ?? git.branch;
|
|
17230
|
+
const repositoryRoot = [git.prefix, options.rootDirectory].filter(Boolean).join("/") || null;
|
|
17199
17231
|
if (options.projectId) log2(`\u25B8 linked project ${options.projectId}`);
|
|
17200
17232
|
else if (git.repositoryUrl) log2(`\u25B8 linking ${git.repositoryUrl}`);
|
|
17201
17233
|
if (options.env && Object.keys(options.env).length > 0)
|
|
@@ -17233,9 +17265,7 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
17233
17265
|
production,
|
|
17234
17266
|
...git.repositoryUrl != null && { repositoryUrl: git.repositoryUrl },
|
|
17235
17267
|
...branch != null && { branch },
|
|
17236
|
-
...
|
|
17237
|
-
rootDirectory: options.rootDirectory
|
|
17238
|
-
},
|
|
17268
|
+
...repositoryRoot != null && { rootDirectory: repositoryRoot },
|
|
17239
17269
|
...Object.keys(envToSend).length > 0 && { env: envToSend }
|
|
17240
17270
|
});
|
|
17241
17271
|
if (ctx.envSkipped?.length)
|
|
@@ -17255,7 +17285,7 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
17255
17285
|
projectId: ctx.projectId,
|
|
17256
17286
|
repositoryUrl: sourceDir,
|
|
17257
17287
|
branch: ctx.branch,
|
|
17258
|
-
rootDirectory: options.rootDirectory ??
|
|
17288
|
+
rootDirectory: options.rootDirectory ?? null,
|
|
17259
17289
|
env: { ...ctx.env, ...envToSend }
|
|
17260
17290
|
},
|
|
17261
17291
|
observer
|
package/dist/deploy.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CliGitConnection } from "@next-deploy/sdk";
|
|
2
2
|
import type { BuildObserver, DeploymentArtifact, DeploymentStatus } from "./artifact-types";
|
|
3
|
+
import { type GitInfo } from "./git-info";
|
|
3
4
|
/** The slice of LocalBuildExecutor the deploy flow needs — injectable in tests. */
|
|
4
5
|
export interface DeployBuildExecutor {
|
|
5
6
|
build(input: {
|
|
@@ -38,6 +39,8 @@ export interface DeployOptions {
|
|
|
38
39
|
fetch?: typeof fetch;
|
|
39
40
|
/** Test seam: replaces the local OpenNext build. */
|
|
40
41
|
executor?: DeployBuildExecutor;
|
|
42
|
+
/** Test seam: replaces the `git` calls that read the repository. */
|
|
43
|
+
gitInfo?: (dir: string) => Promise<GitInfo>;
|
|
41
44
|
/**
|
|
42
45
|
* 소스가 참조하지만 프로젝트에 없는 env 키를 받아, 등록할 값을 돌려준다.
|
|
43
46
|
* 대화형 CLI만 전달한다 — MCP·CI는 생략하고 안내만 받는다.
|
package/dist/deploy.js
CHANGED
package/dist/git-info.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
export interface GitInfo {
|
|
2
2
|
repositoryUrl: string | null;
|
|
3
3
|
branch: string | null;
|
|
4
|
+
/**
|
|
5
|
+
* Path from the repository root to this directory ("apps/web"), or null at
|
|
6
|
+
* the root / outside a repository.
|
|
7
|
+
*
|
|
8
|
+
* A monorepo app deployed from its own directory builds locally from that
|
|
9
|
+
* directory, so nothing here needs it. A git-triggered build clones the
|
|
10
|
+
* whole repository and has to be told where the app lives — this is that
|
|
11
|
+
* answer, recorded without anyone having to know to pass it.
|
|
12
|
+
*/
|
|
13
|
+
prefix: string | null;
|
|
4
14
|
}
|
|
5
15
|
export type GitExec = (args: string[], cwd: string) => Promise<string>;
|
|
6
16
|
/** Reads local git metadata for the deploy: origin remote URL + current branch. */
|
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
slugify,
|
|
27
27
|
toNaroError,
|
|
28
28
|
writeProjectLink
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-TYBC3YSK.js";
|
|
30
30
|
|
|
31
31
|
// src/args.ts
|
|
32
32
|
var BOOLEAN_FLAGS = {
|
|
@@ -1364,6 +1364,7 @@ Usage:
|
|
|
1364
1364
|
naro project inspect Show the linked project
|
|
1365
1365
|
|
|
1366
1366
|
naro deploy [--prod] Build locally and deploy (preview by default)
|
|
1367
|
+
[--root <dir>] [--name <name>] --root points at the app in a monorepo
|
|
1367
1368
|
naro deployments List deployments of the linked project
|
|
1368
1369
|
naro inspect <deployment-id> Show one deployment + build logs
|
|
1369
1370
|
|
|
@@ -1388,6 +1389,8 @@ Global options:
|
|
|
1388
1389
|
--yes, -y Never prompt; assume yes (CI / agents)
|
|
1389
1390
|
--token <t> Access token (or set NARO_TOKEN)
|
|
1390
1391
|
--project <id> Target project (overrides .naro/project.json)
|
|
1392
|
+
--root <dir> App directory inside the repo (monorepos), e.g. apps/web
|
|
1393
|
+
--name <name> Project name for a first deploy (defaults to package.json)
|
|
1391
1394
|
--team <slug> Team scope for project listing/linking
|
|
1392
1395
|
--cwd <dir> Run as if started in <dir>
|
|
1393
1396
|
--prod Deploy/target production
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "naro-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"naro": "./dist/index.js"
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"tsx": "4.23.12",
|
|
29
29
|
"typescript": "7.0.2",
|
|
30
30
|
"vitest": "3.2.7",
|
|
31
|
-
"@next-deploy/core": "0.1.0",
|
|
32
31
|
"@next-deploy/build": "0.1.0",
|
|
33
32
|
"@next-deploy/config": "0.1.0",
|
|
34
|
-
"@next-deploy/sdk": "0.1.0"
|
|
33
|
+
"@next-deploy/sdk": "0.1.0",
|
|
34
|
+
"@next-deploy/core": "0.1.0"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsup && pnpm build:types",
|