@verentis/cli 0.2.6 → 0.2.7
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/index.js +67 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1038,6 +1038,7 @@ function validateManifest(manifest) {
|
|
|
1038
1038
|
validateApplicationLaunch(spec, issues);
|
|
1039
1039
|
}
|
|
1040
1040
|
validateInstallDirectives(spec.install, issues);
|
|
1041
|
+
validateSettingDeclarations(kind, spec, issues);
|
|
1041
1042
|
for (const message of validateMarketplaceSection(manifest.marketplace)) error(message);
|
|
1042
1043
|
const packaging = manifest.packaging ?? {};
|
|
1043
1044
|
if (!packaging.publisher) warning("packaging.publisher is not set \u2014 `verentis pack`/`publish` will refuse the package");
|
|
@@ -1120,6 +1121,72 @@ function validateInstallDirectives(install, issues) {
|
|
|
1120
1121
|
}
|
|
1121
1122
|
});
|
|
1122
1123
|
}
|
|
1124
|
+
var SETTING_KEY_PATTERN = /^[a-z0-9]+([.-][a-z0-9]+)*$/;
|
|
1125
|
+
var ENV_VAR_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
1126
|
+
var SETTING_TYPES = ["string", "number", "boolean", "select"];
|
|
1127
|
+
function validateSettingDeclarations(kind, spec, issues) {
|
|
1128
|
+
const settings2 = spec.settings;
|
|
1129
|
+
if (settings2 === void 0) return;
|
|
1130
|
+
const error = (message) => issues.push({ level: "error", message });
|
|
1131
|
+
if (!Array.isArray(settings2)) {
|
|
1132
|
+
error("spec.settings must be a list of setting declarations");
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1136
|
+
settings2.forEach((declaration, index) => {
|
|
1137
|
+
const at = `spec.settings[${index}]`;
|
|
1138
|
+
if (!declaration || typeof declaration !== "object" || Array.isArray(declaration)) {
|
|
1139
|
+
error(`${at} must be an object with at least a 'key'`);
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
if (!declaration.key || typeof declaration.key !== "string") {
|
|
1143
|
+
error(`${at}.key is required (short key, stored namespaced as '{metadata.name}.{key}')`);
|
|
1144
|
+
} else if (!SETTING_KEY_PATTERN.test(declaration.key)) {
|
|
1145
|
+
error(`${at}.key '${declaration.key}' must be lowercase kebab/dot notation (e.g. 'api-key' or 'smtp.host')`);
|
|
1146
|
+
} else if (seen.has(declaration.key)) {
|
|
1147
|
+
error(`${at}.key '${declaration.key}' is declared more than once`);
|
|
1148
|
+
} else {
|
|
1149
|
+
seen.add(declaration.key);
|
|
1150
|
+
}
|
|
1151
|
+
if (declaration.env !== void 0) {
|
|
1152
|
+
if (typeof declaration.env !== "string" || !ENV_VAR_PATTERN.test(declaration.env)) {
|
|
1153
|
+
error(`${at}.env must be an environment variable name (UPPER_SNAKE_CASE, e.g. 'MY_API_KEY')`);
|
|
1154
|
+
} else if (declaration.env.startsWith("VERENTIS_")) {
|
|
1155
|
+
error(`${at}.env must not use the reserved 'VERENTIS_' prefix`);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
for (const flag of ["secret", "required"]) {
|
|
1159
|
+
if (declaration[flag] !== void 0 && typeof declaration[flag] !== "boolean") {
|
|
1160
|
+
error(`${at}.${flag} must be a boolean`);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
const type = declaration.type ?? "string";
|
|
1164
|
+
if (typeof type !== "string" || !SETTING_TYPES.includes(type)) {
|
|
1165
|
+
error(`${at}.type must be one of ${SETTING_TYPES.join(", ")} (got '${String(declaration.type)}')`);
|
|
1166
|
+
}
|
|
1167
|
+
if (declaration.secret === true && declaration.default !== void 0) {
|
|
1168
|
+
error(`${at} declares a default for a secret \u2014 secrets must never ship default values`);
|
|
1169
|
+
}
|
|
1170
|
+
if (type === "select") {
|
|
1171
|
+
if (!Array.isArray(declaration.options) || declaration.options.length === 0) {
|
|
1172
|
+
error(`${at}.options is required for type 'select'`);
|
|
1173
|
+
}
|
|
1174
|
+
} else if (declaration.options !== void 0) {
|
|
1175
|
+
error(`${at}.options is only allowed for type 'select'`);
|
|
1176
|
+
}
|
|
1177
|
+
});
|
|
1178
|
+
if (kind === "ExecutionEngine") {
|
|
1179
|
+
const declaresSecret = settings2.some(
|
|
1180
|
+
(declaration) => declaration && typeof declaration === "object" && declaration.secret === true
|
|
1181
|
+
);
|
|
1182
|
+
const runtimes = spec.runtimes ?? {};
|
|
1183
|
+
if (declaresSecret && !runtimes["docker"]) {
|
|
1184
|
+
error(
|
|
1185
|
+
"spec.settings declares secrets but the engine has no docker runtime \u2014 secrets are server-only and cannot be provisioned into browser (wasm) runs"
|
|
1186
|
+
);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1123
1190
|
|
|
1124
1191
|
// src/commands/dev.ts
|
|
1125
1192
|
async function resolveDevScopes(flags) {
|