fix: 修复配额说明重复和undefined问题

- 在editStorageForm中初始化oss_storage_quota_value和oss_quota_unit
- 删除重复的旧配额说明块,保留新的当前配额设置显示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-22 19:39:53 +08:00
commit 4350113979
7649 changed files with 897277 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
export const createConfigValueProvider = (configKey, canonicalEndpointParamKey, config, isClientContextParam = false) => {
const configProvider = async () => {
let configValue;
if (isClientContextParam) {
const clientContextParams = config.clientContextParams;
const nestedValue = clientContextParams?.[configKey];
configValue = nestedValue ?? config[configKey] ?? config[canonicalEndpointParamKey];
}
else {
configValue = config[configKey] ?? config[canonicalEndpointParamKey];
}
if (typeof configValue === "function") {
return configValue();
}
return configValue;
};
if (configKey === "credentialScope" || canonicalEndpointParamKey === "CredentialScope") {
return async () => {
const credentials = typeof config.credentials === "function" ? await config.credentials() : config.credentials;
const configValue = credentials?.credentialScope ?? credentials?.CredentialScope;
return configValue;
};
}
if (configKey === "accountId" || canonicalEndpointParamKey === "AccountId") {
return async () => {
const credentials = typeof config.credentials === "function" ? await config.credentials() : config.credentials;
const configValue = credentials?.accountId ?? credentials?.AccountId;
return configValue;
};
}
if (configKey === "endpoint" || canonicalEndpointParamKey === "endpoint") {
return async () => {
if (config.isCustomEndpoint === false) {
return undefined;
}
const endpoint = await configProvider();
if (endpoint && typeof endpoint === "object") {
if ("url" in endpoint) {
return endpoint.url.href;
}
if ("hostname" in endpoint) {
const { protocol, hostname, port, path } = endpoint;
return `${protocol}//${hostname}${port ? ":" + port : ""}${path}`;
}
}
return endpoint;
};
}
return configProvider;
};

View File

@@ -0,0 +1 @@
export const getEndpointFromConfig = async (serviceId) => undefined;

View File

@@ -0,0 +1,3 @@
import { loadConfig } from "@smithy/node-config-provider";
import { getEndpointUrlConfig } from "./getEndpointUrlConfig";
export const getEndpointFromConfig = async (serviceId) => loadConfig(getEndpointUrlConfig(serviceId ?? ""))();

View File

@@ -0,0 +1,55 @@
import { resolveParamsForS3 } from "../service-customizations";
import { createConfigValueProvider } from "./createConfigValueProvider";
import { getEndpointFromConfig } from "./getEndpointFromConfig";
import { toEndpointV1 } from "./toEndpointV1";
export const getEndpointFromInstructions = async (commandInput, instructionsSupplier, clientConfig, context) => {
if (!clientConfig.isCustomEndpoint) {
let endpointFromConfig;
if (clientConfig.serviceConfiguredEndpoint) {
endpointFromConfig = await clientConfig.serviceConfiguredEndpoint();
}
else {
endpointFromConfig = await getEndpointFromConfig(clientConfig.serviceId);
}
if (endpointFromConfig) {
clientConfig.endpoint = () => Promise.resolve(toEndpointV1(endpointFromConfig));
clientConfig.isCustomEndpoint = true;
}
}
const endpointParams = await resolveParams(commandInput, instructionsSupplier, clientConfig);
if (typeof clientConfig.endpointProvider !== "function") {
throw new Error("config.endpointProvider is not set.");
}
const endpoint = clientConfig.endpointProvider(endpointParams, context);
return endpoint;
};
export const resolveParams = async (commandInput, instructionsSupplier, clientConfig) => {
const endpointParams = {};
const instructions = instructionsSupplier?.getEndpointParameterInstructions?.() || {};
for (const [name, instruction] of Object.entries(instructions)) {
switch (instruction.type) {
case "staticContextParams":
endpointParams[name] = instruction.value;
break;
case "contextParams":
endpointParams[name] = commandInput[instruction.name];
break;
case "clientContextParams":
case "builtInParams":
endpointParams[name] = await createConfigValueProvider(instruction.name, name, clientConfig, instruction.type !== "builtInParams")();
break;
case "operationContextParams":
endpointParams[name] = instruction.get(commandInput);
break;
default:
throw new Error("Unrecognized endpoint parameter instruction: " + JSON.stringify(instruction));
}
}
if (Object.keys(instructions).length === 0) {
Object.assign(endpointParams, clientConfig);
}
if (String(clientConfig.serviceId).toLowerCase() === "s3") {
await resolveParamsForS3(endpointParams);
}
return endpointParams;
};

