@json-to-office/shared 3.0.0 → 3.2.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.
@@ -1,4 +1,4 @@
1
- import { R as ResolvedFontSource, a as RasterizeFontFace, b as ResolvedFont } from '../types-kcQwhOlf.js';
1
+ import { R as ResolvedFontSource, a as RasterizeFontFace, b as ResolvedFont } from '../types-DyQ0V9MU.js';
2
2
  import { GenerationWarning } from '../types/warnings.js';
3
3
  import '@sinclair/typebox';
4
4
 
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { C as ComponentDefinition, a as ComponentSchemaConfig, c as convertToJsonSchema, b as createComponentSchema, d as createComponentSchemaObject, e as exportSchemaToFile, f as fixSchemaReferences } from './schema-utils-B2i75lAT.js';
2
2
  export { AddWarningFunction, GenerationWarning } from './types/warnings.js';
3
- import { F as FontRegistryEntry, c as FontRuntimeOpts, R as ResolvedFontSource, b as ResolvedFont, a as RasterizeFontFace } from './types-kcQwhOlf.js';
4
- export { D as DEFAULT_VISUAL_DPI, d as FontFamilyNameSchema, e as FontRegistryDefinition, f as FontRegistryEntrySchema, g as FontRegistrySchema, h as FontSource, i as FontSourceSchema, H as HighchartsHeaders, j as HighchartsHeadersResolver, k as HighchartsServiceConfig, M as MAX_RASTERIZE_BATCH_SLIDES, l as MAX_RASTERIZE_FONTS, m as MAX_RASTERIZE_FONT_BYTES, n as MAX_VISUAL_DPI, o as MIN_VISUAL_DPI, P as PptxBatchRasterizer, p as PptxRasterizeBatchRequest, q as PptxRasterizeBatchResult, r as PptxRasterizeBatchSlide, s as PptxRasterizeBatchSlideResult, t as PptxRasterizeFailureStage, u as PptxRasterizeRequest, v as PptxRasterizeResult, w as PptxRasterizer, x as PptxServiceConfig, y as PptxServiceHeaders, z as PptxServiceHeadersResolver, S as SAFE_FONTS, A as SafeFontName, B as ServicesConfig, C as clampVisualDpi, E as isSafeFont } from './types-kcQwhOlf.js';
3
+ import { F as FontRegistryEntry, c as FontRuntimeOpts, R as ResolvedFontSource, b as ResolvedFont, a as RasterizeFontFace } from './types-DyQ0V9MU.js';
4
+ export { D as DEFAULT_VISUAL_DPI, d as FontFamilyNameSchema, e as FontRegistryDefinition, f as FontRegistryEntrySchema, g as FontRegistrySchema, h as FontSource, i as FontSourceSchema, H as HighchartsHeaders, j as HighchartsHeadersResolver, k as HighchartsServiceConfig, M as MAX_RASTERIZE_BATCH_SLIDES, l as MAX_RASTERIZE_FONTS, m as MAX_RASTERIZE_FONT_BYTES, n as MAX_VISUAL_DPI, o as MIN_VISUAL_DPI, P as PptxBatchRasterizer, p as PptxRasterizeBatchRequest, q as PptxRasterizeBatchResult, r as PptxRasterizeBatchSlide, s as PptxRasterizeBatchSlideResult, t as PptxRasterizeFailureStage, u as PptxRasterizeRequest, v as PptxRasterizeResult, w as PptxRasterizer, x as PptxServiceConfig, y as PptxServiceHeaders, z as PptxServiceHeadersResolver, S as SAFE_FONTS, A as SafeFontName, B as ServicesConfig, C as clampVisualDpi, E as isSafeFont } from './types-DyQ0V9MU.js';
5
5
  import { O as OfficeFormat } from './capabilities-DtPF3aBj.js';
