@sanity/ailf 6.1.1 → 6.1.2

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.
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Cross Dataset Reference (CDR) write shape (D0043).
3
+ *
4
+ * The shape AILF documents use to reference editorial content (article,
5
+ * docPage, …) across the dataset boundary (`ailf-prod-private` →
6
+ * editorial). Sanity's Mutation API requires `_projectId` even when both
7
+ * datasets live in the same project (W0154 spike Finding 13). `_weak: true`
8
+ * keeps the AILF document publishable when the editorial target is retired
9
+ * (Finding 16) and matches the W0155 schema declaration.
10
+ *
11
+ * Canonical builder for this shape. Used by:
12
+ *
13
+ * - `packages/eval/src/sanity/client.ts:buildEditorialReference()` — the
14
+ * env-aware runtime wrapper that supplies projectId + dataset from
15
+ * env, used by the eval pipeline's mirror step (W0156).
16
+ * - `packages/studio/scripts/migrate-to-private-dataset.ts` — the
17
+ * one-shot corpus migration script (W0159).
18
+ *
19
+ * Adding a field here is a single edit; both consumers pick it up without
20
+ * drift. That is the load-bearing property — the migration script and the
21
+ * runtime write path must emit byte-identical CDR shapes.
22
+ */
23
+ export interface EditorialReference {
24
+ _type: "crossDatasetReference";
25
+ _projectId: string;
26
+ _dataset: string;
27
+ _ref: string;
28
+ _weak?: boolean;
29
+ }
30
+ export interface MakeEditorialReferenceArgs {
31
+ /** Sanity project ID hosting both source and dest datasets. */
32
+ projectId: string;
33
+ /** The editorial dataset name (e.g. "next"). */
34
+ dataset: string;
35
+ /** The document ID being referenced. */
36
+ refId: string;
37
+ /** Whether the reference is weak. Defaults to true for AILF→editorial. */
38
+ weak?: boolean;
39
+ }
40
+ /**
41
+ * Construct an editorial Cross Dataset Reference. Pure — no env reads, no
42
+ * side effects. Callers that need env-aware defaults (the eval pipeline)
43
+ * wrap this; callers with explicit config (the migration script) call it
44
+ * directly.
45
+ *
46
+ * @throws if `refId` is empty.
47
+ */
48
+ export declare function makeEditorialReference(args: MakeEditorialReferenceArgs): EditorialReference;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Cross Dataset Reference (CDR) write shape (D0043).
3
+ *
4
+ * The shape AILF documents use to reference editorial content (article,
5
+ * docPage, …) across the dataset boundary (`ailf-prod-private` →
6
+ * editorial). Sanity's Mutation API requires `_projectId` even when both
7
+ * datasets live in the same project (W0154 spike Finding 13). `_weak: true`
8
+ * keeps the AILF document publishable when the editorial target is retired
9
+ * (Finding 16) and matches the W0155 schema declaration.
10
+ *
11
+ * Canonical builder for this shape. Used by:
12
+ *
13
+ * - `packages/eval/src/sanity/client.ts:buildEditorialReference()` — the
14
+ * env-aware runtime wrapper that supplies projectId + dataset from
15
+ * env, used by the eval pipeline's mirror step (W0156).
16
+ * - `packages/studio/scripts/migrate-to-private-dataset.ts` — the
17
+ * one-shot corpus migration script (W0159).
18
+ *
19
+ * Adding a field here is a single edit; both consumers pick it up without
20
+ * drift. That is the load-bearing property — the migration script and the
21
+ * runtime write path must emit byte-identical CDR shapes.
22
+ */
23
+ /**
24
+ * Construct an editorial Cross Dataset Reference. Pure — no env reads, no
25
+ * side effects. Callers that need env-aware defaults (the eval pipeline)
26
+ * wrap this; callers with explicit config (the migration script) call it
27
+ * directly.
28
+ *
29
+ * @throws if `refId` is empty.
30
+ */
31
+ export function makeEditorialReference(args) {
32
+ if (!args.refId) {
33
+ throw new Error("makeEditorialReference: refId is required");
34
+ }
35
+ const weak = args.weak ?? true;
36
+ return {
37
+ _type: "crossDatasetReference",
38
+ _projectId: args.projectId,
39
+ _dataset: args.dataset,
40
+ _ref: args.refId,
41
+ ...(weak ? { _weak: true } : {}),
42
+ };
43
+ }
@@ -19,6 +19,7 @@
19
19
  */