View File

@@ -0,0 +1,31 @@
import { CONFIG_PREFIX_SEPARATOR } from "@smithy/shared-ini-file-loader";
const ENV_ENDPOINT_URL = "AWS_ENDPOINT_URL";
const CONFIG_ENDPOINT_URL = "endpoint_url";
export const getEndpointUrlConfig = (serviceId) => ({
environmentVariableSelector: (env) => {
const serviceSuffixParts = serviceId.split(" ").map((w) => w.toUpperCase());
const serviceEndpointUrl = env[[ENV_ENDPOINT_URL, ...serviceSuffixParts].join("_")];
if (serviceEndpointUrl)
return serviceEndpointUrl;
const endpointUrl = env[ENV_ENDPOINT_URL];
if (endpointUrl)
return endpointUrl;
return undefined;
},
configFileSelector: (profile, config) => {
if (config && profile.services) {
const servicesSection = config[["services", profile.services].join(CONFIG_PREFIX_SEPARATOR)];
if (servicesSection) {
const servicePrefixParts = serviceId.split(" ").map((w) => w.toLowerCase());
const endpointUrl = servicesSection[[servicePrefixParts.join("_"), CONFIG_ENDPOINT_URL].join(CONFIG_PREFIX_SEPARATOR)];
if (endpointUrl)
return endpointUrl;
}
}
const endpointUrl = profile[CONFIG_ENDPOINT_URL];
if (endpointUrl)
return endpointUrl;
return undefined;
},
default: undefined,
});

View File

@@ -0,0 +1,2 @@
export * from "./getEndpointFromInstructions";
export * from "./toEndpointV1";

View File

@@ -0,0 +1,10 @@
import { parseUrl } from "@smithy/url-parser";
export const toEndpointV1 = (endpoint) => {
if (typeof endpoint === "object") {
if ("url" in endpoint) {
return parseUrl(endpoint.url);
}
return endpoint;
}
return parseUrl(endpoint);
};

View File

@@ -0,0 +1,36 @@
import { setFeature } from "@smithy/core";
import { getSmithyContext } from "@smithy/util-middleware";
import { getEndpointFromInstructions } from "./adaptors/getEndpointFromInstructions";
export const endpointMiddleware = ({ config, instructions, }) => {
return (next, context) => async (args) => {
if (config.isCustomEndpoint) {
setFeature(context, "ENDPOINT_OVERRIDE", "N");
}
const endpoint = await getEndpointFromInstructions(args.input, {
getEndpointParameterInstructions() {
return instructions;
},
}, { ...config }, context);
context.endpointV2 = endpoint;
context.authSchemes = endpoint.properties?.authSchemes;
const authScheme = context.authSchemes?.[0];
if (authScheme) {
context["signing_region"] = authScheme.signingRegion;
context["signing_service"] = authScheme.signingName;
const smithyContext = getSmithyContext(context);
const httpAuthOption = smithyContext?.selectedHttpAuthScheme?.httpAuthOption;
if (httpAuthOption) {
httpAuthOption.signingProperties = Object.assign(httpAuthOption.signingProperties || {}, {
signing_region: authScheme.signingRegion,
signingRegion: authScheme.signingRegion,
signing_service: authScheme.signingName,
signingName: authScheme.signingName,
signingRegionSet: authScheme.signingRegionSet,
}, authScheme.properties);
}
}
return next({
...args,
});
};
};

View File

@@ -0,0 +1,18 @@
import { serializerMiddlewareOption } from "@smithy/middleware-serde";
import { endpointMiddleware } from "./endpointMiddleware";
export const endpointMiddlewareOptions = {
step: "serialize",
tags: ["ENDPOINT_PARAMETERS", "ENDPOINT_V2", "ENDPOINT"],
name: "endpointV2Middleware",
override: true,
relation: "before",
toMiddleware: serializerMiddlewareOption.name,
};
export const getEndpointPlugin = (config, instructions) => ({
applyToStack: (clientStack) => {
clientStack.addRelativeTo(endpointMiddleware({
config,
instructions,
}), endpointMiddlewareOptions);
},
});

