@goodbones/campaigns 0.1.0

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 (102) hide show
  1. package/LICENSE +21 -0
  2. package/build/dts/core/campaign-state.d.ts +38 -0
  3. package/build/dts/core/campaign-state.d.ts.map +1 -0
  4. package/build/dts/core/campaigns.d.ts +196 -0
  5. package/build/dts/core/campaigns.d.ts.map +1 -0
  6. package/build/dts/core/ledger.d.ts +173 -0
  7. package/build/dts/core/ledger.d.ts.map +1 -0
  8. package/build/dts/core/phases.d.ts +26 -0
  9. package/build/dts/core/phases.d.ts.map +1 -0
  10. package/build/dts/core/sectors.d.ts +52 -0
  11. package/build/dts/core/sectors.d.ts.map +1 -0
  12. package/build/dts/domain/config.d.ts +985 -0
  13. package/build/dts/domain/config.d.ts.map +1 -0
  14. package/build/dts/domain/report.d.ts +16 -0
  15. package/build/dts/domain/report.d.ts.map +1 -0
  16. package/build/dts/host/campaigns.d.ts +195 -0
  17. package/build/dts/host/campaigns.d.ts.map +1 -0
  18. package/build/dts/host/diff.d.ts +31 -0
  19. package/build/dts/host/diff.d.ts.map +1 -0
  20. package/build/dts/index.d.ts +17 -0
  21. package/build/dts/index.d.ts.map +1 -0
  22. package/build/dts/infrastructure/campaign-functions.d.ts +7 -0
  23. package/build/dts/infrastructure/campaign-functions.d.ts.map +1 -0
  24. package/build/dts/infrastructure/report-source-fake.d.ts +4 -0
  25. package/build/dts/infrastructure/report-source-fake.d.ts.map +1 -0
  26. package/build/dts/infrastructure/report-source-live.d.ts +3 -0
  27. package/build/dts/infrastructure/report-source-live.d.ts.map +1 -0
  28. package/build/dts/load/decode.d.ts +7 -0
  29. package/build/dts/load/decode.d.ts.map +1 -0
  30. package/build/dts/load/extension.d.ts +25 -0
  31. package/build/dts/load/extension.d.ts.map +1 -0
  32. package/build/dts/manifest/lower.d.ts +14 -0
  33. package/build/dts/manifest/lower.d.ts.map +1 -0
  34. package/build/dts/manifest/spec.d.ts +515 -0
  35. package/build/dts/manifest/spec.d.ts.map +1 -0
  36. package/build/dts/ports/campaign-predicate.d.ts +23 -0
  37. package/build/dts/ports/campaign-predicate.d.ts.map +1 -0
  38. package/build/dts/ports/report-source.d.ts +14 -0
  39. package/build/dts/ports/report-source.d.ts.map +1 -0
  40. package/build/dts/testing.d.ts +2 -0
  41. package/build/dts/testing.d.ts.map +1 -0
  42. package/build/esm/core/campaign-state.js +140 -0
  43. package/build/esm/core/campaign-state.js.map +1 -0
  44. package/build/esm/core/campaigns.js +954 -0
  45. package/build/esm/core/campaigns.js.map +1 -0
  46. package/build/esm/core/ledger.js +519 -0
  47. package/build/esm/core/ledger.js.map +1 -0
  48. package/build/esm/core/phases.js +87 -0
  49. package/build/esm/core/phases.js.map +1 -0
  50. package/build/esm/core/sectors.js +313 -0
  51. package/build/esm/core/sectors.js.map +1 -0
  52. package/build/esm/domain/config.js +245 -0
  53. package/build/esm/domain/config.js.map +1 -0
  54. package/build/esm/domain/report.js +168 -0
  55. package/build/esm/domain/report.js.map +1 -0
  56. package/build/esm/host/campaigns.js +1159 -0
  57. package/build/esm/host/campaigns.js.map +1 -0
  58. package/build/esm/host/diff.js +156 -0
  59. package/build/esm/host/diff.js.map +1 -0
  60. package/build/esm/index.js +27 -0
  61. package/build/esm/index.js.map +1 -0
  62. package/build/esm/infrastructure/campaign-functions.js +67 -0
  63. package/build/esm/infrastructure/campaign-functions.js.map +1 -0
  64. package/build/esm/infrastructure/report-source-fake.js +6 -0
  65. package/build/esm/infrastructure/report-source-fake.js.map +1 -0
  66. package/build/esm/infrastructure/report-source-live.js +165 -0
  67. package/build/esm/infrastructure/report-source-live.js.map +1 -0
  68. package/build/esm/load/decode.js +60 -0
  69. package/build/esm/load/decode.js.map +1 -0
  70. package/build/esm/load/extension.js +326 -0
  71. package/build/esm/load/extension.js.map +1 -0
  72. package/build/esm/manifest/lower.js +488 -0
  73. package/build/esm/manifest/lower.js.map +1 -0
  74. package/build/esm/manifest/spec.js +296 -0
  75. package/build/esm/manifest/spec.js.map +1 -0
  76. package/build/esm/ports/campaign-predicate.js +2 -0
  77. package/build/esm/ports/campaign-predicate.js.map +1 -0
  78. package/build/esm/ports/report-source.js +7 -0
  79. package/build/esm/ports/report-source.js.map +1 -0
  80. package/build/esm/testing.js +5 -0
  81. package/build/esm/testing.js.map +1 -0
  82. package/package.json +65 -0
  83. package/src/core/campaign-state.ts +227 -0
  84. package/src/core/campaigns.ts +1319 -0
  85. package/src/core/ledger.ts +675 -0
  86. package/src/core/phases.ts +138 -0
  87. package/src/core/sectors.ts +399 -0
  88. package/src/domain/config.ts +314 -0
  89. package/src/domain/report.ts +203 -0
  90. package/src/host/campaigns.ts +1664 -0
  91. package/src/host/diff.ts +203 -0
  92. package/src/index.ts +256 -0
  93. package/src/infrastructure/campaign-functions.ts +99 -0
  94. package/src/infrastructure/report-source-fake.ts +10 -0
  95. package/src/infrastructure/report-source-live.ts +193 -0
  96. package/src/load/decode.ts +81 -0
  97. package/src/load/extension.ts +466 -0
  98. package/src/manifest/lower.ts +615 -0
  99. package/src/manifest/spec.ts +364 -0
  100. package/src/ports/campaign-predicate.ts +29 -0
  101. package/src/ports/report-source.ts +35 -0
  102. package/src/testing.ts +4 -0