6
6
  export { F as FeatureRequirement, a as FeatureRequirementCollector, b as OfficeRenderer, R as RENDERER_DEPENDENCY_MISSING, c as RenderOptions, d as RendererDiagnostic, e as RendererDiagnosticSeverity, f as RendererRegistry, g as RendererStatus, h as UnsupportedRendererFeatureError, i as UnsupportedRendererFeatureErrorInit, j as assertNever, k as assertRendererSupports, l as diagnoseUnsupportedFeatures, p as partitionDiagnostics, r as rendererError, m as rendererWarning } from './capabilities-DtPF3aBj.js';
7
7
  export { DEFAULT_ERROR_CONFIG, ERROR_EMOJIS, ErrorFormatterConfig, calculatePosition, clearComponentNamesCache, createErrorConfig, createJsonParseError, extractStandardComponentNames, formatErrorMessage, formatErrorSummary, getLiteralValue, getObjectSchemaPropertyNames, getSchemaMetadata, groupErrorsByPath, isLiteralSchema, isObjectSchema, isUnionSchema, transformValueError, transformValueErrors } from './validation/unified/index.js';
@@ -1822,6 +1822,19 @@ declare class JsonBlockEvaluator {
1822
1822
  private nodes;
1823
1823
  constructor(definitions: Record<string, JsonBlockDefinition>, options: BlockEvaluatorOptions);
1824
1824
  private guard;
1825
+ /**
1826
+ * A directive operand and the authored pointer it came from: the slot the
1827
+ * pointer form names, or the current item, slot or context a reference
1828
+ * object names. Definitions are validated before this runs, so a malformed
1829
+ * operand cannot reach it.
1830
+ */
1831
+ private operand;
1832
+ /**
1833
+ * What a reference reads and where the author wrote it. One resolution for
1834
+ * the binding form and the operand form, so `{ "$context": ... }` is
1835
+ * attributed the same way whichever directive carries it.
1836
+ */
1837
+ private reference;
1825
1838
  evaluate(value: unknown, env: BlockEnvironment, out: string, definitionPath: string, depth?: number): unknown;
1826
1839
  expand(value: unknown, path?: string, depth?: number): unknown;
1827
1840
  }