View File

@@ -0,0 +1,6 @@
export * from "./adaptors";
export * from "./endpointMiddleware";
export * from "./getEndpointPlugin";
export * from "./resolveEndpointConfig";
export * from "./resolveEndpointRequiredConfig";
export * from "./types";

View File

@@ -0,0 +1,24 @@
import { normalizeProvider } from "@smithy/util-middleware";
import { getEndpointFromConfig } from "./adaptors/getEndpointFromConfig";
import { toEndpointV1 } from "./adaptors/toEndpointV1";
export const resolveEndpointConfig = (input) => {
const tls = input.tls ?? true;
const { endpoint, useDualstackEndpoint, useFipsEndpoint } = input;
const customEndpointProvider = endpoint != null ? async () => toEndpointV1(await normalizeProvider(endpoint)()) : undefined;
const isCustomEndpoint = !!endpoint;
const resolvedConfig = Object.assign(input, {
endpoint: customEndpointProvider,
tls,
isCustomEndpoint,
useDualstackEndpoint: normalizeProvider(useDualstackEndpoint ?? false),
useFipsEndpoint: normalizeProvider(useFipsEndpoint ?? false),
});
let configuredEndpointPromise = undefined;
resolvedConfig.serviceConfiguredEndpoint = async () => {
if (input.serviceId && !configuredEndpointPromise) {
configuredEndpointPromise = getEndpointFromConfig(input.serviceId);
}
return configuredEndpointPromise;
};
return resolvedConfig;
};

View File

@@ -0,0 +1,9 @@
export const resolveEndpointRequiredConfig = (input) => {
const { endpoint } = input;
if (endpoint === undefined) {
input.endpoint = async () => {
throw new Error("@smithy/middleware-endpoint: (default endpointRuleSet) endpoint is not set - you must configure an endpoint.");
};
}
return input;
};

View File

@@ -0,0 +1 @@
export * from "./s3";

View File

@@ -0,0 +1,37 @@
export const resolveParamsForS3 = async (endpointParams) => {
const bucket = endpointParams?.Bucket || "";
if (typeof endpointParams.Bucket === "string") {
endpointParams.Bucket = bucket.replace(/#/g, encodeURIComponent("#")).replace(/\?/g, encodeURIComponent("?"));
}
if (isArnBucketName(bucket)) {
if (endpointParams.ForcePathStyle === true) {
throw new Error("Path-style addressing cannot be used with ARN buckets");
}
}
else if (!isDnsCompatibleBucketName(bucket) ||
(bucket.indexOf(".") !== -1 && !String(endpointParams.Endpoint).startsWith("http:")) ||
bucket.toLowerCase() !== bucket ||
bucket.length < 3) {
endpointParams.ForcePathStyle = true;
}
if (endpointParams.DisableMultiRegionAccessPoints) {
endpointParams.disableMultiRegionAccessPoints = true;
endpointParams.DisableMRAP = true;
}
return endpointParams;
};
const DOMAIN_PATTERN = /^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$/;
const IP_ADDRESS_PATTERN = /(\d+\.){3}\d+/;
const DOTS_PATTERN = /\.\./;
export const DOT_PATTERN = /\./;
export const S3_HOSTNAME_PATTERN = /^(.+\.)?s3(-fips)?(\.dualstack)?[.-]([a-z0-9-]+)\./;
export const isDnsCompatibleBucketName = (bucketName) => DOMAIN_PATTERN.test(bucketName) && !IP_ADDRESS_PATTERN.test(bucketName) && !DOTS_PATTERN.test(bucketName);
export const isArnBucketName = (bucketName) => {
const [arn, partition, service, , , bucket] = bucketName.split(":");
const isArn = arn === "arn" && bucketName.split(":").length >= 6;
const isValidArn = Boolean(isArn && partition && service && bucket);
if (isArn && !isValidArn) {
throw new Error(`Invalid ARN: ${bucketName} was an invalid ARN.`);
}
return isValidArn;
};

View File

@@ -0,0 +1 @@
export {};