@intentius/chant-lexicon-cedar 0.124.30 → 0.124.32

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 (101) hide show
  1. package/dist/agentcore/embed.js +250 -0
  2. package/dist/agentcore/enforcement.js +81 -0
  3. package/dist/agentcore/scan.js +93 -0
  4. package/dist/avp/ambient.js +100 -0
  5. package/dist/avp/client.js +318 -0
  6. package/dist/avp/describe-resources.js +144 -0
  7. package/dist/avp/embed.js +125 -0
  8. package/dist/avp/live-export.js +151 -0
  9. package/dist/avp/ownership.js +144 -0
  10. package/dist/avp/statement.js +45 -0
  11. package/dist/avp/store.js +105 -0
  12. package/dist/avp/testdata/mock-transport.js +100 -0
  13. package/dist/codegen/docs-cli.js +6 -0
  14. package/dist/codegen/docs.js +133 -0
  15. package/dist/codegen/emit.js +331 -0
  16. package/dist/codegen/generate-cli.js +18 -0
  17. package/dist/codegen/generate.js +122 -0
  18. package/dist/codegen/naming.js +90 -0
  19. package/dist/codegen/package.js +33 -0
  20. package/dist/commands.js +86 -0
  21. package/dist/composites/deny-by-default-set.js +51 -0
  22. package/dist/composites/index.js +9 -0
  23. package/dist/composites/owner-can-manage.js +48 -0
  24. package/dist/config.js +159 -0
  25. package/dist/coverage.js +112 -0
  26. package/dist/detect.js +61 -0
  27. package/dist/dogwood/cli.js +477 -0
  28. package/dist/dogwood/event-schema.js +219 -0
  29. package/dist/dogwood/index.js +32 -0
  30. package/dist/dogwood/macros.js +175 -0
  31. package/dist/dogwood/policy.js +58 -0
  32. package/dist/dogwood/replay-activity.js +313 -0
  33. package/dist/dogwood/replay-op.js +134 -0
  34. package/dist/dogwood/scan.js +234 -0
  35. package/dist/dogwood/serialize.js +199 -0
  36. package/dist/dogwood/temporal.js +354 -0
  37. package/dist/dogwood/trace.js +269 -0
  38. package/dist/dogwood/upstream.js +40 -0
  39. package/dist/dogwood/window.js +82 -0
  40. package/dist/gate-policy-pack.js +189 -0
  41. package/dist/gate-policy.js +168 -0
  42. package/dist/gate-schema.js +122 -0
  43. package/dist/generated/index.js +94 -0
  44. package/dist/generated/runtime.js +2 -0
  45. package/dist/import/adapter.js +54 -0
  46. package/dist/import/clause-text.js +166 -0
  47. package/dist/import/generator.js +178 -0
  48. package/dist/import/parser.js +273 -0
  49. package/dist/index.js +79 -0
  50. package/dist/init-templates.js +330 -0
  51. package/dist/integrity.json +2 -2
  52. package/dist/lint/audit-catalog.js +65 -0
  53. package/dist/lint/audit-lineage.js +23 -0
  54. package/dist/lint/post-synth/cedar-helpers.js +123 -0
  55. package/dist/lint/post-synth/cedc010.js +59 -0
  56. package/dist/lint/post-synth/cedc011.js +29 -0
  57. package/dist/lint/post-synth/cedc012.js +34 -0
  58. package/dist/lint/post-synth/cedc013.js +45 -0
  59. package/dist/lint/post-synth/cedc014.js +54 -0
  60. package/dist/lint/post-synth/cede010.js +51 -0
  61. package/dist/lint/post-synth/cede011.js +36 -0
  62. package/dist/lint/post-synth/ceds010.js +31 -0
  63. package/dist/lint/post-synth/ceds011.js +22 -0
  64. package/dist/lint/post-synth/ceds012.js +31 -0
  65. package/dist/lint/post-synth/dogwood-helpers.js +94 -0
  66. package/dist/lint/post-synth/dwdc010.js +38 -0
  67. package/dist/lint/post-synth/dwdc011.js +34 -0
  68. package/dist/lint/post-synth/dwdc012.js +24 -0
  69. package/dist/lint/post-synth/dwdc013.js +29 -0
  70. package/dist/lint/post-synth/dwde010.js +84 -0
  71. package/dist/lint/post-synth/dwde011.js +67 -0
  72. package/dist/lint/post-synth/dwds010.js +21 -0
  73. package/dist/lint/post-synth/index.js +36 -0
  74. package/dist/lint/post-synth/wasm-helpers.js +234 -0
  75. package/dist/lint/rules/index.js +9 -0
  76. package/dist/lint/rules/policy-shape.js +114 -0
  77. package/dist/lsp/completions.js +52 -0
  78. package/dist/lsp/hover.js +56 -0
  79. package/dist/lsp/registry.d.ts.map +1 -1
  80. package/dist/lsp/registry.js +51 -0
  81. package/dist/manifest.json +1 -1
  82. package/dist/mcp/index.js +82 -0
  83. package/dist/mcp/policy-coverage.js +134 -0
  84. package/dist/op/activities/index.js +16 -0
  85. package/dist/package-cli.js +18 -0
  86. package/dist/plugin.js +304 -0
  87. package/dist/policy-text.js +117 -0
  88. package/dist/schema-artifact.js +66 -0
  89. package/dist/serializer.js +203 -0
  90. package/dist/spec/fetch.js +96 -0
  91. package/dist/spec/parse.js +164 -0
  92. package/dist/spec/pin.js +170 -0
  93. package/dist/spec/wasm.js +194 -0
  94. package/dist/validate-cli.js +7 -0
  95. package/dist/validate.js +74 -0
  96. package/package.json +7 -7
  97. package/src/codegen/package.ts +2 -2
  98. package/src/coverage.ts +2 -2
  99. package/src/import/generator.ts +2 -2
  100. package/src/lsp/registry.ts +2 -1
  101. package/src/spec/fetch.ts +2 -2
