@cdot65/prisma-airs-cli 5.8.1 → 5.8.3

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.
Files changed (2) hide show
  1. package/dist/cli/index.js +34 -5
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -9879,6 +9879,20 @@ function patternRequest(source, name) {
9879
9879
  function portablePattern(record) {
9880
9880
  return PORTABLE_TECHNIQUES.has(record.detection_config?.technique ?? "") && record.detection_config?.technique !== void 0;
9881
9881
  }
9882
+ function normalizedName(value) {
9883
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
9884
+ }
9885
+ function predefinedCandidates(source, records) {
9886
+ const wanted = normalizedName(source.name ?? "");
9887
+ const wantedTokens = new Set(wanted.split(" "));
9888
+ return records.filter(
9889
+ (record) => record.type === "predefined" && record.name != null && !RETIRED_PATTERN.has(record.status ?? "active") && record.detection_config?.technique === source.detection_config?.technique
9890
+ ).map((record) => {
9891
+ const name = normalizedName(record.name);
9892
+ const score = name === wanted ? 3 : name.includes(wanted) || wanted.includes(name) ? 2 : name.split(" ").some((token) => wantedTokens.has(token)) ? 1 : 0;
9893
+ return { name: record.name, score };
9894
+ }).filter((item) => item.score > 0).sort((a, b) => b.score - a.score || a.name.localeCompare(b.name)).slice(0, 3).map((item) => item.name);
9895
+ }
9882
9896
  function matchByName(records, name, retired, label) {
9883
9897
  const matches = records.filter((record) => record.name === name && !retired(record));
9884
9898
  if (matches.length > 1) throw new Error(`Ambiguous destination ${label} name: ${name}`);
@@ -9957,16 +9971,25 @@ async function planDlpResourcesRestore(api, input2, destinationTsgId, options =
9957
9971
  });
9958
9972
  }
9959
9973
  const patternPlans = [];
9974
+ const missingPredefined = [];
9960
9975
  for (const source of backup.patterns) {
9961
9976
  if (!source.id || !source.name) throw new Error("Backup data pattern lacks identity");
9962
9977
  const retired = (record) => RETIRED_PATTERN.has(record.status ?? "active");
9963
- if (source.type === "predefined") {
9964
- const match2 = matchByName(destination.patterns, source.name, retired, "data pattern");
9965
- if (!match2?.id || match2.type !== "predefined")
9966
- throw new Error(`Missing predefined destination data pattern: ${source.name}`);
9978
+ if (source.type === "predefined" && !Object.hasOwn(patternMap2, source.name)) {
9979
+ const byId = destination.patterns.find(
9980
+ (record) => record.id === source.id && record.type === "predefined" && !retired(record) && record.detection_config?.technique === source.detection_config?.technique
9981
+ );
9982
+ const match2 = byId ?? matchByName(destination.patterns, source.name, retired, "data pattern");
9983
+ if (!match2?.id || !match2.name || match2.type !== "predefined") {
9984
+ missingPredefined.push({
9985
+ name: source.name,
9986
+ candidates: predefinedCandidates(source, destination.patterns)
9987
+ });
9988
+ continue;
9989
+ }
9967
9990
  patternPlans.push({
9968
9991
  sourceId: source.id,
9969
- name: source.name,
9992
+ name: match2.name,
9970
9993
  action: "resolve",
9971
9994
  existing: structuredClone(match2)
9972
9995
  });
@@ -10010,6 +10033,12 @@ async function planDlpResourcesRestore(api, input2, destinationTsgId, options =
10010
10033
  existing: structuredClone(match)
10011
10034
  });
10012
10035
  }
10036
+ if (missingPredefined.length)
10037
+ throw new Error(
10038
+ `Missing predefined destination data patterns: ${missingPredefined.map(
10039
+ (item) => `${item.name}${item.candidates.length ? ` (candidates: ${item.candidates.map((name) => `"${name}"`).join(", ")})` : " (no candidates)"}`
10040
+ ).join("; ")}; bind each with --pattern-map "<source-name>=<destination-name>"`
10041
+ );
10013
10042
  const profilePlans = [];
10014
10043
  for (const source of backup.profiles) {
10015
10044
  if (!source.name) throw new Error("Backup data profile lacks identity");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cdot65/prisma-airs-cli",
3
3
  "packageManager": "pnpm@10.6.5",
4
- "version": "5.8.1",
4
+ "version": "5.8.3",
5
5
  "description": "CLI and library for Palo Alto Prisma AIRS — guardrail refinement, AI red teaming, model security scanning, profile audits",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",