@@ -0,0 +1,60 @@
1
+ import * as Result from "effect/Result";
2
+ import * as Schema from "effect/Schema";
3
+ import * as SchemaIssue from "effect/SchemaIssue";
4
+ import { CampaignsManifest } from "../manifest/spec.js";
5
+ // Decoding this family's slice of the manifest. The core has already expanded
6
+ // `defs`/`use` and `include` and split these keys off; what arrives here is
7
+ // `{ campaigns?, ledger? }` as written.
8
+ //
9
+ // Every issue, not the first, and each rendered through the `describe` the
10
+ // core handed over — so a campaign's decode error carries the same line,
11
+ // path and `use` trail a tree node's does.
12
+ export { CampaignsManifest } from "../manifest/spec.js";
13
+ export { DEFAULT_LEDGER_DIR } from "../manifest/spec.js";
14
+ const decode = Schema.decodeUnknownResult(CampaignsManifest, {
15
+ errors: "all",
16
+ onExcessProperty: "error",
17
+ });
18
+ const flatten = SchemaIssue.makeFormatterStandardSchemaV1();
19
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20
+ const isList = (value) => Array.isArray(value);
21
+ // The standard-schema formatter flattens the issue tree to `{ path, message }`
22
+ // pairs; a path segment may arrive wrapped as `{ key }`.
23
+ const pathOf = (issue) => (issue.path ?? []).map((segment) => (typeof segment === "object" ? segment.key : segment));
24
+ // The family's first shape — a list of campaigns each carrying one `detect` —
25
+ // is refused by name, since the decoder's own message for it would be a wall
26
+ // of union issues. A campaign now owns its `objectives`, each of which is
27
+ // what a campaign used to be.
28
+ const legacyCampaignsIssue = (campaigns) => {
29
+ if (campaigns === undefined)
30
+ return null;
31
+ if (isList(campaigns)) {
32
+ return ("`campaigns` is a list. A campaign is now a map keyed by its id, and what a campaign used " +
33
+ "to be — a detector with a ledger — is one of its `objectives`: write " +
34
+ "`campaigns: { <id>: { objectives: { <objective>: { holdout, match, probes } } } }`, " +
35
+ "with `unit` renamed `holdout` and `detect` renamed `match`.");
36
+ }
37
+ if (!isRecord(campaigns))
38
+ return null;
39
+ for (const [id, campaign] of Object.entries(campaigns)) {
40
+ if (!isRecord(campaign))
41
+ continue;
42
+ if ("detect" in campaign && !("objectives" in campaign)) {
43
+ return (`campaign "${id}" carries a \`detect\` and no \`objectives\`. A campaign owns its ` +
44
+ `objectives, each a detector with a ledger: move \`detect\` (now \`match\`), \`unit\` ` +
45
+ `(now \`holdout\`) and \`probes\` under \`objectives: { <objective>: … }\`.`);
46
+ }
47
+ }
48
+ return null;
49
+ };
50
+ export const decodeCampaigns = (slice, describe) => {
51
+ const legacy = legacyCampaignsIssue(slice.campaigns);
52
+ if (legacy !== null)
53
+ return Result.fail([describe(["campaigns"], legacy)]);
54
+ const decoded = decode(slice);
55
+ if (Result.isFailure(decoded)) {
56
+ return Result.fail(flatten(decoded.failure.issue).issues.map((issue) => describe(pathOf(issue), issue.message)));
57
+ }
58
+ return Result.succeed(decoded.success);
59
+ };
60
+ //# sourceMappingURL=decode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["../../../src/load/decode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,8EAA8E;AAC9E,4EAA4E;AAC5E,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,yEAAyE;AACzE,2CAA2C;AAE3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,EAAE;IAC3D,MAAM,EAAE,KAAK;IACb,gBAAgB,EAAE,OAAO;CAC1B,CAAC,CAAC;AACH,MAAM,OAAO,GAAG,WAAW,CAAC,6BAA6B,EAAE,CAAC;AAE5D,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CACpE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEvE,MAAM,MAAM,GAAG,CAAC,KAAc,EAAmC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEzF,+EAA+E;AAC/E,yDAAyD;AACzD,MAAM,MAAM,GAAG,CAAC,KAEf,EAAgB,EAAE,CACjB,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAE7F,8EAA8E;AAC9E,6EAA6E;AAC7E,0EAA0E;AAC1E,8BAA8B;AAC9B,MAAM,oBAAoB,GAAG,CAAC,SAAkB,EAAiB,EAAE;IACjE,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACtB,OAAO,CACL,2FAA2F;YAC3F,uEAAuE;YACvE,sFAAsF;YACtF,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,KAAK,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACvD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,SAAS;QAClC,IAAI,QAAQ,IAAI,QAAQ,IAAI,CAAC,CAAC,YAAY,IAAI,QAAQ,CAAC,EAAE,CAAC;YACxD,OAAO,CACL,aAAa,EAAE,oEAAoE;gBACnF,uFAAuF;gBACvF,4EAA4E,CAC7E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,KAAwC,EACxC,QAAwD,EACC,EAAE;IAC3D,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAE3E,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,IAAI,CAChB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAClD,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CACvC,CACF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC,CAAC"}
@@ -0,0 +1,326 @@
1
+ import { compileExportRules, compileImportRules, compileMemberRules, compileStructure, compileSurfaceRules, ConfigInvalid, exportRulesFailingTheirProbe, memberRulesFailingTheirProbe, rulesFailingTheirProbe, structureRulesFailingTheirProbe, surfaceRulesFailingTheirProbe, } from "@goodbones/core";
2
+ import * as Result from "effect/Result";
3
+ import { campaignsFailingTheirProbe, compileCampaignRules, detectorOf, leafTermsOf, } from "../core/campaigns.js";
4
+ import { decodeLedger, decodePlanRecord, decodeSectorRecord, isLegacyLedger, ledgerPathOf, legacyLedgerPathOf, planPathOf, } from "../core/ledger.js";
5
+ import { END_STATE_ROOT, lowerCampaigns, lowerEndState } from "../manifest/lower.js";
6
+ import { NO_REPORTS } from "../ports/report-source.js";
7
+ import { decodeCampaigns, DEFAULT_LEDGER_DIR } from "./decode.js";
8
+ // The campaigns family as a `PolicyExtension`: everything `loadPolicy` used
9
+ // to do for this family, moved to the package that owns it.
10
+ //
11
+ // It claims two manifest keys, decodes them with its own codec, lowers them
12
+ // with the core's glob primitives, compiles and probes the rules, refuses the
13
+ // four things a campaign can name that its host cannot answer — a `fn` the
14
+ // host did not import, a `report` with no source, a `syntax` term in a scope
15
+ // whose language has no matcher, an `endState` that lowers to nothing — and
16
+ // reads the ledgers off the file system port. The core carries the result and
17
+ // never looks inside it; `campaignsOf(policy)` is how a host reads it back.
18
+ export const CAMPAIGNS_EXTENSION_ID = "campaigns";
19
+ // Keyed `<campaign>/<objective>`, and `<campaign>/<sector>` for a record.
20
+ export const ledgerKeyOf = (campaign, objective) => `${campaign}/${objective}`;
21
+ // A campaign-free policy, for a host that loaded the extension against a
22
+ // manifest holding no `campaigns` key at all.
23
+ const NOTHING = {
24
+ campaignRules: [],
25
+ ledgers: new Map(),
26
+ legacyLedgers: new Map(),
27
+ sectorRecords: new Map(),
28
+ plans: new Map(),
29
+ ledgerDir: DEFAULT_LEDGER_DIR,
30
+ functions: new Map(),
31
+ reports: NO_REPORTS,
32
+ };
33
+ // What a host reads back off the policy. A policy loaded without this
34
+ // extension answers the empty family rather than throwing: `architecture
35
+ // check` on a manifest with no campaigns is not an error.
36
+ export const campaignsOf = (policy) => {
37
+ const found = policy.extensions.get(CAMPAIGNS_EXTENSION_ID);
38
+ return found === undefined ? NOTHING : found;
39
+ };
40
+ const referencedFunctions = (detect) => {
41
+ switch (detect.kind) {
42
+ case "all":
43
+ case "any":
44
+ return detect.terms.flatMap(referencedFunctions);
45
+ case "not":
46
+ return referencedFunctions(detect.term);
47
+ case "fn":
48
+ return [detect.name];
49
+ default:
50
+ return [];
51
+ }
52
+ };
53
+ // Every detector a campaign holds: its objectives' (a `has` term's included)
54
+ // and its perimeter's.
55
+ const detectorsOf = (rule) => [
56
+ ...rule.objectives.flatMap((objective) => {
57
+ const detect = detectorOf(objective);
58
+ return detect === null ? [] : [detect];
59
+ }),
60
+ ...(rule.perimeter?.kind === "match" ? [rule.perimeter.detect] : []),
61
+ ];
62
+ const readJson = (configPath, fileSystem, at) => {
63
+ const text = fileSystem.readText(at);
64
+ if (text === null)
65
+ return Result.succeed(null);
66
+ try {
67
+ return Result.succeed(JSON.parse(text));
68
+ }
69
+ catch (cause) {
70
+ return Result.fail(new ConfigInvalid({ configPath, detail: `the ledger ${at} is not JSON: ${String(cause)}` }));
71
+ }
72
+ };
73
+ // The ledgers, read through the port. An absent file is an objective with no
74
+ // ledger yet; a malformed one is refused, since reading it as empty would
75
+ // report every hit as unrecorded growth. A file in the family's first layout
76
+ // — one per campaign, `<dir>/<campaign>.json` — is read as the ledger of the
77
+ // campaign's one objective, under the implicit sector, and remembered so
78
+ // `clear` can rewrite it where it now belongs.
79
+ const readLedgers = (configPath, fileSystem, ledgerDir, campaigns) => {
80
+ const ledgers = new Map();
81
+ const legacy = new Map();
82
+ const sectorRecords = new Map();
83
+ const plans = new Map();
84
+ for (const campaign of campaigns) {
85
+ for (const objective of campaign.objectives) {
86
+ const at = ledgerPathOf(ledgerDir, campaign.id, objective.id);
87
+ let raw = readJson(configPath, fileSystem, at);
88
+ if (Result.isFailure(raw))
89
+ return Result.fail(raw.failure);
90
+ let from = at;
91
+ if (raw.success === null && campaign.objectives.length === 1) {
92
+ from = legacyLedgerPathOf(ledgerDir, campaign.id);
93
+ raw = readJson(configPath, fileSystem, from);
94
+ if (Result.isFailure(raw))
95
+ return Result.fail(raw.failure);
96
+ if (raw.success !== null && !isLegacyLedger(raw.success)) {
97
+ return Result.fail(new ConfigInvalid({
98
+ configPath,
99
+ detail: `the ledger ${from} is not in the family's first layout, and an objective's ` +
100
+ `ledger is ${at}. Move it.`,
101
+ }));
102
+ }
103
+ if (raw.success !== null)
104
+ legacy.set(campaign.id, from);
105
+ }
106
+ if (raw.success === null)
107
+ continue;
108
+ const decoded = decodeLedger(raw.success);
109
+ if (Result.isFailure(decoded)) {
110
+ return Result.fail(new ConfigInvalid({
111
+ configPath,
112
+ detail: `the ledger ${from} does not decode:\n${decoded.failure}`,
113
+ }));
114
+ }
115
+ const ledger = decoded.success;
116
+ const expected = from === at ? objective.id : campaign.id;
117
+ if (ledger.campaign !== campaign.id || ledger.objective !== expected) {
118
+ return Result.fail(new ConfigInvalid({
119
+ configPath,
120
+ detail: `the ledger ${from} says it belongs to "${ledger.campaign}/${ledger.objective}", ` +
121
+ `not "${campaign.id}/${objective.id}".`,
122
+ }));
123
+ }
124
+ ledgers.set(ledgerKeyOf(campaign.id, objective.id), {
125
+ ...ledger,
126
+ objective: objective.id,
127
+ });
128
+ }
129
+ const sectorsDir = `${ledgerDir}/${campaign.id}/sectors`;
130
+ for (const name of fileSystem.list(sectorsDir)) {
131
+ if (!name.endsWith(".json"))
132
+ continue;
133
+ const at = `${sectorsDir}/${name}`;
134
+ const raw = readJson(configPath, fileSystem, at);
135
+ if (Result.isFailure(raw))
136
+ return Result.fail(raw.failure);
137
+ if (raw.success === null)
138
+ continue;
139
+ const decoded = decodeSectorRecord(raw.success);
140
+ if (Result.isFailure(decoded)) {
141
+ return Result.fail(new ConfigInvalid({
142
+ configPath,
143
+ detail: `the sector record ${at} does not decode:\n${decoded.failure}`,
144
+ }));
145
+ }
146
+ if (decoded.success.campaign !== campaign.id) {
147
+ return Result.fail(new ConfigInvalid({
148
+ configPath,
149
+ detail: `the sector record ${at} says it belongs to "${decoded.success.campaign}", not "${campaign.id}".`,
150
+ }));
151
+ }
152
+ sectorRecords.set(ledgerKeyOf(campaign.id, decoded.success.sector), decoded.success);
153
+ }
154
+ const planAt = planPathOf(ledgerDir, campaign.id);
155
+ const rawPlan = readJson(configPath, fileSystem, planAt);
156
+ if (Result.isFailure(rawPlan))
157
+ return Result.fail(rawPlan.failure);
158
+ if (rawPlan.success !== null) {
159
+ const decoded = decodePlanRecord(rawPlan.success);
160
+ if (Result.isFailure(decoded)) {
161
+ return Result.fail(new ConfigInvalid({
162
+ configPath,
163
+ detail: `the plan record ${planAt} does not decode:\n${decoded.failure}`,
164
+ }));
165
+ }
166
+ plans.set(campaign.id, decoded.success);
167
+ }
168
+ }
169
+ return Result.succeed({ ledgers, legacy, sectorRecords, plans });
170
+ };
171
+ const load = (options, context) => {
172
+ const { config, configPath, extractor, fileSystem, languages, routeFor, spec } = context;
173
+ // Lowering refuses a shape the schema cannot — a phase naming an objective
174
+ // that is not there, an `endState` over a multi-root perimeter — and it
175
+ // refuses by throwing, as the core's own lowering does. That is the very
176
+ // thing this repository's `lowering-reports-not-throws` campaign is paying
177
+ // down; it is not this extension's to change on the way past.
178
+ const lowered = lowerCampaigns(spec, config, languages);
179
+ const campaignRules = compileCampaignRules(lowered);
180
+ if (Result.isFailure(campaignRules))
181
+ return Result.fail(campaignRules.failure);
182
+ // A `fn` term names a function the host was to import. One it did not is a
183
+ // term that would answer false for every file, and is refused.
184
+ const functions = options.functions ?? new Map();
185
+ const missing = campaignRules.success.flatMap((rule) => detectorsOf(rule).flatMap((detect) => referencedFunctions(detect).filter((name) => !functions.has(name))));
186
+ if (missing.length > 0) {
187
+ return Result.fail(new ConfigInvalid({
188
+ configPath,
189
+ detail: `these campaigns name a predicate function the host did not load: ` +
190
+ `${[...new Set(missing)].join(", ")}. A \`fn\` term is \`module#export\`, resolved ` +
191
+ `relative to the manifest, and the export must be a function.`,
192
+ }));
193
+ }
194
+ // A `report` term is answered by the host's source. Without one every such
195
+ // campaign would report nothing and look complete.
196
+ const reporting = campaignRules.success.filter((rule) => detectorsOf(rule).some((detect) => leafTermsOf(detect).includes("report")));
197
+ if (options.reports === undefined && reporting.length > 0) {
198
+ return Result.fail(new ConfigInvalid({
199
+ configPath,
200
+ detail: `these campaigns hold a \`report\` term and the host provided no report source: ` +
201
+ `${reporting.map((rule) => rule.name).join(", ")}.`,
202
+ }));
203
+ }
204
+ // A `syntax` term needs a matcher for the language of every file in its
205
+ // scope. The probes are the files the campaign is proven on; a probe whose
206
+ // language has none would pass no probe and mean nothing.
207
+ const syntaxless = campaignRules.success.flatMap((rule) => {
208
+ const proven = [
209
+ ...rule.objectives.map((objective) => ({
210
+ name: objective.name,
211
+ detect: detectorOf(objective),
212
+ probes: objective.probes,
213
+ })),
214
+ ...(rule.perimeter?.kind === "match"
215
+ ? [
216
+ {
217
+ name: `${rule.name}/perimeter`,
218
+ detect: rule.perimeter.detect,
219
+ probes: rule.perimeter.probes,
220
+ },
221
+ ]
222
+ : []),
223
+ ];
224
+ return proven.flatMap(({ detect, name, probes }) => {
225
+ if (detect === null || !leafTermsOf(detect).includes("syntax"))
226
+ return [];
227
+ return [...probes.fires, ...probes.ignores].flatMap((probe) => {
228
+ const route = routeFor(probe.path);
229
+ return route === undefined || route.language.syntax !== undefined
230
+ ? []
231
+ : [`${name} (${probe.path}: ${route.language.id} carries no syntax matcher)`];
232
+ });
233
+ });
234
+ });
235
+ if (syntaxless.length > 0) {
236
+ return Result.fail(new ConfigInvalid({
237
+ configPath,
238
+ detail: `these campaigns hold a \`syntax\` term in a scope whose language has no syntax ` +
239
+ `matcher: ${[...new Set(syntaxless)].join(", ")}. Compose the language pack with ` +
240
+ `one (\`@goodbones/ast-grep\` for TypeScript), or write the detector without it.`,
241
+ }));
242
+ }
243
+ // An `endState` is compiled and probed once, at an abstract root, before any
244
+ // sector exists to lower it for: a sector-relative tree whose rules cannot
245
+ // fire is refused like any other.
246
+ const endStateFailures = [];
247
+ for (const rule of campaignRules.success) {
248
+ for (const phase of rule.phases) {
249
+ if (phase.endState === undefined)
250
+ continue;
251
+ let loweredEnd;
252
+ try {
253
+ loweredEnd = lowerEndState(phase.endState, END_STATE_ROOT, [], config.resolve, languages);
254
+ }
255
+ catch (cause) {
256
+ return Result.fail(new ConfigInvalid({
257
+ configPath,
258
+ detail: `campaign "${rule.id}" phase "${phase.id}": its endState does not lower: ${String(cause)}`,
259
+ }));
260
+ }
261
+ const endImports = compileImportRules(loweredEnd.imports);
262
+ if (Result.isFailure(endImports))
263
+ return Result.fail(endImports.failure);
264
+ const endExports = compileExportRules(loweredEnd.exports);
265
+ if (Result.isFailure(endExports))
266
+ return Result.fail(endExports.failure);
267
+ const endMembers = compileMemberRules(loweredEnd.members);
268
+ if (Result.isFailure(endMembers))
269
+ return Result.fail(endMembers.failure);
270
+ const endSurface = compileSurfaceRules(loweredEnd.surface);
271
+ if (Result.isFailure(endSurface))
272
+ return Result.fail(endSurface.failure);
273
+ const endStructure = compileStructure(loweredEnd.structure);
274
+ if (Result.isFailure(endStructure))
275
+ return Result.fail(endStructure.failure);
276
+ const label = (name) => `${rule.name}/${phase.id}/endState ${name}`;
277
+ for (const name of [
278
+ ...rulesFailingTheirProbe(endImports.success).map((one) => one.name),
279
+ ...exportRulesFailingTheirProbe(endExports.success, extractor).map((one) => one.name),
280
+ ...memberRulesFailingTheirProbe(endMembers.success, extractor).map((one) => one.name),
281
+ ...surfaceRulesFailingTheirProbe(endSurface.success, extractor).map((one) => one.name),
282
+ ...structureRulesFailingTheirProbe(endStructure.success),
283
+ ]) {
284
+ endStateFailures.push(label(name));
285
+ }
286
+ }
287
+ }
288
+ const vacuous = [
289
+ ...campaignsFailingTheirProbe(campaignRules.success, extractor, (file) => routeFor(file)?.language.syntax ?? null, functions).map((failed) => failed.outOfScope === true
290
+ ? `${failed.name} (its probe ${failed.probe.path} is outside the campaign's own scope)`
291
+ : failed.expected === "fires"
292
+ ? `${failed.name} (fires probe ${failed.probe.path} did not fire)`
293
+ : failed.expected === "end-shape"
294
+ ? `${failed.name} (no fires probe is a sector in its end shape — one that no objective ` +
295
+ `fires on — so the perimeter would un-birth the sector the moment its first phase was met)`
296
+ : `${failed.name} (ignores probe ${failed.probe.path} fired` +
297
+ (failed.admittedBy === undefined ? ")" : `, admitted by \`${failed.admittedBy}\`)`)),
298
+ ...endStateFailures,
299
+ ];
300
+ const ledgerDir = spec.ledger ?? DEFAULT_LEDGER_DIR;
301
+ const ledgers = readLedgers(configPath, fileSystem, ledgerDir, campaignRules.success);
302
+ if (Result.isFailure(ledgers))
303
+ return Result.fail(ledgers.failure);
304
+ return Result.succeed({
305
+ value: {
306
+ campaignRules: campaignRules.success,
307
+ ledgers: ledgers.success.ledgers,
308
+ legacyLedgers: ledgers.success.legacy,
309
+ sectorRecords: ledgers.success.sectorRecords,
310
+ plans: ledgers.success.plans,
311
+ ledgerDir,
312
+ functions,
313
+ reports: options.reports ?? NO_REPORTS,
314
+ },
315
+ vacuous,
316
+ });
317
+ };
318
+ // The extension, as a host composes it. `loadPolicy({ …, extensions: [
319
+ // campaignsExtension({ functions, reports }) ] })`.
320
+ export const campaignsExtension = (options = {}) => ({
321
+ id: CAMPAIGNS_EXTENSION_ID,
322
+ manifestKeys: ["campaigns", "ledger"],
323
+ decode: (slice, describe) => decodeCampaigns(slice, describe),
324
+ load: (context) => load(options, context),
325
+ });
326
+ //# sourceMappingURL=extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../src/load/extension.ts"],"names":[],"mappings":"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"}