naro-cli 0.2.0 → 0.2.1

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.
@@ -28,6 +28,7 @@ export interface BuildLog {
28
28
  /** Mirrors the build metadata shape from the internal build package. */
29
29
  export interface BuildMetadata {
30
30
  gitCommitSha?: string;
31
+ gitCommitMessage?: string;
31
32
  artifactKey?: string;
32
33
  }
33
34
  /** Mirrors the build observer shape from the internal build package. */
@@ -107,18 +107,31 @@ async function saveCache(args) {
107
107
  await log(observer, scope, "INFO", `Saved ${scope} cache (${key}).`);
108
108
  }
109
109
 
110
+ // ../../packages/build/src/hash.ts
111
+ import { createHash as createHash2 } from "crypto";
112
+ function hashAsset(data) {
113
+ return createHash2("sha256").update(data).digest("hex").slice(0, 32);
114
+ }
115
+
110
116
  // ../../packages/build/src/local-build-executor.ts
111
117
  import { mkdtemp, rm } from "fs/promises";
112
118
  import { tmpdir } from "os";
113
119
  import { join as join7 } from "path";
114
120
 
121
+ // ../../packages/core/src/artifact-manifest.ts
122
+ var MAX_FILE_BYTES = 25 * 1024 * 1024;
123
+ var MAX_ARTIFACT_BYTES = 64 * 1024 * 1024;
124
+
115
125
  // ../../packages/core/src/errors.ts
116
126
  var DeploymentError = class extends Error {
117
127
  code;
128
+ /** HTTP status from the upstream response that caused this error, when known. */
129
+ status;
118
130
  constructor(code, message, options) {
119
131
  super(message, options);
120
132
  this.name = "DeploymentError";
121
133
  this.code = code;
134
+ if (options?.status !== void 0) this.status = options.status;
122
135
  }
123
136
  };
124
137
 
@@ -14636,6 +14649,41 @@ function date4(params) {
14636
14649
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
14637
14650
  config(en_default());
14638
14651
 
14652
+ // ../../packages/core/src/subdomain.ts
14653
+ var RESERVED_SUBDOMAINS = [
14654
+ "admin",
14655
+ "api",
14656
+ "app",
14657
+ "assets",
14658
+ "blog",
14659
+ "cdn",
14660
+ "dashboard",
14661
+ "docs",
14662
+ "help",
14663
+ "imap",
14664
+ "mail",
14665
+ "mx",
14666
+ "naro",
14667
+ "ns1",
14668
+ "ns2",
14669
+ "preview",
14670
+ "smtp",
14671
+ "static",
14672
+ "status",
14673
+ "support",
14674
+ "www"
14675
+ ];
14676
+ var SUBDOMAIN_PATTERN = /^[a-z0-9](-?[a-z0-9])*$/;
14677
+ var SUBDOMAIN_MAX_LENGTH = 54;
14678
+ function subdomainProblem(value) {
14679
+ if (value.length < 1 || value.length > SUBDOMAIN_MAX_LENGTH) return "invalid";
14680
+ if (!SUBDOMAIN_PATTERN.test(value)) return "invalid";
14681
+ if (value.endsWith("-preview")) return "reserved";
14682
+ if (RESERVED_SUBDOMAINS.includes(value))
14683
+ return "reserved";
14684
+ return null;
14685
+ }
14686
+
14639
14687
  // ../../packages/core/src/schemas.ts
14640
14688
  function isSupportedGitUrl(value) {
14641
14689
  if (/^git@[A-Za-z0-9.-]+:[A-Za-z0-9._/-]+(?:\.git)?$/.test(value)) {
@@ -14666,12 +14714,30 @@ var createDeploymentSchema = external_exports.object({
14666
14714
  branch: external_exports.string().trim().max(240).optional().transform((value) => value || null)
14667
14715
  });
14668
14716
  var connectRepositorySchema = external_exports.object({
14717
+ // Web-only route context: the only consumer is apps/web's
14718
+ // POST /api/projects handler, which resolves this to a team id.
14719
+ teamSlug: external_exports.string().trim().min(1),
14669
14720
  name: external_exports.string().trim().min(1).max(80),
14670
14721
  installationId: external_exports.number().int().positive(),
14671
14722
  repoId: external_exports.number().int().positive(),
14672
14723
  fullName: external_exports.string().trim().min(1).max(200).regex(/^[^/]+\/[^/]+$/, { message: "fullName must be owner/name" }),
14673
14724
  defaultBranch: external_exports.string().trim().min(1).max(240).default("main"),
14674
- rootDirectory: optionalRootDirectory
14725
+ rootDirectory: optionalRootDirectory,
14726
+ subdomain: external_exports.string().trim().max(60).optional().transform((value) => value ? value.toLowerCase() : null).superRefine((value, ctx) => {
14727
+ if (value === null) return;
14728
+ const problem = subdomainProblem(value);
14729
+ if (problem === "invalid") {
14730
+ ctx.addIssue({
14731
+ code: external_exports.ZodIssueCode.custom,
14732
+ message: "Use lowercase letters, numbers, and single hyphens (up to 54 characters)."
14733
+ });
14734
+ } else if (problem === "reserved") {
14735
+ ctx.addIssue({
14736
+ code: external_exports.ZodIssueCode.custom,
14737
+ message: "This subdomain is reserved."
14738
+ });
14739
+ }
14740
+ })
14675
14741
  });
14676
14742
 
14677
14743
  // ../../packages/build/src/package-manager.ts
@@ -15334,7 +15400,22 @@ var LocalBuildExecutor = class {
15334
15400
  "Git returned an invalid commit SHA."
15335
15401
  );
15336
15402
  }
15337
- await observer.onMetadata?.({ gitCommitSha });
15403
+ const subject = await this.dependencies.runCommand(
15404
+ {
15405
+ command: "git",
15406
+ args: ["log", "-1", "--format=%s"],
15407
+ cwd: checkout,
15408
+ timeoutMs: 1e4,
15409
+ stage: "CLONING",
15410
+ errorCode: "CLONE_FAILED"
15411
+ },
15412
+ observer
15413
+ );
15414
+ const gitCommitMessage = [...subject.stdout.at(-1)?.trim() ?? ""].slice(0, 300).join("");
15415
+ await observer.onMetadata?.({
15416
+ gitCommitSha,
15417
+ ...gitCommitMessage ? { gitCommitMessage } : {}
15418
+ });
15338
15419
  const appRoot = this.dependencies.resolveAppRoot(
15339
15420
  checkout,
15340
15421
  input.rootDirectory
@@ -15505,7 +15586,11 @@ async function tryExec(exec, args, cwd) {
15505
15586
  }
15506
15587
  async function detectGitInfo(dir, exec = defaultExec) {
15507
15588
  const remote = await tryExec(exec, ["remote", "get-url", "origin"], dir);
15508
- const branch = await tryExec(exec, ["rev-parse", "--abbrev-ref", "HEAD"], dir);
15589
+ const branch = await tryExec(
15590
+ exec,
15591
+ ["rev-parse", "--abbrev-ref", "HEAD"],
15592
+ dir
15593
+ );
15509
15594
  return {
15510
15595
  repositoryUrl: remote !== null && SUPPORTED_REMOTE.some((re) => re.test(remote)) ? remote : null,
15511
15596
  branch: branch !== null && branch !== "HEAD" ? branch : null
@@ -15787,7 +15872,10 @@ function manifest(artifact) {
15787
15872
  projectId: artifact.projectId,
15788
15873
  entrypoint: artifact.entrypoint.name,
15789
15874
  modules: [artifact.entrypoint, ...artifact.modules].map(meta3),
15790
- assets: artifact.assets.map(meta3),
15875
+ assets: artifact.assets.map((file2) => ({
15876
+ ...meta3(file2),
15877
+ hash: hashAsset(file2.data)
15878
+ })),
15791
15879
  compatibilityDate: artifact.compatibilityDate,
15792
15880
  compatibilityFlags: artifact.compatibilityFlags,
15793
15881
  assetsBinding: artifact.assetsBinding
@@ -15825,9 +15913,13 @@ async function startCliDeployment(accessToken, opts) {
15825
15913
  body: JSON.stringify({
15826
15914
  name: opts.name,
15827
15915
  production: opts.production,
15828
- ...opts.repositoryUrl != null && { repositoryUrl: opts.repositoryUrl },
15916
+ ...opts.repositoryUrl != null && {
15917
+ repositoryUrl: opts.repositoryUrl
15918
+ },
15829
15919
  ...opts.branch != null && { branch: opts.branch },
15830
- ...opts.rootDirectory != null && { rootDirectory: opts.rootDirectory },
15920
+ ...opts.rootDirectory != null && {
15921
+ rootDirectory: opts.rootDirectory
15922
+ },
15831
15923
  ...opts.env !== void 0 && { env: opts.env }
15832
15924
  })
15833
15925
  }
@@ -15964,6 +16056,9 @@ function localDependencies(sourceDir) {
15964
16056
  if (spec.command === "git" && spec.args[0] === "rev-parse") {
15965
16057
  return { stdout: ["0".repeat(40)], stderr: [] };
15966
16058
  }
16059
+ if (spec.command === "git" && spec.args[0] === "log") {
16060
+ return { stdout: [], stderr: [] };
16061
+ }
15967
16062
  return runCommand(spec, observer);
15968
16063
  },
15969
16064
  detectPackageManager: detectPackageManagerLenient,
@@ -16015,9 +16110,10 @@ async function deployDirectory(sourceDir, options, log2) {
16015
16110
  deploymentId: ctx.deploymentId,
16016
16111
  callbackToken: ctx.callbackToken
16017
16112
  });
16113
+ const surface = ctx.subdomain ?? name;
16018
16114
  return {
16019
- workerName: name,
16020
- url: uploaded.previewUrl ?? `${name}${production ? "" : "-preview"}.naro.sh`
16115
+ workerName: surface,
16116
+ url: uploaded.previewUrl ?? `${surface}${production ? "" : "-preview"}.naro.sh`
16021
16117
  };
16022
16118
  }
16023
16119
 
package/dist/deploy.d.ts CHANGED
@@ -9,6 +9,7 @@ export interface CliDeploymentContext {
9
9
  env: Record<string, string>;
10
10
  controlPlaneUrl: string;
11
11
  envSkipped?: string[];
12
+ subdomain?: string;
12
13
  }
13
14
  export declare function startCliDeployment(accessToken: string, opts: {
14
15
  name: string;
package/dist/deploy.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  requireSessionOrLogin,
9
9
  slugify,
10
10
  startCliDeployment
11
- } from "./chunk-UNCVFCTH.js";
11
+ } from "./chunk-IC4R5EYE.js";
12
12
  export {
13
13
  controlPlaneUrl,
14
14
  deployDirectory,
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  runLogin,
6
6
  runLogout,
7
7
  runWhoami
8
- } from "./chunk-UNCVFCTH.js";
8
+ } from "./chunk-IC4R5EYE.js";
9
9
 
10
10
  // src/index.ts
11
11
  function parseFlags(argv) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naro-cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "naro": "./dist/index.js"
@@ -29,8 +29,8 @@
29
29
  "typescript": "7.0.2",
30
30
  "vitest": "3.2.7",
31
31
  "@next-deploy/build": "0.1.0",
32
- "@next-deploy/config": "0.1.0",
33
- "@next-deploy/core": "0.1.0"
32
+ "@next-deploy/core": "0.1.0",
33
+ "@next-deploy/config": "0.1.0"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsup && pnpm build:types",