@armoriq/policy-ir 0.1.2 → 0.1.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.
- package/README.md +1 -0
- package/dist/document-entry-CDOQVeis.d.cts +229 -0
- package/dist/document-entry-CDOQVeis.d.ts +229 -0
- package/dist/document.cjs +722 -0
- package/dist/document.cjs.map +1 -0
- package/dist/document.d.cts +1 -0
- package/dist/document.d.ts +1 -0
- package/dist/document.js +688 -0
- package/dist/document.js.map +1 -0
- package/dist/index.cjs +117 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -228
- package/dist/index.d.ts +3 -228
- package/dist/index.js +117 -14
- package/dist/index.js.map +1 -1
- package/dist/vectors.cjs +43 -1
- package/dist/vectors.cjs.map +1 -1
- package/dist/vectors.js +43 -1
- package/dist/vectors.js.map +1 -1
- package/package.json +29 -6
- package/vectors/document.json +6 -0
- package/vectors/evaluate.json +37 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/document/parse.ts","../src/document/diagnostics.ts","../src/document/grammar.ts","../src/document/reader.ts","../src/evaluate/input.ts","../src/document/portable-regex.ts","../src/document/validate.ts","../src/compile/serialize.ts"],"sourcesContent":["import { parse as parseYamlText } from 'yaml';\nimport type { Approval } from '../ir.js';\nimport { Diagnostics } from './diagnostics.js';\nimport {\n type ConditionSpec,\n type NetworkEntry,\n type Overlay,\n type PolicySource,\n type PolicySpec,\n type RuleValue,\n type RuleVariant,\n SOURCE_OPERATORS,\n type SourceTarget,\n type ToolsSection,\n} from './grammar.js';\nimport { Reader, isPlainObject } from './reader.js';\n\nexport interface ParseResult {\n source: PolicySource | null;\n diagnostics: Diagnostics;\n}\n\n/** Parse `armor.io/v2` YAML text strictly. */\nexport function parseYaml(text: string): ParseResult {\n const diag = new Diagnostics();\n let value: unknown;\n try {\n value = parseYamlText(text);\n } catch (error) {\n diag.error('yaml_syntax', '', (error as Error).message);\n return { source: null, diagnostics: diag };\n }\n return parseValue(value, diag);\n}\n\n/** Parse an already-loaded YAML/JSON value strictly. */\nexport function parseDocument(value: unknown): ParseResult {\n return parseValue(value, new Diagnostics());\n}\n\nconst ROOT_KEYS = ['apiVersion', 'kind', 'metadata', 'target', 'precedence', 'spec'] as const;\nconst SPEC_KEYS = ['tools', 'files', 'network', 'skills', 'secrets', 'members', 'products', 'capture', 'approvalDefaults', 'expiresAt'] as const;\nconst VARIANT_KEYS = ['action', 'when', 'approval', 'reason', 'controls', 'expiresAt'] as const;\n\nfunction parseValue(value: unknown, diag: Diagnostics): ParseResult {\n const r = new Reader(diag);\n const root = r.object(value, '', ROOT_KEYS);\n if (!root) return { source: null, diagnostics: diag };\n if (root.apiVersion !== 'armor.io/v2') diag.error('unsupported_api_version', '/apiVersion', `expected armor.io/v2`);\n if (root.kind !== 'Policy') diag.error('unsupported_kind', '/kind', `expected Policy`);\n const metadata = parseMetadata(r, root.metadata);\n const target = parseTarget(r, diag, root.target);\n const precedence = parsePrecedence(diag, root.precedence);\n const spec = parseSpec(r, diag, root.spec);\n if (diag.hasErrors || !metadata || !target || !spec) return { source: null, diagnostics: diag };\n const source: PolicySource = { apiVersion: 'armor.io/v2', kind: 'Policy', metadata, target, spec };\n if (precedence) source.precedence = precedence;\n return { source, diagnostics: diag };\n}\n\nfunction parseMetadata(r: Reader, value: unknown): PolicySource['metadata'] | null {\n const m = r.object(value, '/metadata', ['name', 'description', 'orgId', 'labels']);\n if (!m) return null;\n const name = r.string(m.name, '/metadata/name');\n if (!name) return null;\n const out: PolicySource['metadata'] = { name };\n const description = r.optionalString(m.description, '/metadata/description');\n const orgId = r.optionalString(m.orgId, '/metadata/orgId');\n if (description) out.description = description;\n if (orgId) out.orgId = orgId;\n if (m.labels !== undefined) out.labels = parseLabels(r, m.labels);\n return out;\n}\n\nfunction parseLabels(r: Reader, value: unknown): Record<string, string> {\n const labels = r.map(value, '/metadata/labels') ?? {};\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(labels)) {\n const s = r.string(v, `/metadata/labels/${k}`);\n if (s) out[k] = s;\n }\n return out;\n}\n\nconst TARGET_FORMS = ['agent', 'group', 'org', 'device'] as const;\n\nfunction parseTarget(r: Reader, diag: Diagnostics, value: unknown): SourceTarget | null {\n const t = r.object(value, '/target', ['agent', 'mcpServers', 'group', 'org', 'device']);\n if (!t) return null;\n const forms = TARGET_FORMS.filter((f) => t[f] !== undefined);\n if (forms.length !== 1) {\n diag.error('target_form', '/target', `exactly one of agent, group, org or device is required; got ${forms.length}`);\n return null;\n }\n return targetOf(r, diag, t, forms[0]!);\n}\n\nfunction targetOf(r: Reader, diag: Diagnostics, t: Record<string, unknown>, form: (typeof TARGET_FORMS)[number]): SourceTarget | null {\n if (form === 'org' || form === 'device') return fixedTarget(diag, t, form);\n if (t.mcpServers !== undefined && form !== 'agent') diag.error('unknown_key', '/target/mcpServers', 'mcpServers belongs to an agent target');\n const id = r.string(t[form], `/target/${form}`);\n if (!id) return null;\n if (form === 'group') return { group: id };\n const servers = r.strings(t.mcpServers, '/target/mcpServers');\n return servers ? { agent: id, mcpServers: servers } : { agent: id };\n}\n\nconst FIXED_TARGETS = {\n org: { value: '*', code: 'target_org', message: 'the organization floor is written as org: \"*\"' },\n device: { value: 'local', code: 'target_device', message: 'the only device target is local' },\n} as const;\n\nfunction fixedTarget(diag: Diagnostics, t: Record<string, unknown>, form: 'org' | 'device'): SourceTarget | null {\n const expected = FIXED_TARGETS[form];\n if (t[form] === expected.value) return form === 'org' ? { org: '*' } : { device: 'local' };\n diag.error(expected.code, `/target/${form}`, expected.message);\n return null;\n}\n\nfunction parsePrecedence(diag: Diagnostics, value: unknown): PolicySource['precedence'] | undefined {\n if (value === undefined || value === 'device-first' || value === 'agent-first') return value as PolicySource['precedence'];\n diag.error('expected_precedence', '/precedence', 'expected device-first or agent-first');\n return undefined;\n}\n\nfunction parseSpec(r: Reader, diag: Diagnostics, value: unknown): PolicySpec | null {\n const s = r.object(value, '/spec', SPEC_KEYS);\n if (!s) return null;\n const tools = parseTools(r, diag, s.tools, '/spec/tools');\n if (!tools) return null;\n const spec: PolicySpec = { tools, expiresAt: r.expiresAt(s.expiresAt, '/spec/expiresAt') };\n assign(spec, 'files', parseFiles(r, s.files));\n assign(spec, 'network', parseNetwork(r, s.network));\n assign(spec, 'skills', parseSkills(r, s.skills));\n assign(spec, 'secrets', parseSecrets(r, s.secrets));\n assign(spec, 'members', parseOverlays(r, diag, s.members, '/spec/members'));\n assign(spec, 'products', parseOverlays(r, diag, s.products, '/spec/products'));\n assign(spec, 'capture', parseCapture(r, s.capture));\n assign(spec, 'approvalDefaults', parseApproval(r, s.approvalDefaults, '/spec/approvalDefaults'));\n return spec;\n}\n\nfunction assign<K extends keyof PolicySpec>(spec: PolicySpec, key: K, value: PolicySpec[K] | undefined): void {\n if (value !== undefined) spec[key] = value;\n}\n\nfunction parseTools(r: Reader, diag: Diagnostics, value: unknown, path: string): ToolsSection | null {\n const t = r.object(value, path, ['default', 'rules']);\n if (!t) return null;\n const dflt = r.verdict(t.default, `${path}/default`);\n if (!dflt) return null;\n const rules = parseRules(r, diag, t.rules, `${path}/rules`);\n return rules ? { default: dflt, rules } : { default: dflt };\n}\n\nfunction parseRules(r: Reader, diag: Diagnostics, value: unknown, path: string): Record<string, RuleValue> | undefined {\n if (value === undefined) return undefined;\n const map = r.map(value, path);\n if (!map) return undefined;\n const out: Record<string, RuleValue> = {};\n for (const [key, rule] of Object.entries(map)) {\n const parsed = parseRule(r, diag, rule, `${path}/${key}`);\n if (parsed) out[key] = parsed;\n }\n return out;\n}\n\n/** A scalar verdict is one unconditional variant; a list is ordered variants. */\nfunction parseRule(r: Reader, diag: Diagnostics, value: unknown, path: string): RuleValue | null {\n if (typeof value === 'string') {\n const v = r.verdict(value, path);\n return v ? [{ action: v, expiresAt: 'never' }] : null;\n }\n if (!Array.isArray(value)) {\n diag.error('expected_rule', path, 'expected a verdict or a list of variants');\n return null;\n }\n const variants = value.map((v, i) => parseVariant(r, diag, v, `${path}/${i}`));\n return variants.every((v): v is RuleVariant => v !== null) ? variants : null;\n}\n\nfunction parseVariant(r: Reader, diag: Diagnostics, value: unknown, path: string): RuleVariant | null {\n const v = r.object(value, path, VARIANT_KEYS);\n if (!v) return null;\n const action = r.verdict(v.action, `${path}/action`);\n if (!action) return null;\n const variant: RuleVariant = { action, expiresAt: r.expiresAt(v.expiresAt, `${path}/expiresAt`) };\n const when = parseWhen(r, diag, v.when, `${path}/when`);\n const approval = parseApproval(r, v.approval, `${path}/approval`);\n const reason = r.optionalString(v.reason, `${path}/reason`);\n const controls = r.strings(v.controls, `${path}/controls`);\n if (when) variant.when = when;\n if (approval) variant.approval = approval;\n if (reason) variant.reason = reason;\n if (controls) variant.controls = controls;\n return variant;\n}\n\nfunction parseWhen(r: Reader, diag: Diagnostics, value: unknown, path: string): Record<string, ConditionSpec> | undefined {\n if (value === undefined) return undefined;\n const map = r.map(value, path);\n if (!map) return undefined;\n const out: Record<string, ConditionSpec> = {};\n for (const [field, spec] of Object.entries(map)) {\n const cond = parseCondition(r, diag, spec, `${path}/${field}`);\n if (cond) out[field] = cond;\n }\n return out;\n}\n\nfunction parseCondition(r: Reader, diag: Diagnostics, value: unknown, path: string): ConditionSpec | null {\n const c = r.object(value, path, SOURCE_OPERATORS);\n if (!c) return null;\n const ops = Object.keys(c);\n if (ops.length !== 1) {\n diag.error('condition_operator', path, `exactly one operator is required; got ${ops.length}`);\n return null;\n }\n return c as ConditionSpec;\n}\n\nfunction parseApproval(r: Reader, value: unknown, path: string): Approval | undefined {\n if (value === undefined) return undefined;\n const a = r.object(value, path, ['approvers', 'roles', 'members', 'anyMember']);\n if (!a) return undefined;\n const approvers = r.number(a.approvers, `${path}/approvers`);\n const out: Approval = { approvers: approvers ?? 1 };\n const roles = r.strings(a.roles, `${path}/roles`);\n const members = r.strings(a.members, `${path}/members`);\n const anyMember = r.boolean(a.anyMember, `${path}/anyMember`);\n if (roles) out.roles = roles;\n if (members) out.members = members;\n if (anyMember !== undefined) out.anyMember = anyMember;\n return out;\n}\n\nfunction parseFiles(r: Reader, value: unknown): PolicySpec['files'] | undefined {\n if (value === undefined) return undefined;\n const f = r.object(value, '/spec/files', ['deny', 'allowOutsideWorkspace']);\n if (!f) return undefined;\n const out: NonNullable<PolicySpec['files']> = {};\n const deny = r.strings(f.deny, '/spec/files/deny');\n const outside = r.boolean(f.allowOutsideWorkspace, '/spec/files/allowOutsideWorkspace');\n if (deny) out.deny = deny;\n if (outside !== undefined) out.allowOutsideWorkspace = outside;\n return out;\n}\n\nfunction parseNetwork(r: Reader, value: unknown): PolicySpec['network'] | undefined {\n if (value === undefined) return undefined;\n const n = r.object(value, '/spec/network', ['default', 'allow', 'deny']);\n if (!n) return undefined;\n const out: NonNullable<PolicySpec['network']> = {};\n const dflt = r.optionalVerdict(n.default, '/spec/network/default');\n const allow = parseNetworkEntries(r, n.allow, '/spec/network/allow');\n const deny = parseNetworkEntries(r, n.deny, '/spec/network/deny');\n if (dflt) out.default = dflt;\n if (allow) out.allow = allow;\n if (deny) out.deny = deny;\n return out;\n}\n\nfunction parseNetworkEntries(r: Reader, value: unknown, path: string): NetworkEntry[] | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n r.strings(value, path);\n return undefined;\n }\n const out: NetworkEntry[] = [];\n value.forEach((entry, i) => {\n if (typeof entry === 'string') return void out.push(entry);\n const e = r.object(entry, `${path}/${i}`, ['host', 'reason']);\n const host = e ? r.string(e.host, `${path}/${i}/host`) : null;\n if (e && host) out.push(e.reason === undefined ? { host } : { host, reason: String(e.reason) });\n });\n return out;\n}\n\nfunction parseSkills(r: Reader, value: unknown): PolicySpec['skills'] | undefined {\n if (value === undefined) return undefined;\n const s = r.object(value, '/spec/skills', ['default', 'hold', 'block']);\n if (!s) return undefined;\n const out: NonNullable<PolicySpec['skills']> = {};\n const dflt = r.optionalVerdict(s.default, '/spec/skills/default');\n const hold = r.strings(s.hold, '/spec/skills/hold');\n const block = r.strings(s.block, '/spec/skills/block');\n if (dflt) out.default = dflt;\n if (hold) out.hold = hold;\n if (block) out.block = block;\n return out;\n}\n\nfunction parseSecrets(r: Reader, value: unknown): PolicySpec['secrets'] | undefined {\n if (value === undefined) return undefined;\n const s = r.object(value, '/spec/secrets', ['envBlocklist']);\n if (!s) return undefined;\n const envBlocklist = r.strings(s.envBlocklist, '/spec/secrets/envBlocklist');\n return envBlocklist ? { envBlocklist } : {};\n}\n\nfunction parseOverlays(r: Reader, diag: Diagnostics, value: unknown, path: string): Record<string, Overlay> | undefined {\n if (value === undefined) return undefined;\n const map = r.map(value, path);\n if (!map) return undefined;\n const out: Record<string, Overlay> = {};\n for (const [key, overlay] of Object.entries(map)) {\n const parsed = parseOverlay(r, diag, overlay, `${path}/${key}`);\n if (parsed) out[key] = parsed;\n }\n return out;\n}\n\nfunction parseOverlay(r: Reader, diag: Diagnostics, value: unknown, path: string): Overlay | null {\n const o = r.object(value, path, ['tools', 'expiresAt']);\n if (!o) return null;\n const overlay: Overlay = { expiresAt: r.expiresAt(o.expiresAt, `${path}/expiresAt`) };\n if (o.tools === undefined) return overlay;\n const t = r.object(o.tools, `${path}/tools`, ['default', 'rules']);\n if (!t) return overlay;\n const tools: NonNullable<Overlay['tools']> = {};\n const dflt = r.optionalVerdict(t.default, `${path}/tools/default`);\n const rules = parseRules(r, diag, t.rules, `${path}/tools/rules`);\n if (dflt) tools.default = dflt;\n if (rules) tools.rules = rules;\n overlay.tools = tools;\n return overlay;\n}\n\nfunction parseCapture(r: Reader, value: unknown): PolicySpec['capture'] | undefined {\n if (value === undefined) return undefined;\n const c = r.object(value, '/spec/capture', ['arguments', 'redact', 'maxBytesPerCall', 'sample']);\n if (!c) return undefined;\n const out: NonNullable<PolicySpec['capture']> = {};\n const args = r.boolean(c.arguments, '/spec/capture/arguments');\n const redact = r.strings(c.redact, '/spec/capture/redact');\n const max = r.number(c.maxBytesPerCall, '/spec/capture/maxBytesPerCall');\n const sample = r.number(c.sample, '/spec/capture/sample');\n if (args !== undefined) out.arguments = args;\n if (redact) out.redact = redact;\n if (max !== undefined) out.maxBytesPerCall = max;\n if (sample !== undefined) out.sample = sample;\n return out;\n}\n\nexport { isPlainObject };\n","export type Severity = 'error' | 'warning';\n\nexport interface Diagnostic {\n code: string;\n severity: Severity;\n /** JSON-pointer-like path into the source document, `/spec/tools/rules/Bash/0`. */\n path: string;\n message: string;\n}\n\nexport class Diagnostics {\n readonly items: Diagnostic[] = [];\n\n error(code: string, path: string, message: string): void {\n this.items.push({ code, severity: 'error', path, message });\n }\n\n warning(code: string, path: string, message: string): void {\n this.items.push({ code, severity: 'warning', path, message });\n }\n\n get hasErrors(): boolean {\n return this.items.some((d) => d.severity === 'error');\n }\n}\n","import type { Approval, Verdict } from '../ir.js';\n\n/** The `armor.io/v2` source document after strict parsing, before lowering. */\nexport interface PolicySource {\n apiVersion: 'armor.io/v2';\n kind: 'Policy';\n metadata: { name: string; description?: string; orgId?: string; labels?: Record<string, string> };\n target: SourceTarget;\n precedence?: 'device-first' | 'agent-first';\n spec: PolicySpec;\n}\n\nexport type SourceTarget =\n | { agent: string; mcpServers?: string[] }\n | { group: string }\n | { org: '*' }\n | { device: 'local' };\n\nexport interface PolicySpec {\n tools: ToolsSection;\n files?: { deny?: string[]; allowOutsideWorkspace?: boolean };\n network?: { default?: Verdict; allow?: NetworkEntry[]; deny?: NetworkEntry[] };\n skills?: { default?: Verdict; hold?: string[]; block?: string[] };\n secrets?: { envBlocklist?: string[] };\n members?: Record<string, Overlay>;\n products?: Record<string, Overlay>;\n capture?: { arguments?: boolean; redact?: string[]; maxBytesPerCall?: number; sample?: number };\n approvalDefaults?: Approval;\n expiresAt: string;\n}\n\nexport type NetworkEntry = string | { host: string; reason?: string };\n\nexport interface ToolsSection {\n default: Verdict;\n rules?: Record<string, RuleValue>;\n}\n\nexport interface Overlay {\n tools?: { default?: Verdict; rules?: Record<string, RuleValue> };\n expiresAt: string;\n}\n\n/** A scalar verdict is shorthand for one unconditional variant. */\nexport type RuleValue = Verdict | RuleVariant[];\n\nexport interface RuleVariant {\n action: Verdict;\n when?: Record<string, ConditionSpec>;\n approval?: Approval;\n reason?: string;\n controls?: string[];\n expiresAt: string;\n}\n\n/** `{gt: 5000}`, `{in: [a, b]}`, `{matches: '^x'}`, `{exists: true}`. Exactly one operator. */\nexport type ConditionSpec = Partial<Record<SourceOperator, unknown>>;\n\nexport const SOURCE_OPERATORS = [\n 'eq',\n 'neq',\n 'in',\n 'notIn',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'matches',\n 'notMatches',\n 'startsWith',\n 'glob',\n 'withinWorkspace',\n 'exists',\n] as const;\nexport type SourceOperator = (typeof SOURCE_OPERATORS)[number];\n\nexport const VERDICTS: readonly Verdict[] = ['allow', 'hold', 'block'];\nexport const NEVER = 'never';\n","import type { Verdict } from '../ir.js';\nimport type { Diagnostics } from './diagnostics.js';\nimport { NEVER, VERDICTS } from './grammar.js';\n\n/**\n * Strict field readers over a parsed YAML value. Every unknown key is an\n * error (VC-2): a typo such as `denyTools:` must never become a no-op.\n */\nexport class Reader {\n constructor(private readonly diag: Diagnostics) {}\n\n object(value: unknown, path: string, keys: readonly string[]): Record<string, unknown> | null {\n if (!isPlainObject(value)) {\n this.diag.error('expected_object', path, `expected a mapping, got ${describe(value)}`);\n return null;\n }\n for (const key of Object.keys(value)) {\n if (!keys.includes(key)) this.diag.error('unknown_key', `${path}/${key}`, `unknown key \"${key}\"`);\n }\n return value;\n }\n\n /** A mapping whose keys are user-chosen (rule keys, member keys). */\n map(value: unknown, path: string): Record<string, unknown> | null {\n if (isPlainObject(value)) return value;\n this.diag.error('expected_object', path, `expected a mapping, got ${describe(value)}`);\n return null;\n }\n\n string(value: unknown, path: string): string | null {\n if (typeof value === 'string' && value.length > 0) return value;\n this.diag.error('expected_string', path, `expected a non-empty string, got ${describe(value)}`);\n return null;\n }\n\n optionalString(value: unknown, path: string): string | undefined {\n return value === undefined ? undefined : (this.string(value, path) ?? undefined);\n }\n\n boolean(value: unknown, path: string): boolean | undefined {\n if (value === undefined || typeof value === 'boolean') return value;\n this.diag.error('expected_boolean', path, `expected true or false, got ${describe(value)}`);\n return undefined;\n }\n\n number(value: unknown, path: string): number | undefined {\n if (value === undefined || (typeof value === 'number' && Number.isFinite(value))) return value;\n this.diag.error('expected_number', path, `expected a number, got ${describe(value)}`);\n return undefined;\n }\n\n strings(value: unknown, path: string): string[] | undefined {\n if (value === undefined) return undefined;\n if (Array.isArray(value) && value.every((v) => typeof v === 'string')) return value as string[];\n this.diag.error('expected_string_list', path, `expected a list of strings, got ${describe(value)}`);\n return undefined;\n }\n\n verdict(value: unknown, path: string): Verdict | null {\n if (typeof value === 'string' && (VERDICTS as readonly string[]).includes(value)) return value as Verdict;\n this.diag.error('expected_verdict', path, `expected allow, hold or block, got ${describe(value)}`);\n return null;\n }\n\n optionalVerdict(value: unknown, path: string): Verdict | undefined {\n return value === undefined ? undefined : (this.verdict(value, path) ?? undefined);\n }\n\n /** `never` or ISO-8601; absent materializes to `never` (VC-7c, FR-22). */\n expiresAt(value: unknown, path: string): string {\n if (value === undefined) return NEVER;\n if (value instanceof Date) return value.toISOString();\n if (value === NEVER) return NEVER;\n if (typeof value === 'string' && !Number.isNaN(Date.parse(value))) return new Date(value).toISOString();\n this.diag.error('expected_expiry', path, `expected \"never\" or an ISO-8601 date-time, got ${describe(value)}`);\n return NEVER;\n }\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);\n}\n\nexport function describe(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'a list';\n if (value instanceof Date) return 'a date';\n return typeof value === 'object' ? 'a mapping' : JSON.stringify(value);\n}\n","import type { Approval, Layer, Verdict } from '../ir.js';\n\nexport interface Principal {\n membershipId?: string;\n email?: string;\n groups?: string[];\n /** The local agent making the call, for a `products:` overlay. */\n product?: string;\n}\n\n/** One call, as the enforce path and the local hook both see it. */\nexport interface CallInput {\n tool: string;\n arguments: Record<string, unknown>;\n /**\n * Derived fields a host may supply: `path`, `program`, `command`,\n * `writeRedirection`, `withinWorkspace`, `url`, `host`, `skill`, `env`.\n * Globs are literal, so a host writes `path` home-relative (`~/.ssh/id_rsa`)\n * when the path is under the user's home; `files.deny: [\"~/.ssh/**\"]` then\n * matches exactly what the author wrote.\n */\n derived?: Record<string, unknown>;\n /** Capability tags the inventory holds for this tool. */\n capabilities?: string[];\n /** The tool's live input-schema hash, when the caller knows it. */\n schemaHash?: string | null;\n member?: Principal;\n /** ISO date-time the call is evaluated at. */\n timestamp: string;\n}\n\nexport interface SchemaDriftObligation {\n type: 'schema_drift';\n statementId: string;\n bound: string;\n observed: string | null;\n}\n\nexport type Obligation = SchemaDriftObligation;\n\nexport interface VerdictProvenance {\n policyId: string;\n statementId: string | null;\n ruleKey: string;\n variant: number;\n layer: Layer;\n}\n\nexport interface Evaluation {\n verdict: Verdict;\n /** The floor's own verdict, so a caller can tell a floor block from a rule block. */\n floorVerdict: Verdict | null;\n approval: Approval | null;\n obligations: Obligation[];\n provenance: VerdictProvenance;\n}\n\nexport const VERDICT_RANK: Record<Verdict, number> = { allow: 0, hold: 1, block: 2 };\n\nexport function stricter(a: Verdict, b: Verdict): Verdict {\n return VERDICT_RANK[a] >= VERDICT_RANK[b] ? a : b;\n}\n","/** The regex subset RegExp, RE2 and the Python translator (python/armoriq_policy_ir/jsregex.py) all read alike; both parsers walk UTF-16 units. */\nexport function isPortablePattern(pattern: unknown): boolean {\n if (typeof pattern !== 'string') return false;\n try {\n new RegExp(pattern);\n } catch {\n return false;\n }\n const parser = new Parser(pattern);\n return parser.alternatives() && parser.done();\n}\n\ntype Atom = 'quantifiable' | 'assertion' | null;\ntype ClassAtom = 'char' | 'set' | null;\n\nconst ESCAPED_PUNCTUATION = new Set('\\\\/.*+?()[]{}|^$-');\nconst CONTROL_ESCAPES = new Set('tnrfv');\nconst SET_ESCAPES = new Set('dwsDWS');\nconst CLASS_SET_ESCAPES = new Set('dws');\nconst BARE_SPECIALS = new Set(']{}*+?');\nconst QUANTIFIER = /^\\{\\d+(,\\d*)?\\}/;\n\nclass Parser {\n private i = 0;\n\n constructor(private readonly p: string) {}\n\n done(): boolean {\n return this.i === this.p.length;\n }\n\n alternatives(): boolean {\n while (!this.done() && this.p[this.i] !== ')') {\n if (this.p[this.i] === '|') this.i++;\n else if (!this.term()) return false;\n }\n return true;\n }\n\n private term(): boolean {\n const atom = this.atom();\n return atom !== null && this.quantifier(atom === 'quantifiable');\n }\n\n private atom(): Atom {\n const c = this.p[this.i++]!;\n if (c === '^' || c === '$') return 'assertion';\n if (c === '\\\\') return this.escape();\n if (c === '[') return this.charClass() ? 'quantifiable' : null;\n if (c === '(') return this.group() ? 'quantifiable' : null;\n return BARE_SPECIALS.has(c) ? null : 'quantifiable';\n }\n\n private escape(): Atom {\n const e = this.p[this.i++] ?? '';\n if (e === 'b' || e === 'B') return 'assertion';\n if (SET_ESCAPES.has(e) || CONTROL_ESCAPES.has(e) || ESCAPED_PUNCTUATION.has(e)) return 'quantifiable';\n return this.hexEscape(e) ? 'quantifiable' : null;\n }\n\n private hexEscape(e: string): boolean {\n const width = e === 'x' ? 2 : e === 'u' ? 4 : 0;\n const digits = this.p.slice(this.i, this.i + width);\n if (width === 0 || !/^[0-9a-fA-F]+$/.test(digits) || digits.length !== width) return false;\n this.i += width;\n return true;\n }\n\n private group(): boolean {\n if (this.p[this.i] === '?') {\n if (this.p[this.i + 1] !== ':') return false;\n this.i += 2;\n }\n if (!this.alternatives() || this.p[this.i] !== ')') return false;\n this.i++;\n return true;\n }\n\n private charClass(): boolean {\n if (this.p[this.i] === '^') this.i++;\n if (this.p[this.i] === ']') return false;\n while (!this.done() && this.p[this.i] !== ']') {\n if (!this.classItem()) return false;\n }\n if (this.done()) return false;\n this.i++;\n return true;\n }\n\n private classItem(): boolean {\n const start = this.classAtom();\n if (start === null) return false;\n if (this.p[this.i] !== '-' || this.p[this.i + 1] === ']') return true;\n this.i++;\n return start === 'char' && this.classAtom() === 'char';\n }\n\n private classAtom(): ClassAtom {\n const c = this.p[this.i++]!;\n if (c === '[') return null;\n if (c !== '\\\\') return isSurrogate(c) ? null : 'char';\n const e = this.p[this.i++] ?? '';\n if (CLASS_SET_ESCAPES.has(e)) return 'set';\n if (CONTROL_ESCAPES.has(e) || ESCAPED_PUNCTUATION.has(e)) return 'char';\n return this.hexEscape(e) ? 'char' : null;\n }\n\n private quantifier(quantifiable: boolean): boolean {\n const length = this.quantifierLength();\n if (length === 0) return true;\n if (length < 0 || !quantifiable) return false;\n this.i += length;\n if (this.p[this.i] === '?') this.i++;\n return true;\n }\n\n private quantifierLength(): number {\n const c = this.p[this.i];\n if (c === '*' || c === '+' || c === '?') return 1;\n if (c !== '{') return 0;\n return QUANTIFIER.exec(this.p.slice(this.i))?.[0].length ?? -1;\n }\n}\n\nfunction isSurrogate(c: string): boolean {\n const code = c.charCodeAt(0);\n return code >= 0xd800 && code <= 0xdfff;\n}\n","import type { Approval, Verdict } from '../ir.js';\nimport { VERDICT_RANK } from '../evaluate/input.js';\nimport { Diagnostics } from './diagnostics.js';\nimport type { ConditionSpec, Overlay, PolicySource, RuleValue, RuleVariant, SourceOperator } from './grammar.js';\nimport { isPortablePattern } from './portable-regex.js';\n\n/**\n * Everything that can be checked without an inventory. Inventory-dependent\n * checks (roster clamp, glob collisions on real tools, schema binding) live in\n * the compiler.\n */\nexport function validate(source: PolicySource): Diagnostics {\n const diag = new Diagnostics();\n const ctx: Context = { diag, approvalDefaults: source.spec.approvalDefaults, base: source.spec.tools };\n validateTargetSections(ctx, source);\n if (source.spec.approvalDefaults) validateApproval(ctx, source.spec.approvalDefaults, '/spec/approvalDefaults', true);\n validateRules(ctx, source.spec.tools.rules, '/spec/tools/rules');\n validateOverlays(ctx, source.spec.members, '/spec/members');\n validateOverlays(ctx, source.spec.products, '/spec/products');\n validateCapture(ctx, source);\n return diag;\n}\n\ninterface Context {\n diag: Diagnostics;\n approvalDefaults: Approval | undefined;\n base: PolicySource['spec']['tools'];\n}\n\n/** `products:` and `precedence:` are local only; `members:` is enterprise only (VC-17, VC-18). */\nfunction validateTargetSections(ctx: Context, source: PolicySource): void {\n const local = 'device' in source.target;\n if (!local && source.spec.products) ctx.diag.error('local_only_section', '/spec/products', 'products applies only under target device: local');\n if (!local && source.precedence) ctx.diag.error('local_only_section', '/precedence', 'precedence applies only under target device: local');\n if (local && source.spec.members) ctx.diag.error('enterprise_only_section', '/spec/members', 'members applies only to an enterprise target');\n if (local && source.metadata.orgId) ctx.diag.error('enterprise_only_field', '/metadata/orgId', 'a local policy carries no orgId');\n}\n\nfunction validateRules(ctx: Context, rules: Record<string, RuleValue> | undefined, path: string): void {\n for (const [key, variants] of Object.entries(rules ?? {})) {\n validateVariants(ctx, variants as RuleVariant[], `${path}/${key}`);\n }\n}\n\nfunction validateVariants(ctx: Context, variants: RuleVariant[], path: string): void {\n variants.forEach((variant, i) => {\n const vpath = `${path}/${i}`;\n if (i > 0 && isUnconditional(variants[i - 1]!)) {\n ctx.diag.error('unreachable_variant', vpath, `variant ${i - 1} has no when, so this variant can never be reached`);\n }\n validateVariant(ctx, variant, vpath);\n });\n}\n\nfunction isUnconditional(variant: RuleVariant): boolean {\n return !variant.when || Object.keys(variant.when).length === 0;\n}\n\nfunction validateVariant(ctx: Context, variant: RuleVariant, path: string): void {\n if (variant.action === 'hold') validateHoldApprover(ctx, variant, path);\n for (const [field, spec] of Object.entries(variant.when ?? {})) validateCondition(ctx, spec, `${path}/when/${field}`);\n}\n\n/** A hold must name a way to resolve its approver, on the variant or in approvalDefaults (VC-6). */\nfunction validateHoldApprover(ctx: Context, variant: RuleVariant, path: string): void {\n if (variant.approval) return void validateApproval(ctx, variant.approval, `${path}/approval`, true);\n if (!ctx.approvalDefaults) {\n ctx.diag.error('hold_without_approver', path, 'a hold names an approval or the document sets approvalDefaults');\n }\n}\n\nfunction validateApproval(ctx: Context, approval: Approval, path: string, requireResolvable: boolean): void {\n if (!Number.isInteger(approval.approvers) || approval.approvers < 1) {\n ctx.diag.error('approvers_count', `${path}/approvers`, 'approvers is a whole number of at least 1');\n }\n if (requireResolvable && !namesAnApprover(approval)) {\n ctx.diag.error('approval_unresolvable', path, 'an approval names roles, members or anyMember: true');\n }\n}\n\nfunction namesAnApprover(approval: Approval): boolean {\n return (approval.roles?.length ?? 0) > 0 || (approval.members?.length ?? 0) > 0 || approval.anyMember === true;\n}\n\ntype OperandCheck = (value: unknown) => boolean;\n\nconst OPERANDS: Record<SourceOperator, [OperandCheck, string]> = {\n eq: [() => true, 'any value'],\n neq: [() => true, 'any value'],\n in: [Array.isArray, 'a list'],\n notIn: [Array.isArray, 'a list'],\n gt: [isNumber, 'a number'],\n gte: [isNumber, 'a number'],\n lt: [isNumber, 'a number'],\n lte: [isNumber, 'a number'],\n matches: [isPortablePattern, 'a regular expression in the portable subset'],\n notMatches: [isPortablePattern, 'a regular expression in the portable subset'],\n startsWith: [isString, 'a string'],\n glob: [isString, 'a glob'],\n withinWorkspace: [isBoolean, 'true or false'],\n exists: [isBoolean, 'true or false'],\n};\n\nfunction validateCondition(ctx: Context, spec: ConditionSpec, path: string): void {\n const [op, value] = Object.entries(spec)[0] as [SourceOperator, unknown];\n const [check, expected] = OPERANDS[op];\n if (!check(value)) ctx.diag.error('condition_operand', `${path}/${op}`, `${op} takes ${expected}`);\n}\n\nfunction isNumber(v: unknown): boolean {\n return typeof v === 'number' && Number.isFinite(v);\n}\nfunction isString(v: unknown): boolean {\n return typeof v === 'string';\n}\nfunction isBoolean(v: unknown): boolean {\n return typeof v === 'boolean';\n}\n\nfunction validateOverlays(ctx: Context, overlays: Record<string, Overlay> | undefined, path: string): void {\n for (const [key, overlay] of Object.entries(overlays ?? {})) {\n const opath = `${path}/${key}`;\n validateRules(ctx, overlay.tools?.rules, `${opath}/tools/rules`);\n flagLoosening(ctx, overlay, opath);\n }\n}\n\n/** A member or product overlay may loosen the base; the review diff must show it (VC-7). */\nfunction flagLoosening(ctx: Context, overlay: Overlay, path: string): void {\n const baseDefault = ctx.base.default;\n if (overlay.tools?.default && looser(overlay.tools.default, baseDefault)) {\n ctx.diag.warning('loosening_grant', `${path}/tools/default`, `default ${overlay.tools.default} is looser than the base default ${baseDefault}`);\n }\n for (const [key, variants] of Object.entries(overlay.tools?.rules ?? {})) {\n const base = baseVerdictFor(ctx.base, key);\n const loosest = (variants as RuleVariant[]).reduce<Verdict>((v, x) => (looser(x.action, v) ? x.action : v), 'block');\n if (looser(loosest, base)) {\n ctx.diag.warning('loosening_grant', `${path}/tools/rules/${key}`, `${key}: ${loosest} is looser than the base ${base}`);\n }\n }\n}\n\n/**\n * What the base can do at its strictest for a key: an overlay verdict looser\n * than that bypasses at least one base variant. No rule means tools.default.\n */\nfunction baseVerdictFor(base: PolicySource['spec']['tools'], key: string): Verdict {\n const variants = base.rules?.[key] as RuleVariant[] | undefined;\n if (!variants) return base.default;\n return variants.reduce<Verdict>((v, x) => (looser(v, x.action) ? x.action : v), 'allow');\n}\n\nfunction looser(a: Verdict, b: Verdict): boolean {\n return VERDICT_RANK[a] < VERDICT_RANK[b];\n}\n\nfunction validateCapture(ctx: Context, source: PolicySource): void {\n const c = source.spec.capture;\n if (!c) return;\n if (c.sample !== undefined && (c.sample < 0 || c.sample > 1)) ctx.diag.error('capture_sample', '/spec/capture/sample', 'sample is between 0 and 1');\n if (c.maxBytesPerCall !== undefined && (c.maxBytesPerCall < 0 || !Number.isInteger(c.maxBytesPerCall))) {\n ctx.diag.error('capture_max_bytes', '/spec/capture/maxBytesPerCall', 'maxBytesPerCall is a whole number of bytes');\n }\n}\n","import { stringify } from 'yaml';\nimport type { PolicySource, RuleValue, RuleVariant } from '../document/grammar.js';\n\n/**\n * PolicySource back to YAML such that `parse(serialize(x))` equals `x`\n * (VC-10). A single unconditional variant with no other fields is written as\n * the scalar shorthand; `expiresAt: never` is written only where the parser\n * would not materialize it identically anyway (everywhere), so it is kept.\n */\nexport function serialize(source: PolicySource): string {\n const spec = { ...source.spec, tools: { ...source.spec.tools, rules: shorthand(source.spec.tools.rules) } };\n if (spec.members) spec.members = overlays(spec.members);\n if (spec.products) spec.products = overlays(spec.products);\n const doc: Record<string, unknown> = {\n apiVersion: source.apiVersion,\n kind: source.kind,\n metadata: source.metadata,\n target: source.target,\n };\n if (source.precedence) doc.precedence = source.precedence;\n doc.spec = spec;\n return stringify(doc, { lineWidth: 0, defaultStringType: 'PLAIN', defaultKeyType: 'PLAIN', aliasDuplicateObjects: false });\n}\n\nfunction shorthand(rules: Record<string, RuleValue> | undefined): Record<string, RuleValue> | undefined {\n if (!rules) return undefined;\n const out: Record<string, RuleValue> = {};\n for (const [key, value] of Object.entries(rules)) out[key] = scalarIfPlain(value as RuleVariant[]);\n return out;\n}\n\nfunction scalarIfPlain(variants: RuleVariant[]): RuleValue {\n const only = variants.length === 1 ? variants[0]! : null;\n const plain = only && Object.keys(only).length === 2 && only.expiresAt === 'never';\n return plain ? only.action : variants;\n}\n\nfunction overlays<T extends { tools?: { rules?: Record<string, RuleValue> } }>(map: Record<string, T>): Record<string, T> {\n const out: Record<string, T> = {};\n for (const [key, overlay] of Object.entries(map)) {\n out[key] = overlay.tools?.rules ? { ...overlay, tools: { ...overlay.tools, rules: shorthand(overlay.tools.rules) } } : overlay;\n }\n return out;\n}\n"],"mappings":"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","names":["overlays"]}
|
package/dist/index.cjs
CHANGED
|
@@ -232,11 +232,11 @@ function escapeRegExp(ch) {
|
|
|
232
232
|
// src/evaluate/conditions.ts
|
|
233
233
|
function resolveField(input, field) {
|
|
234
234
|
const [root, ...rest] = field.split(".");
|
|
235
|
-
const base = root === "args" ? input.arguments : input.derived
|
|
235
|
+
const base = root === "args" ? input.arguments : childOf2(input.derived, root ?? "");
|
|
236
236
|
return rest.reduce(childOf2, base);
|
|
237
237
|
}
|
|
238
238
|
function childOf2(node, key) {
|
|
239
|
-
if (node === null || typeof node !== "object") return void 0;
|
|
239
|
+
if (node === null || typeof node !== "object" || !Object.hasOwn(node, key)) return void 0;
|
|
240
240
|
return node[key];
|
|
241
241
|
}
|
|
242
242
|
function conditionsHold(input, conditions) {
|
|
@@ -828,6 +828,119 @@ function parseCapture(r, value) {
|
|
|
828
828
|
return out;
|
|
829
829
|
}
|
|
830
830
|
|
|
831
|
+
// src/document/portable-regex.ts
|
|
832
|
+
function isPortablePattern(pattern) {
|
|
833
|
+
if (typeof pattern !== "string") return false;
|
|
834
|
+
try {
|
|
835
|
+
new RegExp(pattern);
|
|
836
|
+
} catch {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
const parser = new Parser(pattern);
|
|
840
|
+
return parser.alternatives() && parser.done();
|
|
841
|
+
}
|
|
842
|
+
var ESCAPED_PUNCTUATION = new Set("\\/.*+?()[]{}|^$-");
|
|
843
|
+
var CONTROL_ESCAPES = new Set("tnrfv");
|
|
844
|
+
var SET_ESCAPES = new Set("dwsDWS");
|
|
845
|
+
var CLASS_SET_ESCAPES = new Set("dws");
|
|
846
|
+
var BARE_SPECIALS = new Set("]{}*+?");
|
|
847
|
+
var QUANTIFIER = /^\{\d+(,\d*)?\}/;
|
|
848
|
+
var Parser = class {
|
|
849
|
+
constructor(p) {
|
|
850
|
+
this.p = p;
|
|
851
|
+
}
|
|
852
|
+
p;
|
|
853
|
+
i = 0;
|
|
854
|
+
done() {
|
|
855
|
+
return this.i === this.p.length;
|
|
856
|
+
}
|
|
857
|
+
alternatives() {
|
|
858
|
+
while (!this.done() && this.p[this.i] !== ")") {
|
|
859
|
+
if (this.p[this.i] === "|") this.i++;
|
|
860
|
+
else if (!this.term()) return false;
|
|
861
|
+
}
|
|
862
|
+
return true;
|
|
863
|
+
}
|
|
864
|
+
term() {
|
|
865
|
+
const atom = this.atom();
|
|
866
|
+
return atom !== null && this.quantifier(atom === "quantifiable");
|
|
867
|
+
}
|
|
868
|
+
atom() {
|
|
869
|
+
const c = this.p[this.i++];
|
|
870
|
+
if (c === "^" || c === "$") return "assertion";
|
|
871
|
+
if (c === "\\") return this.escape();
|
|
872
|
+
if (c === "[") return this.charClass() ? "quantifiable" : null;
|
|
873
|
+
if (c === "(") return this.group() ? "quantifiable" : null;
|
|
874
|
+
return BARE_SPECIALS.has(c) ? null : "quantifiable";
|
|
875
|
+
}
|
|
876
|
+
escape() {
|
|
877
|
+
const e = this.p[this.i++] ?? "";
|
|
878
|
+
if (e === "b" || e === "B") return "assertion";
|
|
879
|
+
if (SET_ESCAPES.has(e) || CONTROL_ESCAPES.has(e) || ESCAPED_PUNCTUATION.has(e)) return "quantifiable";
|
|
880
|
+
return this.hexEscape(e) ? "quantifiable" : null;
|
|
881
|
+
}
|
|
882
|
+
hexEscape(e) {
|
|
883
|
+
const width = e === "x" ? 2 : e === "u" ? 4 : 0;
|
|
884
|
+
const digits = this.p.slice(this.i, this.i + width);
|
|
885
|
+
if (width === 0 || !/^[0-9a-fA-F]+$/.test(digits) || digits.length !== width) return false;
|
|
886
|
+
this.i += width;
|
|
887
|
+
return true;
|
|
888
|
+
}
|
|
889
|
+
group() {
|
|
890
|
+
if (this.p[this.i] === "?") {
|
|
891
|
+
if (this.p[this.i + 1] !== ":") return false;
|
|
892
|
+
this.i += 2;
|
|
893
|
+
}
|
|
894
|
+
if (!this.alternatives() || this.p[this.i] !== ")") return false;
|
|
895
|
+
this.i++;
|
|
896
|
+
return true;
|
|
897
|
+
}
|
|
898
|
+
charClass() {
|
|
899
|
+
if (this.p[this.i] === "^") this.i++;
|
|
900
|
+
if (this.p[this.i] === "]") return false;
|
|
901
|
+
while (!this.done() && this.p[this.i] !== "]") {
|
|
902
|
+
if (!this.classItem()) return false;
|
|
903
|
+
}
|
|
904
|
+
if (this.done()) return false;
|
|
905
|
+
this.i++;
|
|
906
|
+
return true;
|
|
907
|
+
}
|
|
908
|
+
classItem() {
|
|
909
|
+
const start = this.classAtom();
|
|
910
|
+
if (start === null) return false;
|
|
911
|
+
if (this.p[this.i] !== "-" || this.p[this.i + 1] === "]") return true;
|
|
912
|
+
this.i++;
|
|
913
|
+
return start === "char" && this.classAtom() === "char";
|
|
914
|
+
}
|
|
915
|
+
classAtom() {
|
|
916
|
+
const c = this.p[this.i++];
|
|
917
|
+
if (c === "[") return null;
|
|
918
|
+
if (c !== "\\") return isSurrogate(c) ? null : "char";
|
|
919
|
+
const e = this.p[this.i++] ?? "";
|
|
920
|
+
if (CLASS_SET_ESCAPES.has(e)) return "set";
|
|
921
|
+
if (CONTROL_ESCAPES.has(e) || ESCAPED_PUNCTUATION.has(e)) return "char";
|
|
922
|
+
return this.hexEscape(e) ? "char" : null;
|
|
923
|
+
}
|
|
924
|
+
quantifier(quantifiable) {
|
|
925
|
+
const length = this.quantifierLength();
|
|
926
|
+
if (length === 0) return true;
|
|
927
|
+
if (length < 0 || !quantifiable) return false;
|
|
928
|
+
this.i += length;
|
|
929
|
+
if (this.p[this.i] === "?") this.i++;
|
|
930
|
+
return true;
|
|
931
|
+
}
|
|
932
|
+
quantifierLength() {
|
|
933
|
+
const c = this.p[this.i];
|
|
934
|
+
if (c === "*" || c === "+" || c === "?") return 1;
|
|
935
|
+
if (c !== "{") return 0;
|
|
936
|
+
return QUANTIFIER.exec(this.p.slice(this.i))?.[0].length ?? -1;
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
function isSurrogate(c) {
|
|
940
|
+
const code = c.charCodeAt(0);
|
|
941
|
+
return code >= 55296 && code <= 57343;
|
|
942
|
+
}
|
|
943
|
+
|
|
831
944
|
// src/document/validate.ts
|
|
832
945
|
function validate(source) {
|
|
833
946
|
const diag = new Diagnostics();
|
|
@@ -894,8 +1007,8 @@ var OPERANDS = {
|
|
|
894
1007
|
gte: [isNumber, "a number"],
|
|
895
1008
|
lt: [isNumber, "a number"],
|
|
896
1009
|
lte: [isNumber, "a number"],
|
|
897
|
-
matches: [
|
|
898
|
-
notMatches: [
|
|
1010
|
+
matches: [isPortablePattern, "a regular expression in the portable subset"],
|
|
1011
|
+
notMatches: [isPortablePattern, "a regular expression in the portable subset"],
|
|
899
1012
|
startsWith: [isString, "a string"],
|
|
900
1013
|
glob: [isString, "a glob"],
|
|
901
1014
|
withinWorkspace: [isBoolean, "true or false"],
|
|
@@ -915,16 +1028,6 @@ function isString(v) {
|
|
|
915
1028
|
function isBoolean(v) {
|
|
916
1029
|
return typeof v === "boolean";
|
|
917
1030
|
}
|
|
918
|
-
function isRe2Pattern(v) {
|
|
919
|
-
if (typeof v !== "string") return false;
|
|
920
|
-
if (/\\[1-9]|\(\?[=!<]/.test(v)) return false;
|
|
921
|
-
try {
|
|
922
|
-
new RegExp(v);
|
|
923
|
-
return true;
|
|
924
|
-
} catch {
|
|
925
|
-
return false;
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
1031
|
function validateOverlays(ctx, overlays2, path) {
|
|
929
1032
|
for (const [key, overlay] of Object.entries(overlays2 ?? {})) {
|
|
930
1033
|
const opath = `${path}/${key}`;
|