20
20
  export { computeCanaryDrift, type CanaryDriftReport, type CanaryReportSlim, type DriftEntry, type DriftThresholds, type DriftVerdict, } from "./canary-drift.js";
21
21
  export { type DocumentRef } from "./document-ref.js";
22
+ export { makeEditorialReference, type EditorialReference, type MakeEditorialReferenceArgs, } from "./editorial-reference.js";
22
23
  export { FEATURE_FLAGS, type FeatureFlag, type FeatureFlagKey, } from "./feature-flags.js";
23
24
  export { GRADE_BOUNDARIES, scoreGrade, type ScoreGrade, } from "./score-grades.js";
24
25
  export { NOISE_THRESHOLD } from "./noise-threshold.js";
@@ -18,6 +18,7 @@
18
18
  * surface against future regressions.
19
19
  */
20
20
  export { computeCanaryDrift, } from "./canary-drift.js";
21
+ export { makeEditorialReference, } from "./editorial-reference.js";
21
22
  export { FEATURE_FLAGS, } from "./feature-flags.js";
22
23
  export { GRADE_BOUNDARIES, scoreGrade, } from "./score-grades.js";
23
24
  export { NOISE_THRESHOLD } from "./noise-threshold.js";
@@ -135,7 +135,7 @@ export declare function buildMirrorDocument(task: LiteracyTaskDefinition, opts:
135
135
  _key: string;
136
136
  reason: string;
137
137
  } | {
138
- doc?: import("../sanity/client.js").EditorialReference | undefined;
138
+ doc?: import("@sanity/ailf-shared").EditorialReference | undefined;
139
139
  docId?: string | undefined;
140
140
  refType: string;
141
141
  _key: string;
@@ -1,5 +1,7 @@
1
1
  import { type SanityClient } from "@sanity/client";
2
+ import { type EditorialReference } from "../_vendor/ailf-shared/index.d.ts";
2
3
  import type { ResolvedSourceConfig } from "../sources.js";
4
+ export type { EditorialReference };
3
5
  export interface SanityConfig {
4
6
  apiVersion: string;
5
7
  dataset: string;
@@ -50,25 +52,6 @@ export declare function getAilfSanityClient(overrides?: Partial<SanityConfig>):
50
52
  * mutating env vars between tests so the cached client doesn't leak.
51
53
  */
52
54
  export declare function resetAilfSanityClientCache(): void;
53
- /**
54
- * The write shape for a Cross Dataset Reference. Sanity's Mutation API
55
- * requires `_projectId` even when the target dataset lives in the same
56
- * project (spike Finding 13). `_weak: true` keeps the AILF source doc
57
- * publishable when the editorial target is retired (Finding 16).
58
- *
59
- * The literal `_type: "crossDatasetReference"` matches the receiving
60
- * Studio schema field type and the validated migration script
61
- * (`packages/studio/scripts/poc-migrate-to-private.ts`).
62
- *
63
- * @see docs/decisions/D0043-private-dataset-with-cdrs.md
64
- */
65
- export interface EditorialReference {
66
- _type: "crossDatasetReference";
67
- _projectId: string;
68
- _dataset: string;
69
- _ref: string;
70
- _weak?: boolean;
71
- }
72
55
  export interface BuildEditorialReferenceOptions {
73
56
  /** Override the editorial-side project ID. Defaults to AILF project. */
74
57
  projectId?: string;
@@ -82,7 +65,9 @@ export interface BuildEditorialReferenceOptions {
82
65
  weak?: boolean;
83
66
  }
84
67
  /**
85
- * Build a Cross Dataset Reference from an AILF document into editorial content.
68
+ * Build a Cross Dataset Reference from an AILF document into editorial content,
69
+ * with env-aware defaults for `projectId` / `dataset` so call sites can pass
70
+ * just the `refId` in the common case.
86
71
  *
87
72
  * Use this for any reference field on an `ailf.*` document that points at an
88
73
  * editorial type (`article`, `docPage`, …). The schema-side counterpart is a
@@ -90,7 +75,7 @@ export interface BuildEditorialReferenceOptions {
90
75
  *
91
76
  * @example
92
77
  * const docRef = buildEditorialReference(articleId)
93
- * // → { _type: "reference", _projectId: "3do82whm",
78
+ * // → { _type: "crossDatasetReference", _projectId: "3do82whm",
94
79
  * // _dataset: "next", _ref: articleId, _weak: true }
95
80
  */
96
81
  export declare function buildEditorialReference(refId: string, options?: BuildEditorialReferenceOptions): EditorialReference;
@@ -1,11 +1,14 @@
1
1
  import { createClient } from "@sanity/client";
2
- // Transitional default for AILF operational documents while D0043 rollout
3
- // is in progress. Code paths route through `getAilfSanityClient()` so the
4
- // default flip to `ailf-prod-private` is a single-line change after the
5
- // migration script (D0043 rollout step 5) ships and runs. Until then the
6
- // default mirrors the editorial dataset to avoid silent dual-write across
7
- // the cutover boundary.
8
- const AILF_DATASET_DEFAULT = "next";
2
+ import { makeEditorialReference, } from "../_vendor/ailf-shared/index.js";
3
+ // Belt-and-suspenders default for AILF operational documents per D0043.
4
+ // In practice this constant is never the load-bearing value in any
5
+ // production-shaped env: the cascade in `getAilfDefaultConfig()` is
6
+ // `AILF_REPORT_DATASET ?? SANITY_DATASET ?? AILF_DATASET_DEFAULT`, and
7
+ // every deployed env sets at least `SANITY_DATASET` for editorial reads.
8
+ // The constant matters only for ad-hoc runs with no env at all — where
9
+ // landing in `ailf-prod-private` is safer than polluting the editorial
10
+ // dataset with stray writes.
11
+ const AILF_DATASET_DEFAULT = "ailf-prod-private";
9
12
  // Default editorial dataset that AILF cross-dataset references point at.
10
13
  // Used by `buildEditorialReference()` and by Studio's CDR field config.
11
14
  const EDITORIAL_DATASET_DEFAULT = "next";
@@ -157,7 +160,9 @@ export function resetAilfSanityClientCache() {
157
160
  _ailfClient = null;
158
161
  }
159
162
  /**
160
- * Build a Cross Dataset Reference from an AILF document into editorial content.
163
+ * Build a Cross Dataset Reference from an AILF document into editorial content,
164
+ * with env-aware defaults for `projectId` / `dataset` so call sites can pass
165
+ * just the `refId` in the common case.
161
166
  *
162
167
  * Use this for any reference field on an `ailf.*` document that points at an
163
168
  * editorial type (`article`, `docPage`, …). The schema-side counterpart is a
@@ -165,13 +170,10 @@ export function resetAilfSanityClientCache() {
165
170
  *
166
171
  * @example
167
172
  * const docRef = buildEditorialReference(articleId)
168
- * // → { _type: "reference", _projectId: "3do82whm",
173
+ * // → { _type: "crossDatasetReference", _projectId: "3do82whm",
169
174
  * // _dataset: "next", _ref: articleId, _weak: true }
170
175
  */
171
176
  export function buildEditorialReference(refId, options = {}) {
172
- if (!refId) {
173
- throw new Error("buildEditorialReference: refId is required");
174
- }
175
177
  // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
176
178
  const envProjectId = process.env.AILF_REPORT_PROJECT_ID || process.env.SANITY_PROJECT_ID;
177
179
  // Editorial dataset precedence: explicit AILF_EDITORIAL_DATASET overrides;
@@ -179,14 +181,10 @@ export function buildEditorialReference(refId, options = {}) {
179
181
  // correct editorial dataset); fall back to "next" only when nothing is set.
180
182
  // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
181
183
  const envDataset = process.env.AILF_EDITORIAL_DATASET || process.env.SANITY_DATASET;
182
- const projectId = options.projectId ?? envProjectId ?? "3do82whm";
183
- const dataset = options.dataset ?? envDataset ?? EDITORIAL_DATASET_DEFAULT;
184
- const weak = options.weak ?? true;
185
- return {
186
- _type: "crossDatasetReference",
187
- _projectId: projectId,
188
- _dataset: dataset,
189
- _ref: refId,
190
- ...(weak ? { _weak: true } : {}),
191
- };
184
+ return makeEditorialReference({
185
+ projectId: options.projectId ?? envProjectId ?? "3do82whm",
186
+ dataset: options.dataset ?? envDataset ?? EDITORIAL_DATASET_DEFAULT,
187
+ refId,
188
+ weak: options.weak,
189
+ });
192
190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/ailf",
3
- "version": "6.1.1",
3
+ "version": "6.1.2",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"