@@ -0,0 +1,194 @@
1
+ /**
2
+ * The one place `@cedar-policy/cedar-wasm` is called from.
3
+ *
4
+ * Three findings from the 4.12.0 verification (#1648) are encoded here rather
5
+ * than left to each caller to remember:
6
+ *
7
+ * 1. **Only the `/nodejs` flavor.** The root ESM build imports the `.wasm` as
8
+ * an ES module, which Bun cannot start (`wasm.__wbindgen_start is not a
9
+ * function`) and Node only supports behind an experimental warning printed
10
+ * on every run. `/nodejs` loads the binary with `readFileSync` and works
11
+ * under node CJS, node ESM, vitest and bun alike.
12
+ *
13
+ * 2. **`schemaToJsonWithResolvedTypes` takes a string and means it.** A JS
14
+ * object traps the wasm with `memory access out of bounds` — not a failure
15
+ * answer, a memory fault. The `typeof === "string"` guard below is the
16
+ * difference between a readable error and a trap.
17
+ *
18
+ * 3. **The `Answer` union is not the whole error channel.** Malformed input
19
+ * throws a bare serde `Error` from inside the wasm instead of returning
20
+ * `{type:"failure"}`, and the `line 1 column N` in those messages refers to
21
+ * the internal call struct, not to anything the user wrote. Both channels
22
+ * are normalized into one result type here.
23
+ */
24
+ import { createRequire } from "module";
25
+ /**
26
+ * Loaded on first use, not at import.
27
+ *
28
+ * The wasm binary is 4.2 MB and costs ~13 MB RSS to instantiate. Importing
29
+ * this package is something a user's `chant.config.ts` does purely to bring
30
+ * the `cedar` key into `ChantConfig`, and every `chant build` in a project
31
+ * with a policy set loads the serializer — neither touches the validator. A
32
+ * top-level import would charge all of them for it.
33
+ */
34
+ let wasm;
35
+ function cedar() {
36
+ if (!wasm) {
37
+ // `require`, not `import()`: the `/nodejs` flavor is CommonJS, and this
38
+ // keeps the call sites synchronous, which is what every consumer here
39
+ // wants. See the flavor note above for why the root ESM build is not an
40
+ // option.
41
+ wasm = createRequire(import.meta.url)("@cedar-policy/cedar-wasm/nodejs");
42
+ }
43
+ return wasm;
44
+ }
45
+ /** The Cedar *language* version this build of the package implements. */
46
+ export function langVersion() {
47
+ return cedar().getCedarLangVersion();
48
+ }
49
+ /** The `@cedar-policy/cedar-wasm` package version. */
50
+ export function packageVersion() {
51
+ return cedar().getCedarVersion();
52
+ }
53
+ /**
54
+ * Resolve a human-readable `.cedarschema` into fully-qualified schema JSON.
55
+ *
56
+ * Returns a result rather than throwing so a bad project schema reads as a
57
+ * message about the project schema, not as a stack trace out of a wasm module.
58
+ */
59
+ export function resolveSchema(schemaText) {
60
+ if (typeof schemaText !== "string") {
61
+ // Guarded, not attempted: a non-string traps the instance rather than
62
+ // returning a failure answer (#1648 §5.4).
63
+ return {
64
+ ok: false,
65
+ error: `schemaToJsonWithResolvedTypes takes the human-readable schema as a string; got ${typeof schemaText}`,
66
+ };
67
+ }
68
+ let answer;
69
+ try {
70
+ answer = cedar().schemaToJsonWithResolvedTypes(schemaText);
71
+ }
72
+ catch (err) {
73
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
74
+ }
75
+ if (!answer || typeof answer !== "object") {
76
+ return { ok: false, error: "cedar-wasm returned no answer" };
77
+ }
78
+ const record = answer;
79
+ if (record.type !== "success") {
80
+ return { ok: false, error: formatWasmErrors(record.errors) };
81
+ }
82
+ if (!record.json || typeof record.json !== "object") {
83
+ return { ok: false, error: "cedar-wasm reported success with no schema JSON" };
84
+ }
85
+ return { ok: true, value: record.json };
86
+ }
87
+ /**
88
+ * Run one wasm call and collapse both of its error channels into a result.
89
+ *
90
+ * The `Answer` union is not the whole error channel — malformed input throws a
91
+ * bare serde `Error` from inside the module, and the `line 1 column N` those
92
+ * messages carry points at the internal call struct rather than at anything
93
+ * the user wrote (#1648 §5.3). Both land here as `{ ok: false }`.
94
+ */
95
+ function wasmCall(what, run, extract) {
96
+ let answer;
97
+ try {
98
+ answer = run();
99
+ }
100
+ catch (err) {
101
+ return { ok: false, error: `${what}: ${err instanceof Error ? err.message : String(err)}` };
102
+ }
103
+ if (!answer || typeof answer !== "object") {
104
+ return { ok: false, error: `${what}: cedar-wasm returned no answer` };
105
+ }
106
+ const record = answer;
107
+ if (record.type !== "success") {
108
+ return { ok: false, error: formatWasmErrors(record.errors) };
109
+ }
110
+ const value = extract(answer);
111
+ if (value === undefined) {
112
+ return { ok: false, error: `${what}: cedar-wasm reported success with no result` };
113
+ }
114
+ return { ok: true, value };
115
+ }
116
+ /**
117
+ * Split a `.cedar` document into its policies and its templates.
118
+ *
119
+ * The strings that come back are the **verbatim source** of each policy —
120
+ * annotations, line breaks and all — in source order, which is what lets the
121
+ * importer recover a condition body exactly as it was written rather than as
122
+ * the JSON leg would re-render it. Comments are dropped: they are not part of
123
+ * any grammar the module round-trips.
124
+ */
125
+ export function splitPolicySet(text) {
126
+ if (typeof text !== "string") {
127
+ return { ok: false, error: `policySetTextToParts takes policy text as a string; got ${typeof text}` };
128
+ }
129
+ return wasmCall("policySetTextToParts", () => cedar().policySetTextToParts(text), (answer) => {
130
+ const { policies, policy_templates: templates } = answer;
131
+ if (!Array.isArray(policies) || !Array.isArray(templates))
132
+ return undefined;
133
+ return { policies: policies, templates: templates };
134
+ });
135
+ }
136
+ /** Convert one *static* policy (text or JSON) into Cedar's JSON policy format. */
137
+ export function policyToJson(policy) {
138
+ return wasmCall("policyToJson", () => cedar().policyToJson(policy), (answer) => answer.json);
139
+ }
140
+ /**
141
+ * Convert one *template* (text or JSON) into Cedar's JSON policy format.
142
+ *
143
+ * A policy carrying `?principal`/`?resource` is a template, and `policyToJson`
144
+ * refuses it outright ("expected a static policy, got a template containing
145
+ * the slot ?resource") — the two entry points are not interchangeable.
146
+ */
147
+ export function templateToJson(template) {
148
+ return wasmCall("templateToJson", () => cedar().templateToJson(template), (answer) => answer.json);
149
+ }
150
+ /**
151
+ * Render one policy's JSON back to Cedar text.
152
+ *
153
+ * Only ever used to recover an *expression* body that has no source text to
154
+ * quote — an imported JSON policy set. The output is single-line and defensively
155
+ * parenthesized (`((context.mfa) == true)`), and `formatPolicies` does not undo
156
+ * that, so it is never the source of a human-facing `.cedar` artifact: those are
157
+ * laid out by the serializer.
158
+ */
159
+ export function policyToText(policy) {
160
+ return wasmCall("policyToText", () => cedar().policyToText(policy), (answer) => answer.text);
161
+ }
162
+ /**
163
+ * Does this value parse as a Cedar policy set?
164
+ *
165
+ * `checkParsePolicySet` throws — rather than answering `failure` — for a
166
+ * document carrying keys it does not know, which is precisely the shape a
167
+ * foreign lexicon's JSON has, so the throw is a match rejection here.
168
+ */
169
+ export function parsesAsPolicySet(value) {
170
+ try {
171
+ return cedar().checkParsePolicySet(value).type === "success";
172
+ }
173
+ catch {
174
+ return false;
175
+ }
176
+ }
177
+ /**
178
+ * Flatten a `DetailedError[]` into one line.
179
+ *
180
+ * `code`, `url` and `severity` are `null` on every error this package emits
181
+ * (#1648 §5.6), so only `message` and `help` carry anything.
182
+ */
183
+ export function formatWasmErrors(errors) {
184
+ if (!Array.isArray(errors) || errors.length === 0)
185
+ return "cedar-wasm reported a failure with no detail";
186
+ return errors
187
+ .map((e) => {
188
+ if (typeof e === "string")
189
+ return e;
190
+ const detail = e;
191
+ return detail.help ? `${detail.message} (${detail.help})` : String(detail.message ?? e);
192
+ })
193
+ .join("; ");
194
+ }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env tsx
2
+ import { validate } from "./validate.js";
3
+ import { printValidationResult } from "@intentius/chant/codegen/validate";
4
+ // `validate` returns a result; printing it is what turns a failed check into a
5
+ // non-zero exit. The scaffold called it and discarded the answer, so a missing
6
+ // registry exited 0.
7
+ printValidationResult(await validate());
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Validate the generated lexicon-cedar artifacts.
3
+ *
4
+ * The required-name list below is the surface this package publishes when it
5
+ * generates from its own bundled default schema, which is what `prepack`,
6
+ * `just check-lexicons` and CI all do. It is not a claim about a user's
7
+ * project schema — theirs produces their own names, and `coverage()` is the
8
+ * check that answers whether their schema is fully reachable.
9
+ *
10
+ * Listing them explicitly is the point: `src/generated/` is gitignored, so
11
+ * without this list nothing in the repository records what the default schema
12
+ * is supposed to produce, and a codegen change that quietly dropped every
13
+ * action would still pass "the registry parses".
14
+ */
15
+ import { dirname } from "path";
16
+ import { fileURLToPath } from "url";
17
+ import { validateLexiconArtifacts } from "@intentius/chant/codegen/validate";
18
+ /**
19
+ * Names the default schema must produce: the policy authoring class, one class
20
+ * per entity type, one per action, and the record type beside each.
21
+ */
22
+ const REQUIRED_NAMES = [
23
+ // The authoring surface, present regardless of schema.
24
+ "Policy",
25
+ // Entity types.
26
+ "Application",
27
+ "Document",
28
+ "Folder",
29
+ "Group",
30
+ "ServiceAccount",
31
+ "Team",
32
+ "User",
33
+ // Entity attribute records.
34
+ "ApplicationAttributes",
35
+ "DocumentAttributes",
36
+ "FolderAttributes",
37
+ "GroupAttributes",
38
+ "ServiceAccountAttributes",
39
+ "TeamAttributes",
40
+ "UserAttributes",
41
+ // Actions.
42
+ "AdminAction",
43
+ "ApproveAction",
44
+ "CommentAction",
45
+ "CreateAction",
46
+ "DeleteAction",
47
+ "ListAction",
48
+ "ReadAction",
49
+ "ShareAction",
50
+ "WriteAction",
51
+ // Action context records.
52
+ "AdminContext",
53
+ "ApproveContext",
54
+ "CommentContext",
55
+ "CreateContext",
56
+ "DeleteContext",
57
+ "ListContext",
58
+ "ReadContext",
59
+ "ShareContext",
60
+ "WriteContext",
61
+ ];
62
+ /** Exposed so tests can assert the list stays above the tier-3 bar. */
63
+ export const requiredNames = REQUIRED_NAMES;
64
+ /**
65
+ * Validate the generated lexicon-cedar artifacts.
66
+ */
67
+ export async function validate(opts) {
68
+ const basePath = opts?.basePath ?? dirname(dirname(fileURLToPath(import.meta.url)));
69
+ return validateLexiconArtifacts({
70
+ lexiconJsonFilename: "lexicon-cedar.json",
71
+ requiredNames: REQUIRED_NAMES,
72
+ basePath,
73
+ });
74
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-cedar",
3
- "version": "0.124.30",
3
+ "version": "0.124.32",
4
4
  "description": "Cedar lexicon for chant — typed authoring for Cedar authorization policies",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -33,22 +33,22 @@
33
33
  ".": {
34
34
  "development": "./src/index.ts",
35
35
  "types": "./dist/index.d.ts",
36
- "default": "./src/index.ts"
36
+ "default": "./dist/index.js"
37
37
  },
38
38
  "./*": {
39
39
  "development": "./src/*.ts",
40
40
  "types": "./dist/*.d.ts",
41
- "default": "./src/*.ts"
41
+ "default": "./dist/*.js"
42
42
  },
43
43
  "./lint/post-synth": {
44
44
  "development": "./src/lint/post-synth/index.ts",
45
45
  "types": "./dist/lint/post-synth/index.d.ts",
46
- "default": "./src/lint/post-synth/index.ts"
46
+ "default": "./dist/lint/post-synth/index.js"
47
47
  },
48
48
  "./op/activities": {
49
49
  "development": "./src/op/activities/index.ts",
50
50
  "types": "./dist/op/activities/index.d.ts",
51
- "default": "./src/op/activities/index.ts"
51
+ "default": "./dist/op/activities/index.js"
52
52
  },
53
53
  "./manifest": "./dist/manifest.json",
54
54
  "./meta": "./dist/meta.json",
@@ -62,7 +62,7 @@
62
62
  "docs:dev": "cd docs && npm run dev",
63
63
  "docs:build": "cd docs && npm install && npm run build",
64
64
  "prepack": "npm run generate && npm run bundle && npm run validate && npm run build",
65
- "build": "../../scripts/tsc7.sh -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
65
+ "build": "../../scripts/tsc7.sh -p tsconfig.build.json --sourceMap false && tsc-alias -p tsconfig.build.json"
66
66
  },