@@ -2030,4 +2043,25 @@ declare function blockReferencesFromDocument(document: unknown, source: {
2030
2043
  */
2031
2044
  declare function mergeWithDefaults<T>(userConfig: T, themeDefaults: Partial<T>): T;
2032
2045
 
2033
- export { BLOCK_SLOT_PLACEMENT_PROPS, BLOCK_SLOT_ROLES, type BlockComposition, type BlockCompositionOptions, BlockDefinitionsSchema, type BlockEnvironment, BlockEvaluationError, type BlockEvaluatorOptions, type BlockInvocationExample, BlockInvocationPropsSchema, type BlockIssue, type BlockReference, type BlockSectionEffect, type BlockSlideEffect, type BlockSlot, type BlockSlotBudget, type BlockSlotRole, type BlockSlotRoleValue, BlockSlotSchema, type BlockSourceMap, CANVASES, type ChartTypography, ChromeSchema, DEFAULT_CHART_THEME_COLORS, type DesignCanvas, DesignSpacingSchema, type DesignSystem, DesignSystemProperties, DesignSystemSchema, type DocumentBlockTarget, type ExpandedBlocks, FONT_URL_ALLOWLIST, type FontIssueCode, FontRegistry, FontRegistryEntry, type FontRegistryInput, type FontResolutionIssue, FontRuntimeOpts, type FontSubstitution, type FontValidationInput, type FontValidationResult, type JsonBlockDefinition, JsonBlockDefinitionSchema, JsonBlockEvaluator, MotifSchema, OfficeFormat, POINTS_PER_PIXEL_96DPI, POPULAR_GOOGLE_FONTS, PaletteSchema, type PopularGoogleFont, ROLE_SCALE_STEPS, RasterizeFontFace, ResolvedFont, ResolvedFontSource, type SynthesizedFamily, TYPE_ROLES, TextCaseSchema, type TypeRole, type TypeRoleName, TypeRoleNameSchema, TypeRoleSchema, TypeRolesSchema, TypographySchema, UPSTREAM_OVERRIDES, type UpstreamOverride, type UpstreamVariant, WEIGHT_LABELS, applyDocumentBlocksToSchema, applyExportMode, applyFontSubstitution, blockDependencies, blockInvocationExample, blockInvocationPropsSchema, blockPointerKey, blockReferencesFromDocument, blockSlotBudgets, blockSlotEditorSchema, blockSlotFacts, blockSlotJsonSchema, blockSlotMarkdown, blockSlotRoles, blockSlotsEditorSchema, blockSlotsJsonSchema, blockValueAt, blockWordCount, buildDefaultSubstitutionMap, capsFormatting, chartFamilyResolver, chartFontFaceCss, chartPointsPerPixel, collectFontNamesFromDocx, collectFontNamesFromPptx, composeBlocksWithPlugins, createBlockAuthoringSchema, cssFontFamily, defaultSubstituteFor, designCanvas, designColors, detectFontFormat, documentBlockMetadata, documentFontRegistry, fetchGoogleFontSources, getUpstreamOverride, isAllowedFontUrl, isBlockRecord, mergeFontRegistries, mergeWithDefaults, readBlockDefinitions, resolveBlockSlot, resolveDesignColor, resolveTypeRoles, restructureNameDiscriminatedUnions, rewriteFontFamilyName, synthesizeFamilyName, themeFontRegistry, toAuthoredBlockPointer, unionBranches, validateBlockDefinitions, validateBlockInvocations, validateDesignColors, validateFontReferences, withChartFontFaceCss, withChartTypography };
2046
+ /**
2047
+ * Whether a service URL stays on this machine or a private network.
2048
+ *
2049
+ * The question the `highcharts` component has to answer before it posts a
2050
+ * chart — every series, label and title — to an export server. Only what an
2051
+ * address itself proves counts: loopback, RFC 1918, link-local and
2052
+ * unique-local literals, `localhost`, and the special-use names reserved for
2053
+ * private resolution (`.local`, `.internal`, `.home.arpa`). A hostname that
2054
+ * DNS decides — a bare label, a `.corp` — is not guessed at: it needs
2055
+ * `services.highcharts.allowRemote`, like any other.
2056
+ */
2057
+ declare function isPrivateServiceUrl(url: string): boolean;
2058
+ /** Warning code for a chart posted outside the private network. */
2059
+ declare const REMOTE_EXPORT_WARNING = "W_HIGHCHARTS_REMOTE_EXPORT";
2060
+ /**
2061
+ * A public export server is a decision, not a default: the request carries
2062
+ * the whole chart, data included. Throws unless the caller opted in; when it
2063
+ * did, returns the sentence each pipeline records as a warning.
2064
+ */
2065
+ declare function remoteExportNotice(serverUrl: string, allowRemote: boolean | undefined): string | undefined;
2066
+
2067
+ export { BLOCK_SLOT_PLACEMENT_PROPS, BLOCK_SLOT_ROLES, type BlockComposition, type BlockCompositionOptions, BlockDefinitionsSchema, type BlockEnvironment, BlockEvaluationError, type BlockEvaluatorOptions, type BlockInvocationExample, BlockInvocationPropsSchema, type BlockIssue, type BlockReference, type BlockSectionEffect, type BlockSlideEffect, type BlockSlot, type BlockSlotBudget, type BlockSlotRole, type BlockSlotRoleValue, BlockSlotSchema, type BlockSourceMap, CANVASES, type ChartTypography, ChromeSchema, DEFAULT_CHART_THEME_COLORS, type DesignCanvas, DesignSpacingSchema, type DesignSystem, DesignSystemProperties, DesignSystemSchema, type DocumentBlockTarget, type ExpandedBlocks, FONT_URL_ALLOWLIST, type FontIssueCode, FontRegistry, FontRegistryEntry, type FontRegistryInput, type FontResolutionIssue, FontRuntimeOpts, type FontSubstitution, type FontValidationInput, type FontValidationResult, type JsonBlockDefinition, JsonBlockDefinitionSchema, JsonBlockEvaluator, MotifSchema, OfficeFormat, POINTS_PER_PIXEL_96DPI, POPULAR_GOOGLE_FONTS, PaletteSchema, type PopularGoogleFont, REMOTE_EXPORT_WARNING, ROLE_SCALE_STEPS, RasterizeFontFace, ResolvedFont, ResolvedFontSource, type SynthesizedFamily, TYPE_ROLES, TextCaseSchema, type TypeRole, type TypeRoleName, TypeRoleNameSchema, TypeRoleSchema, TypeRolesSchema, TypographySchema, UPSTREAM_OVERRIDES, type UpstreamOverride, type UpstreamVariant, WEIGHT_LABELS, applyDocumentBlocksToSchema, applyExportMode, applyFontSubstitution, blockDependencies, blockInvocationExample, blockInvocationPropsSchema, blockPointerKey, blockReferencesFromDocument, blockSlotBudgets, blockSlotEditorSchema, blockSlotFacts, blockSlotJsonSchema, blockSlotMarkdown, blockSlotRoles, blockSlotsEditorSchema, blockSlotsJsonSchema, blockValueAt, blockWordCount, buildDefaultSubstitutionMap, capsFormatting, chartFamilyResolver, chartFontFaceCss, chartPointsPerPixel, collectFontNamesFromDocx, collectFontNamesFromPptx, composeBlocksWithPlugins, createBlockAuthoringSchema, cssFontFamily, defaultSubstituteFor, designCanvas, designColors, detectFontFormat, documentBlockMetadata, documentFontRegistry, fetchGoogleFontSources, getUpstreamOverride, isAllowedFontUrl, isBlockRecord, isPrivateServiceUrl, mergeFontRegistries, mergeWithDefaults, readBlockDefinitions, remoteExportNotice, resolveBlockSlot, resolveDesignColor, resolveTypeRoles, restructureNameDiscriminatedUnions, rewriteFontFamilyName, synthesizeFamilyName, themeFontRegistry, toAuthoredBlockPointer, unionBranches, validateBlockDefinitions, validateBlockInvocations, validateDesignColors, validateFontReferences, withChartFontFaceCss, withChartTypography };
package/dist/index.js CHANGED
@@ -1738,6 +1738,7 @@ var BLOCK_DIRECTIVES = {
1738
1738
  $join: { keys: ["$join", "separator", "keepEmpty"], result: "string" },
1739
1739
  $measure: { keys: ["$measure", "fraction", "unit"], result: "number" }
1740
1740
  };
1741
+ var BLOCK_OPERAND_ROOTS = ["$item", "$slot", "$context"];
1741
1742
 
1742
1743
  // src/blocks/evaluator.ts
1743
1744
  import { Value } from "@sinclair/typebox/value";
@@ -1920,6 +1921,21 @@ function slotDescriptorAt(slots, pointer2) {
1920
1921
  }
1921
1922
  return descriptor;
1922
1923
  }
1924
+ var OPERAND_DIRECTIVES = ["$if", "$each", "$count"];
1925
+ var isPointer = (value) => typeof value === "string" && (value === "" || value.startsWith("/"));
1926
+ function blockOperand(value, key) {
1927
+ if (isPointer(value))
1928
+ return {
1929
+ root: OPERAND_DIRECTIVES.includes(key) ? "$slot" : key,
1930
+ pointer: value
1931
+ };
1932
+ if (!OPERAND_DIRECTIVES.includes(key) || !isBlockRecord(value))
1933
+ return void 0;
1934
+ const keys = Object.keys(value);
1935
+ const root = BLOCK_OPERAND_ROOTS.find((candidate) => candidate === keys[0]);
1936
+ if (keys.length !== 1 || !root || !isPointer(value[root])) return void 0;
1937
+ return { root, pointer: value[root] };
1938
+ }
1923
1939
  function checkTemplate(value, path, slots, issues, repeated = false, depth = 0) {
1924
1940
  if (depth > 64) {
1925
1941
  issues.push({
@@ -1957,20 +1973,20 @@ function checkTemplate(value, path, slots, issues, repeated = false, depth = 0)
1957
1973
  "$each",
1958
1974
  "$count"
1959
1975
  ].includes(key)) {
1960
- const pointer2 = value[key];
1961
- if (typeof pointer2 !== "string" || pointer2 !== "" && !pointer2.startsWith("/"))
1976
+ const operand = blockOperand(value[key], key);
1977
+ if (!operand)
1962
1978
  issues.push({
1963
1979
  path,
1964
1980
  code: "block_invalid_binding",
1965
- message: "Bindings use JSON Pointers, e.g. /title."
1981
+ message: OPERAND_DIRECTIVES.includes(key) ? `${key} takes a slot pointer such as /items, or one reference: ${BLOCK_OPERAND_ROOTS.map((root) => `{ "${root}": ... }`).join(", ")}.` : "Bindings use JSON Pointers, e.g. /title."
1966
1982
  });
1967
- else if (["$slot", "$if", "$each", "$count"].includes(key)) {
1968
- const descriptor = slotDescriptorAt(slots, pointer2);
1983
+ else if (operand.root === "$slot") {
1984
+ const descriptor = slotDescriptorAt(slots, operand.pointer);
1969
1985
  if (!descriptor)
1970
1986
  issues.push({
1971
1987
  path,
1972
1988
  code: "block_unknown_binding",
1973
- message: `No slot field '${pointer2}' is declared.`
1989
+ message: `No slot field '${operand.pointer}' is declared.`
1974
1990
  });
1975
1991
  else if (["$each", "$count"].includes(key) && descriptor.type !== "array")
1976
1992
  issues.push({
@@ -1979,7 +1995,7 @@ function checkTemplate(value, path, slots, issues, repeated = false, depth = 0)
1979
1995
  message: `${key} requires an array slot.`
1980
1996
  });
1981
1997
  }
1982
- if (key === "$item" && !repeated)
1998
+ if (operand?.root === "$item" && !repeated)
1983
1999
  issues.push({
1984
2000
  path,
1985
2001
  code: "block_invalid_binding",
@@ -2164,6 +2180,55 @@ var JsonBlockEvaluator = class {
2164
2180
  "Block expansion exceeds the depth/node limit (64/50000)."
2165
2181
  );
2166
2182
  }
2183
+ /**
2184
+ * A directive operand and the authored pointer it came from: the slot the
2185
+ * pointer form names, or the current item, slot or context a reference
2186
+ * object names. Definitions are validated before this runs, so a malformed
2187
+ * operand cannot reach it.
2188
+ */
2189
+ operand(raw, key, env) {
2190
+ const { root, pointer: pointer2 } = blockOperand(raw, key);
2191
+ const { value, source } = this.reference(root, pointer2, env);
2192
+ return {
2193
+ value,
2194
+ source,
2195
+ // Element i of the array is authored at pointer/i, looked up the same
2196
+ // way: a slot the enclosing invocation built from its own repeat maps
2197
+ // element by element, and pointer + "/i" is not the same as that.
2198
+ element: (index) => this.reference(root, `${pointer2}/${index}`, env).source
2199
+ };
2200
+ }
2201
+ /**
2202
+ * What a reference reads and where the author wrote it. One resolution for
2203
+ * the binding form and the operand form, so `{ "$context": ... }` is
2204
+ * attributed the same way whichever directive carries it.
2205
+ */
2206
+ reference(root, pointer2, env) {
2207
+ if (root === "$item")
2208
+ return {
2209
+ value: blockValueAt(env.item, pointer2),
2210
+ source: `${env.itemSource ?? env.source}${pointer2}`
2211
+ };
2212
+ if (root === "$context") {
2213
+ const authored = toAuthoredBlockPointer(
2214
+ env.contextSources ?? {},
2215
+ pointer2
2216
+ );
2217
+ return {
2218
+ value: blockValueAt(env.context, pointer2),
2219
+ source: authored === pointer2 ? env.source : authored
2220
+ };
2221
+ }
2222
+ if (root === "$theme")
2223
+ return {
2224
+ value: blockValueAt(this.options.theme, pointer2),
2225
+ source: env.source
2226
+ };
2227
+ return {
2228
+ value: blockValueAt(env.slots, pointer2),
2229
+ source: env.slotSources ? toAuthoredBlockPointer(env.slotSources, pointer2) : `${env.source}/props/slots${pointer2}`
2230
+ };
2231
+ }
2167
2232
  evaluate(value, env, out, definitionPath, depth = 0) {
2168
2233
  this.guard(env.source, depth);
2169
2234
  this.sourceMap[out] = env.source;
@@ -2201,14 +2266,12 @@ var JsonBlockEvaluator = class {
2201
2266
  (k) => k in value
2202
2267
  );
2203
2268
  const pointer2 = value[key];
2204
- const root = key === "$slot" ? env.slots : key === "$item" ? env.item : key === "$theme" ? this.options.theme : env.context;
2205
- const found = blockValueAt(root, pointer2);
2206
- if (key === "$slot")
2207
- this.sourceMap[out] = env.slotSources ? toAuthoredBlockPointer(env.slotSources, pointer2) : `${env.source}/props/slots${pointer2}`;
2208
- if (key === "$item")
2209
- this.sourceMap[out] = `${env.itemSource ?? env.source}${pointer2}`;
2210
- if (key === "$context")
2211
- this.sourceMap[out] = toAuthoredBlockPointer(env.contextSources ?? {}, pointer2) === pointer2 ? env.source : toAuthoredBlockPointer(env.contextSources ?? {}, pointer2);
2269
+ const { value: found, source } = this.reference(
2270
+ key,
2271
+ pointer2,
2272
+ env
2273
+ );
2274
+ this.sourceMap[out] = source;
2212
2275
  let result2 = found !== void 0 ? structuredClone(found) : void 0;
2213
2276
  if (result2 === void 0 && own(value, "default"))
2214
2277
  result2 = this.evaluate(
@@ -2251,31 +2314,33 @@ var JsonBlockEvaluator = class {
2251
2314
  }
2252
2315
  return result2;
2253
2316
  }
2254
- if ("$if" in value)
2255
- return this.evaluate(
2256
- present(blockValueAt(env.slots, value.$if)) ? value.then : value.else,
2257
- env,
2258
- out,
2259
- definitionPath,
2260
- depth + 1
2261
- );
2317
+ if ("$if" in value) {
2318
+ const operand = this.operand(value.$if, "$if", env);
2319
+ const branch = present(operand.value) ? value.then : value.else;
2320
+ const result2 = this.evaluate(branch, env, out, definitionPath, depth + 1);
2321
+ const literal = !isBlockRecord(branch) || !Object.keys(branch).some((k) => k.startsWith("$"));
2322
+ if (literal && this.sourceMap[out] === env.source)
2323
+ this.sourceMap[out] = operand.source;
2324
+ return result2;
2325
+ }
2262
2326
  if ("$count" in value) {
2263
- const list = blockValueAt(env.slots, value.$count);
2264
- if (!Array.isArray(list))
2327
+ const operand = this.operand(value.$count, "$count", env);
2328
+ if (!Array.isArray(operand.value))
2265
2329
  return fail(
2266
- `${env.source}/props/slots${value.$count}`,
2330
+ operand.source,
2267
2331
  "block_slot_type",
2268
- "$count requires an array slot."
2332
+ "$count requires an array."
2269
2333
  );
2270
- return list.length;
2334
+ return operand.value.length;
2271
2335
  }
2272
2336
  if ("$each" in value) {
2273
- const list = blockValueAt(env.slots, value.$each);
2337
+ const operand = this.operand(value.$each, "$each", env);
2338
+ const list = operand.value;
2274
2339
  if (!Array.isArray(list))
2275
2340
  return fail(
2276
- `${env.source}/props/slots${value.$each}`,
2341
+ operand.source,
2277
2342
  "block_slot_type",
2278
- "$each requires an array slot."
2343
+ "$each requires an array."
2279
2344
  );
2280
2345
  const result2 = [];
2281
2346
  list.forEach((item, i) => {
@@ -2285,14 +2350,17 @@ var JsonBlockEvaluator = class {
2285
2350
  {
2286
2351
  ...env,
2287
2352
  item,
2288
- itemSource: env.slotSources ? toAuthoredBlockPointer(env.slotSources, `${value.$each}/${i}`) : `${env.source}/props/slots${value.$each}/${i}`
2353
+ itemSource: operand.element(i)
2289
2354
  },
2290
2355
  pointer2,
2291
2356
  `${definitionPath}/template`,
2292
2357
  depth + 1
2293
2358
  );
2294
- if (evaluated !== void 0) result2.push(evaluated);
2295
- else
2359
+ if (evaluated !== void 0) {
2360
+ if (this.sourceMap[pointer2] === env.source)
2361
+ this.sourceMap[pointer2] = operand.element(i);
2362
+ result2.push(evaluated);
2363
+ } else
2296
2364
  for (const key of Object.keys(this.sourceMap)) {
2297
2365
  if (key === pointer2 || key.startsWith(`${pointer2}/`))
2298
2366
  delete this.sourceMap[key];
@@ -2702,6 +2770,15 @@ function createBlockAuthoringSchema(definitions, componentDefinition, excludedCo
2702
2770
  const prefix = `BlockTemplate_${componentDefinition}`;
2703
2771
  const references = referenceDescriptions(format);
2704
2772
  const measure = measureDescriptions(format);
2773
+ const operand = (description) => ({
2774
+ description,
2775
+ anyOf: [
2776
+ pointer(description),
2777
+ ...BLOCK_OPERAND_ROOTS.map(
2778
+ (root) => object({ [root]: pointer(references[root]) }, [root])
2779
+ )
2780
+ ]
2781
+ });
2705
2782
  const bodyName = `${prefix}_Body`;
2706
2783
  const ref = (name) => ({ $ref: `#/definitions/${name}` });
2707
2784
  if (definitions[bodyName]) return ref(bodyName);
@@ -2867,8 +2944,8 @@ function createBlockAuthoringSchema(definitions, componentDefinition, excludedCo
2867
2944
  case "$if":
2868
2945
  specs[directive] = object(
2869
2946
  {
2870
- $if: pointer(
2871
- "Test a slot by JSON Pointer, e.g. /subtitle. Missing, null, false, empty text and empty arrays select else; zero selects then."
2947
+ $if: operand(
2948
+ 'Test a slot by JSON Pointer, e.g. /subtitle, or a reference such as { "$item": "/numeric" }. Missing, null, false, empty text and empty arrays select else; zero selects then.'
2872
2949
  ),
2873
2950
  then: describe(
2874
2951
  branch(),
@@ -2885,8 +2962,8 @@ function createBlockAuthoringSchema(definitions, componentDefinition, excludedCo
2885
2962
  case "$each":
2886
2963
  specs[directive] = object(
2887
2964
  {
2888
- $each: pointer(
2889
- "Repeat template for each entry in an array slot, e.g. /items. Read the current entry with $item."
2965
+ $each: operand(
2966
+ 'Repeat template for each entry in an array slot, e.g. /items, or in an array of the current entry, { "$item": "/cells" }. Read the current entry with $item.'
2890
2967
  ),
2891
2968
  template: describe(
2892
2969
  item(),
@@ -2899,8 +2976,8 @@ function createBlockAuthoringSchema(definitions, componentDefinition, excludedCo
2899
2976
  case "$count":
2900
2977
  specs[directive] = object(
2901
2978
  {
2902
- $count: pointer(
2903
- "Return the number of entries in an array slot, e.g. /items."
2979
+ $count: operand(
2980
+ 'Return the number of entries in an array slot, e.g. /items, or in an array of the current entry, { "$item": "/cells" }.'
2904
2981
  )
2905
2982
  },
2906
2983
  ["$count"]
@@ -3351,6 +3428,38 @@ function deepMerge(target, source) {
3351
3428
  function mergeWithDefaults(userConfig, themeDefaults) {
3352
3429
  return deepMerge(themeDefaults, userConfig);
3353
3430
  }
3431
+
3432
+ // src/utils/serviceUrl.ts
3433
+ function isPrivateServiceUrl(url) {
3434
+ let hostname;
3435
+ try {
3436
+ hostname = new URL(
3437
+ /^https?:\/\//i.test(url.trim()) ? url.trim() : `http://${url.trim()}`
3438
+ ).hostname.toLowerCase();
3439
+ } catch {
3440
+ return false;
3441
+ }
3442
+ const host = hostname.replace(/^\[|\]$/g, "").replace(/\.$/, "");
3443
+ if (host === "localhost" || host.endsWith(".localhost")) return true;
3444
+ if (host === "::1" || /^f[cd][0-9a-f]{2}:/.test(host)) return true;
3445
+ if (/^fe[89ab][0-9a-f]:/.test(host)) return true;
3446
+ const v4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
3447
+ if (v4) {
3448
+ const [a, b] = [Number(v4[1]), Number(v4[2])];
3449
+ return a === 127 || a === 10 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 168 || a === 169 && b === 254;
3450
+ }
3451
+ return /\.(local|internal|home\.arpa)$/.test(host);
3452
+ }
3453
+ var REMOTE_EXPORT_WARNING = "W_HIGHCHARTS_REMOTE_EXPORT";
3454
+ function remoteExportNotice(serverUrl, allowRemote) {
3455
+ if (isPrivateServiceUrl(serverUrl)) return void 0;
3456
+ if (!allowRemote) {
3457
+ throw new Error(
3458
+ `Highcharts export server ${serverUrl} is outside this machine and its private networks, and a chart is posted whole \u2014 every series, label and title. Run the export server locally (pnpm dlx highcharts-export-server --enableServer true), or set services.highcharts.allowRemote (HIGHCHARTS_ALLOW_REMOTE=1) to send chart data there deliberately.`
3459
+ );
3460
+ }
3461
+ return `Chart data \u2014 every series, label and title \u2014 was sent to ${serverUrl}, outside this machine and its private networks (services.highcharts.allowRemote).`;
3462
+ }
3354
3463
  export {
3355
3464
  BLOCK_SLOT_PLACEMENT_PROPS,
3356
3465
  BLOCK_SLOT_ROLES,
@@ -3387,6 +3496,7 @@ export {
3387
3496
  POINTS_PER_PIXEL_96DPI,
3388
3497
  POPULAR_GOOGLE_FONTS,
3389
3498
  PaletteSchema,
3499
+ REMOTE_EXPORT_WARNING,
3390
3500
  RENDERER_DEPENDENCY_MISSING,
3391
3501
  ROLE_SCALE_STEPS,
3392
3502
  RendererRegistry,
@@ -3465,6 +3575,7 @@ export {
3465
3575
  isBlockRecord,
3466
3576
  isLiteralSchema,
3467
3577
  isObjectSchema,
3578
+ isPrivateServiceUrl,
3468
3579
  isSafeFont,
3469
3580
  isUnionSchema,
3470
3581
  isValidSemver,
@@ -3475,6 +3586,7 @@ export {
3475
3586
  parseSemver,
3476
3587
  partitionDiagnostics,
3477
3588
  readBlockDefinitions,
3589
+ remoteExportNotice,
3478
3590
  rendererError,
3479
3591
  rendererWarning,
3480
3592
  resolveBlockSlot,