@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
|
-
|
|
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 };
|
package/dist/deploy/deploy.d.ts
CHANGED
|
@@ -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>;
|
package/dist/deploy/deploy.js
CHANGED
|
@@ -67,7 +67,8 @@ export async function deployProject(options) {
|
|
|
67
67
|
: String(error),
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
const
|
|
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?.();
|