67
67
  "dependencies": {
68
68
  "@cedar-policy/cedar-wasm": "4.12.0"
@@ -74,6 +74,6 @@
74
74
  },
75
75
  "peerDependencies": {
76
76
  "zod": "^4.3.6",
77
- "@intentius/chant": "^0.124.30"
77
+ "@intentius/chant": "^0.124.32"
78
78
  }
79
79
  }
@@ -5,7 +5,7 @@
5
5
  import { cedarPlugin } from "../plugin";
6
6
  import { readFileSync } from "fs";
7
7
  import { dirname, join } from "path";
8
- import { fileURLToPath } from "url";
8
+ import { moduleSourceDir } from "@intentius/chant/module-source";
9
9
  import {
10
10
  collectSkills,
11
11
  packagePipeline,
@@ -16,7 +16,7 @@ import { generate } from "./generate";
16
16
 
17
17
  export type { PackageOptions, PackageResult };
18
18
 
19
- const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
19
+ const pkgDir = dirname(moduleSourceDir(import.meta.url));
20
20
 
21
21
  /**
22
22
  * Package the Cedar lexicon into a distributable BundleSpec.
package/src/coverage.ts CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  import { existsSync, readFileSync } from "fs";
17
17
  import { dirname, join } from "path";
18
- import { fileURLToPath } from "url";
18
+ import { moduleSourceDir } from "@intentius/chant/module-source";
19
19
  import { LEXICON_JSON_FILENAME } from "./codegen/generate";
20
20
  import { attributesTypeName, contextTypeName } from "./codegen/emit";
21
21
  import { readSchemaSource, type ResolveSchemaOptions } from "./spec/fetch";
@@ -60,7 +60,7 @@ export interface CedarCoverageOptions extends ResolveSchemaOptions {
60
60
  }
61
61
 
62
62
  function defaultGeneratedDir(): string {
63
- return join(dirname(fileURLToPath(import.meta.url)), "generated");
63
+ return join(moduleSourceDir(import.meta.url), "generated");
64
64
  }
65
65
 
66
66
  function pct(covered: number, total: number): number {
@@ -15,7 +15,7 @@
15
15
 
16
16
  import { existsSync, readFileSync } from "fs";
17
17
  import { dirname, join } from "path";
18
- import { fileURLToPath } from "url";
18
+ import { moduleSourceDir } from "@intentius/chant/module-source";
19
19
  import type { CedarPolicyIR } from "./parser";
20
20
 
21
21
  /** The package this generated source imports from. */
@@ -199,7 +199,7 @@ interface RegistryEntry {
199
199
  * `Policy` class accepts and the compiler still checks.
200
200
  */
201
201
  export function loadActionConstants(packageDir?: string): Record<string, string> {
202
- const base = packageDir ?? dirname(dirname(fileURLToPath(import.meta.url)));
202
+ const base = packageDir ?? dirname(moduleSourceDir(import.meta.url));
203
203
  const path = join(base, "generated", REGISTRY_FILE);
204
204
  if (!existsSync(path)) return {};
205
205
 
@@ -16,10 +16,11 @@
16
16
  */
17
17
 
18
18
  import { createRequire } from "module";
19
+ import { moduleSourceUrl } from "@intentius/chant/module-source";
19
20
  import { LexiconIndex, type LexiconEntry } from "@intentius/chant/lsp/lexicon-providers";
20
21
  import { LEXICON_JSON_FILENAME } from "../codegen/generate";
21
22
 
22
- const require = createRequire(import.meta.url);
23
+ const require = createRequire(moduleSourceUrl(import.meta.url));
23
24
 
24
25
  /** One `lexicon-cedar.json` entry, as {@link generateRegistry} writes it. */
25
26
  export interface CedarRegistryEntry {
package/src/spec/fetch.ts CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  import { existsSync, readFileSync } from "fs";
25
25
  import { dirname, isAbsolute, join, resolve } from "path";
26
- import { fileURLToPath } from "url";
26
+ import { moduleSourceDir } from "@intentius/chant/module-source";
27
27
  import { CEDAR_DEFAULT_SCHEMA_PATH } from "../config";
28
28
 
29
29
  /** Filename the bundled fallback schema ships under. */
@@ -44,7 +44,7 @@ let specDir: string | undefined;
44
44
  function resolveSpecDir(): string | undefined {
45
45
  if (specDir !== undefined) return specDir;
46
46
  try {
47
- specDir = dirname(fileURLToPath(import.meta.url));
47
+ specDir = moduleSourceDir(import.meta.url);
48
48
  } catch {
49
49
  return undefined;
50
50
  }