@synopackageland/cli 0.3.0 → 0.3.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.
@@ -315,11 +315,12 @@ function volumeMounts(compose) {
315
315
  }
316
316
  return mounts;
317
317
  }
318
+ // A Compose that mounts nothing reaches even less of the NAS than one that
319
+ // mounts only PKGVAR, so it earns the same consent line. Returning false for
320
+ // zero sources left the wizard step with no items at all, and DSM's Package
321
+ // Center rejects that SPK with "Invalid file format".
318
322
  function composeUsesOnlyAppSpace(compose) {
319
323
  const sources = volumeSources(compose);
320
- if (sources.length === 0) {
321
- return false;
322
- }
323
324
  return sources.every((source) => source.startsWith("${SYNOPKG_PKGVAR}") || source.startsWith("${SYNO_APP_SECRETS_DIR}"));
324
325
  }
325
326
  const PRIVILEGE_MAX_WARNING = "此 App 的容器有高權限,接近這台 NAS 的 root、幾乎整台機器。是否安裝由你這位管理員決定。";
@@ -354,7 +355,10 @@ function renderInstallWizard(contract, compose) {
354
355
  desc: capabilityText,
355
356
  });
356
357
  }
357
- if (!hasSharedFolder && !capabilityText && compose && composeUsesOnlyAppSpace(compose)) {
358
+ // No compose at all is the native branch: the binary gets PKGVAR and nothing
359
+ // else, so it earns the same line. Requiring a compose left native wizards
360
+ // empty, which DSM rejects as an invalid package.
361
+ if (!hasSharedFolder && !capabilityText && (!compose || composeUsesOnlyAppSpace(compose))) {
358
362
  items.push({
359
363
  desc: APP_OWN_SPACE_CONSENT,
360
364
  });
@@ -2,6 +2,8 @@ import { contractSpan, makeError } from "../errors.js";
2
2
  import { collectInstallParameters, getValuePosition, stringViolations, } from "./load.js";
3
3
  import { validateContractSchema } from "./schema-validate.js";
4
4
  import { isWebLaunchMode, readWebIntegration } from "./web-launch.js";
5
+ /** DSM 7.4 Package Center rejects a longer package identity outright. */
6
+ const DSM_PACKAGE_IDENTITY_MAX = 32;
5
7
  const METADATA_STRING_FIELDS = [
6
8
  "package",
7
9
  "version",
@@ -21,6 +23,14 @@ export function validateContract(parsed, contractFile) {
21
23
  }
22
24
  errors.push(...validateDeveloperString(value, contractFile, field, getValuePosition(doc, [field]) ?? { line: 1, column: 1 }));
23
25
  }
26
+ // DSM 7.4 Package Center refuses an SPK whose package identity exceeds 32
27
+ // characters -- "Invalid file format", before the install starts and with
28
+ // nothing written to synopkg.log. Measured on 10.17.83.200: 32 installs, 33
29
+ // does not.
30
+ if (typeof contract.package === "string" && contract.package.length > DSM_PACKAGE_IDENTITY_MAX) {
31
+ const pos = getValuePosition(doc, ["package"]) ?? { line: 1, column: 1 };
32
+ errors.push(makeError("CONTRACT_PACKAGE_TOO_LONG", contractSpan(contractFile, pos.line, pos.column, "package"), `Package Identity 超過 DSM 上限 ${DSM_PACKAGE_IDENTITY_MAX} 字元(目前 ${contract.package.length})。`, "請縮短 package,否則 Package Center 會以「Invalid file format」拒絕安裝。"));
33
+ }
24
34
  if (contract.adminport !== undefined) {
25
35
  if (typeof contract.adminport !== "number" || !Number.isInteger(contract.adminport)) {
26
36
  const pos = getValuePosition(doc, ["adminport"]) ?? { line: 1, column: 1 };
@@ -1,6 +1,7 @@
1
1
  import type { NativeArchFamily } from "../build-spk/dsm-arch.js";
2
2
  import type { ProjectRoot } from "../discovery.js";
3
3
  import type { NasHost } from "../host/types.js";
4
+ import { resolveDeploySpkVersion } from "./spk-version.js";
4
5
  import type { PublishSpkResult } from "@synopackageland/package-source/publish-spk";
5
6
  export interface DeployProjectOptions {
6
7
  project: ProjectRoot;
@@ -9,6 +10,7 @@ export interface DeployProjectOptions {
9
10
  host: NasHost;
10
11
  dev?: boolean;
11
12
  replaceCurated?: boolean;
13
+ spkVersionResolver?: typeof resolveDeploySpkVersion;
12
14
  catalogPublish?: (spkPath: string) => Promise<PublishSpkResult>;
13
15
  shareValues?: Record<string, string>;
14
16
  runAsValues?: Record<string, string>;
@@ -67,7 +67,8 @@ export async function deployProject(options) {
67
67
  : String(error),
68
68
  };
69
69
  }
70
- const spkVersion = await resolveDeploySpkVersion(options.project, options.host, identity.packageId);
70
+ const resolveSpkVersion = options.spkVersionResolver ?? resolveDeploySpkVersion;
71
+ const spkVersion = await resolveSpkVersion(options.project, options.host, identity.packageId);
71
72
  let archFamily = options.archFamily;
72
73
  if (archFamily === undefined && options.project.nativePath && existsSync(options.project.nativePath)) {
73
74
  archFamily = await options.host.getArchFamily?.();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Syno Package Land Developer Kit CLI",
5
5
  "type": "module",
6
6
  "bin": {