@ryuzaki13/react-foundation-lib 1.2.4 → 1.2.5

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 { Mt as e } from "./odata-service-D8oFjUah.js";
1
+ import { Mt as e } from "./odata-service-DnPlNGpU.js";
2
2
  var t = {
3
3
  decimals: 1,
4
4
  decimalSeparator: ",",
@@ -489,4 +489,4 @@ function E(e) {
489
489
  //#endregion
490
490
  export { f as a, d as c, o as d, s as f, u as h, m as i, n as l, l as m, T as n, g as o, c as p, C as r, h as s, E as t, t as u };
491
491
 
492
- //# sourceMappingURL=validate-DrKdjesg.js.map
492
+ //# sourceMappingURL=validate-nWY_Mla5.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-DrKdjesg.js","names":[],"sources":["../../src/formatters/number/presets.ts","../../src/formatters/rowBased/context.ts","../../src/formatters/rowBased/registry.ts","../../src/formatters/pipeline/validate.ts"],"sourcesContent":["import type { NumberFormatPreset, NumberFormatPresetConfig } from \"./types\";\n\n/** Символ группировки из ru-RU (U+00A0 или U+202F в зависимости от среды) */\nconst ruGroupChar = new Intl.NumberFormat(\"ru-RU\").formatToParts(1000).find((p) => p.type === \"group\")?.value ?? \"\\u00A0\";\n\n/** Значения по умолчанию — совпадают с ru-RU форматированием */\nexport const NUMBER_FORMAT_DEFAULTS: Omit<NumberFormatPreset, \"name\"> = {\n\tdecimals: 1,\n\tdecimalSeparator: \",\",\n\tgrouping: true,\n\tgroupingSeparator: ruGroupChar,\n\tgroupingSize: 3\n};\n\nexport const DEFAULT_NUMBER_PRESET_NAMES = Object.freeze({\n\tinteger: \"integer\",\n\tdecimal: \"decimal\",\n\tdecimal2: \"decimal-2\",\n\tdecimal3: \"decimal-3\",\n\tcurrency: \"currency\",\n\tprice: \"price\",\n\tpercent: \"percent\",\n\ttonnage: \"tonnage\",\n\tcompactCurrency: \"compact-currency\",\n\tcompactCurrencyRound: \"compact-currency-round\",\n\tcompactPercent: \"compact-percent\",\n\tcompactPercentRound: \"compact-percent-round\",\n\tcompactTonnage: \"compact-tonnage\",\n\tcompactTonnageRound: \"compact-tonnage-round\"\n});\n\n/**\n * Типовые предустановки числового форматирования.\n *\n * Compact-пресеты без суффикса сохраняют консервативное усечение, а парные\n * `*-round` дают явный математический режим без runtime-переопределения пресета.\n * Недостающие поля каждой предустановки заполняются из `NUMBER_FORMAT_DEFAULTS`.\n */\nconst BUILTIN: NumberFormatPresetConfig[] = [\n\t{ name: \"integer\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"decimal\" },\n\t{ name: \"decimal-2\", decimals: 2 },\n\t{ name: \"decimal-3\", decimals: 3 },\n\t{ name: \"currency\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"price\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"percent\", decimals: 2 },\n\t{ name: \"tonnage\" },\n\t{ name: \"compact-currency\", decimals: 0, decimalSeparator: \"\", compact: {} },\n\t{ name: \"compact-currency-round\", decimals: 0, decimalSeparator: \"\", compact: { roundingMode: \"round\" } },\n\t{ name: \"compact-percent\", decimals: 2, compact: { maxDecimals: 2 } },\n\t{ name: \"compact-percent-round\", decimals: 2, compact: { maxDecimals: 2, roundingMode: \"round\" } },\n\t{ name: \"compact-tonnage\", compact: { maxDecimals: 1 } },\n\t{ name: \"compact-tonnage-round\", compact: { maxDecimals: 1, roundingMode: \"round\" } }\n];\n\nconst registry = new Map<string, NumberFormatPreset>();\n\nfunction init(): void {\n\tfor (const cfg of BUILTIN) {\n\t\tregistry.set(cfg.name, { ...NUMBER_FORMAT_DEFAULTS, ...cfg });\n\t}\n}\n\ninit();\n\nexport function getNumberPreset(name: string): NumberFormatPreset | undefined {\n\treturn registry.get(name);\n}\n\nexport function getNumberPresetNames(): string[] {\n\treturn Array.from(registry.keys());\n}\n\n/** Зарегистрировать или перезаписать предустановку. Недостающие поля берутся из FORMAT_DEFAULTS. */\nexport function registerNumberPreset(config: NumberFormatPresetConfig): NumberFormatPreset {\n\tconst preset: NumberFormatPreset = { ...NUMBER_FORMAT_DEFAULTS, ...config };\n\tregistry.set(preset.name, preset);\n\treturn preset;\n}\n\n/** Сбросить реестр к начальному состоянию (только типовые предустановки) */\nexport function resetNumberPresets(): void {\n\tregistry.clear();\n\tinit();\n}\n\nexport function resolveNumberPreset(presetOrName: string | NumberFormatPreset): NumberFormatPreset {\n\tif (typeof presetOrName !== \"string\") return presetOrName;\n\n\tconst found = getNumberPreset(presetOrName);\n\tif (!found) throw new Error(`Предустановка \"${presetOrName}\" не найдена`);\n\n\treturn found;\n}\n","import { parseNumber } from \"../number\";\n\nimport type { RowBasedFormatterContext, RowBasedFormatterContextInstrumentation } from \"./types\";\n\nexport function createRowBasedFormatterContext(args: {\n\trowData: Record<string, unknown>;\n\trawValue: unknown;\n\tcolumnId: string;\n\tkeys?: readonly string[];\n\tinstrumentation?: RowBasedFormatterContextInstrumentation;\n}): RowBasedFormatterContext {\n\t// TODO: duplicate createTableFormulaContext src\\shared\\lib\\formulas\\execute.ts\n\tconst keys = [...(args.keys ?? [])];\n\n\tconst readKey = (index: number): string | undefined => {\n\t\tif (!Number.isInteger(index) || index < 0) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\targs.instrumentation?.onReadIndex?.(index);\n\n\t\tif (index >= keys.length) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn keys[index];\n\t};\n\n\tconst readValue = (index: number): unknown => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return undefined;\n\t\treturn args.rowData[key];\n\t};\n\n\tconst readNum = (index: number): number => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return 0;\n\t\treturn parseNumber(args.rowData[key]);\n\t};\n\n\treturn {\n\t\trowData: args.rowData,\n\t\trawValue: args.rawValue,\n\t\tcolumnId: args.columnId,\n\t\tkey: readKey,\n\t\tvalue: readValue,\n\t\tnum: readNum\n\t};\n}\n","import type { RowBasedFormatterDefinition } from \"./types\";\n\nexport type RowBasedFormatterRegistry = Readonly<{\n\tlist: readonly RowBasedFormatterDefinition[];\n\tbyId: ReadonlyMap<string, RowBasedFormatterDefinition>;\n}>;\n\n/**\n * Создаёт реестр формул для подмены значения в групповой строке.\n */\nexport function createRowBasedFormatterRegistry(definitions: readonly RowBasedFormatterDefinition[]): RowBasedFormatterRegistry {\n\tconst byId = new Map<string, RowBasedFormatterDefinition>();\n\tconst list: RowBasedFormatterDefinition[] = [];\n\n\tfor (const definition of definitions) {\n\t\tconst normalizedId = definition.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tthrow new Error(\"Formula id для RowBasedFormatter не может быть пустым\");\n\t\t}\n\n\t\tif (byId.has(normalizedId)) {\n\t\t\tthrow new Error(`Найден дублирующийся formulaId в RowBasedFormatter: ${normalizedId}`);\n\t\t}\n\n\t\tconst normalizedDefinition: RowBasedFormatterDefinition = Object.freeze({\n\t\t\t...definition,\n\t\t\tid: normalizedId,\n\t\t\tname: definition.name.trim(),\n\t\t\tdescription: definition.description.trim()\n\t\t});\n\n\t\tbyId.set(normalizedId, normalizedDefinition);\n\t\tlist.push(normalizedDefinition);\n\t}\n\n\treturn Object.freeze({\n\t\tlist: Object.freeze(list),\n\t\tbyId\n\t});\n}\n\nlet rowBasedFormatterRegistry = createRowBasedFormatterRegistry([]);\n\n/**\n * Устанавливает реестр row-based форматтеров host-приложения.\n *\n * Pipeline использует этот реестр при валидации и компиляции formula-режима,\n * поэтому конфигурация должна завершиться до первого построения runtime.\n */\nexport function configureRowBasedFormatterRegistry(registry: RowBasedFormatterRegistry): void {\n\trowBasedFormatterRegistry = registry;\n}\n\n/**\n * Возвращает список доступных формул для групповой подмены.\n */\nexport function getRowBasedFormatterList(): readonly RowBasedFormatterDefinition[] {\n\treturn rowBasedFormatterRegistry.list;\n}\n\n/**\n * Возвращает формулу по id.\n */\nexport function getRowBasedFormatterById(formulaId: string | undefined): RowBasedFormatterDefinition | undefined {\n\tconst normalizedId = formulaId?.trim();\n\tif (!normalizedId) return undefined;\n\treturn rowBasedFormatterRegistry.byId.get(normalizedId);\n}\n","import { getNumberPreset } from \"../number\";\nimport { createRowBasedFormatterContext, getRowBasedFormatterById } from \"../rowBased\";\n\nimport type {\n\tFormattersPipelineConfig,\n\tFormattersPipelineEdge,\n\tFormattersPipelineGraph,\n\tFormattersPipelineNode,\n\tFormattersPipelinePlan,\n\tFormattersPipelineRowBasedOverrideFormulaConfig,\n\tFormattersPipelineStep\n} from \"./types\";\n\nexport type FormattersPipelineValidationCode =\n\t| \"config_not_defined\"\n\t| \"unsupported_version\"\n\t| \"graph_or_plan_required\"\n\t| \"node_id_duplicate\"\n\t| \"edge_id_duplicate\"\n\t| \"edge_node_not_found\"\n\t| \"source_count_invalid\"\n\t| \"sink_count_invalid\"\n\t| \"source_incoming_invalid\"\n\t| \"sink_outgoing_invalid\"\n\t| \"node_degree_invalid\"\n\t| \"path_broken\"\n\t| \"path_cycle_detected\"\n\t| \"path_disconnected_nodes\"\n\t| \"step_id_duplicate\"\n\t| \"step_resolve_value_state_multiple\"\n\t| \"step_typed_value_format_multiple\"\n\t| \"step_row_based_override_multiple\"\n\t| \"step_normalize_leading_zeros_multiple\"\n\t| \"step_typed_before_value_state\"\n\t| \"step_row_based_override_field_key_empty\"\n\t| \"step_row_based_override_formula_id_empty\"\n\t| \"step_row_based_override_formula_not_found\"\n\t| \"step_row_based_override_dependency_index_out_of_range\"\n\t| \"step_row_based_override_unused_dependencies\"\n\t| \"step_row_based_override_formula_does_not_use_dependencies\"\n\t| \"step_row_based_override_formula_runtime_error\"\n\t| \"step_threshold_states_count_invalid\"\n\t| \"step_value_hidden_without_icon\"\n\t| \"step_typed_value_format_preset_empty\"\n\t| \"step_typed_value_format_preset_not_found\";\n\nexport type FormattersPipelineValidationMessage = {\n\tcode: FormattersPipelineValidationCode;\n\tmessage: string;\n};\n\nexport type FormattersPipelineValidationResult = {\n\tok: boolean;\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n\tplan?: FormattersPipelinePlan;\n};\n\ntype MutableValidationState = {\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n};\n\nfunction pushError(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.errors.push({ code, message });\n}\n\nfunction pushWarning(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.warnings.push({ code, message });\n}\n\nfunction toSortedArray(items: Set<number>): number[] {\n\treturn [...items].sort((left, right) => left - right);\n}\n\nfunction createSampleRowData(dependencies: readonly string[], multiplier: number): Record<string, unknown> {\n\treturn dependencies.reduce<Record<string, unknown>>((acc, dependencyId, index) => {\n\t\tacc[dependencyId] = (index + 1) * multiplier;\n\t\treturn acc;\n\t}, {});\n}\n\nfunction validateRowBasedOverrideFormulaConfig(config: FormattersPipelineRowBasedOverrideFormulaConfig, state: MutableValidationState) {\n\tif (!config.formulaId.trim()) {\n\t\tpushError(state, \"step_row_based_override_formula_id_empty\", \"Для rowBasedOverride (formula) необходимо заполнить formulaId.\");\n\t\treturn;\n\t}\n\n\tconst formula = getRowBasedFormatterById(config.formulaId);\n\tconst dependencies = [...(config.dependencyIds ?? [])];\n\n\tif (!formula) {\n\t\tpushError(state, \"step_row_based_override_formula_not_found\", \"Формула rowBasedOverride не найдена в реестре.\");\n\t\treturn;\n\t}\n\n\tconst usedIndexes = new Set<number>();\n\tconst outOfRangeIndexes = new Set<number>();\n\tlet runtimeErrorCount = 0;\n\n\tconst runValidationPass = (sampleRowData: Record<string, unknown>) => {\n\t\ttry {\n\t\t\tconst context = createRowBasedFormatterContext({\n\t\t\t\trowData: sampleRowData,\n\t\t\t\trawValue: 100,\n\t\t\t\tcolumnId: \"__validation__\",\n\t\t\t\tkeys: dependencies,\n\t\t\t\tinstrumentation: {\n\t\t\t\t\tonReadIndex: (index) => {\n\t\t\t\t\t\tusedIndexes.add(index);\n\t\t\t\t\t},\n\t\t\t\t\tonOutOfRangeIndex: (index) => {\n\t\t\t\t\t\toutOfRangeIndexes.add(index);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tformula.fn(context);\n\t\t} catch {\n\t\t\truntimeErrorCount += 1;\n\t\t}\n\t};\n\n\t// Несколько прогонов повышают шанс увидеть обращения к индексам в разных ветках формулы.\n\trunValidationPass(createSampleRowData(dependencies, 100));\n\trunValidationPass(createSampleRowData(dependencies, -100));\n\n\tconst sortedUsedIndexes = toSortedArray(usedIndexes);\n\tconst requiredDependencyCount = sortedUsedIndexes.length > 0 ? sortedUsedIndexes[sortedUsedIndexes.length - 1] + 1 : 0;\n\n\tif (outOfRangeIndexes.size > 0) {\n\t\tpushError(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_dependency_index_out_of_range\",\n\t\t\t`Формула rowBasedOverride обращается к несуществующим индексам. Минимально требуется зависимостей: ${requiredDependencyCount}, выбрано: ${dependencies.length}.`\n\t\t);\n\t}\n\n\tif (sortedUsedIndexes.length === 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_does_not_use_dependencies\",\n\t\t\t\"Формула rowBasedOverride не использует dependencyIds.\"\n\t\t);\n\t}\n\n\tconst unusedDependencies = dependencies.filter((_, index) => !usedIndexes.has(index));\n\tif (unusedDependencies.length > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_unused_dependencies\",\n\t\t\t`Выбраны, но не используются формулой rowBasedOverride: ${unusedDependencies.join(\", \")}.`\n\t\t);\n\t}\n\n\tif (runtimeErrorCount > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_runtime_error\",\n\t\t\t\"На тестовых данных формула rowBasedOverride завершилась с ошибкой.\"\n\t\t);\n\t}\n}\n\nfunction validateStepDefinitions(steps: readonly FormattersPipelineStep[], state: MutableValidationState) {\n\tconst stepIdSet = new Set<string>();\n\tconst counters = {\n\t\tnormalizeLeadingZeros: 0,\n\t\trowBasedOverride: 0,\n\t\tresolveValueState: 0,\n\t\ttypedValueFormat: 0\n\t};\n\n\tfor (const step of steps) {\n\t\tconst normalizedId = step.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"step_id_duplicate\", \"Шаг pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (stepIdSet.has(normalizedId)) {\n\t\t\tpushError(state, \"step_id_duplicate\", `Найден дублирующийся id шага pipeline: ${normalizedId}.`);\n\t\t}\n\t\tstepIdSet.add(normalizedId);\n\n\t\tswitch (step.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tcounters.normalizeLeadingZeros += 1;\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tcounters.rowBasedOverride += 1;\n\n\t\t\t\tif (step.config.mode === \"field\" && !step.config.fieldKey.trim()) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_row_based_override_field_key_empty\",\n\t\t\t\t\t\t\"Для rowBasedOverride (field) необходимо заполнить fieldKey.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (step.config.mode === \"formula\") {\n\t\t\t\t\tvalidateRowBasedOverrideFormulaConfig(step.config, state);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tcounters.resolveValueState += 1;\n\n\t\t\t\tif (\n\t\t\t\t\tstep.config.resolver.kind === \"threshold\" &&\n\t\t\t\t\tstep.config.resolver.states.length !== step.config.resolver.thresholds.length + 1\n\t\t\t\t) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_threshold_states_count_invalid\",\n\t\t\t\t\t\t\"Для threshold-резолвера количество states должно быть равно thresholds + 1.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tcounters.typedValueFormat += 1;\n\t\t\t\tif (step.config?.numberPresetName !== undefined) {\n\t\t\t\t\tconst normalizedPresetName = step.config.numberPresetName.trim();\n\t\t\t\t\tif (!normalizedPresetName) {\n\t\t\t\t\t\tpushError(state, \"step_typed_value_format_preset_empty\", \"Для typedValueFormat указан пустой numberPresetName.\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!getNumberPreset(normalizedPresetName)) {\n\t\t\t\t\t\tpushError(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\t\"step_typed_value_format_preset_not_found\",\n\t\t\t\t\t\t\t`Для typedValueFormat указан неизвестный пресет: ${normalizedPresetName}.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (counters.normalizeLeadingZeros > 1) {\n\t\tpushError(state, \"step_normalize_leading_zeros_multiple\", \"В pipeline может быть только один шаг normalizeLeadingZeros.\");\n\t}\n\n\tif (counters.rowBasedOverride > 1) {\n\t\tpushError(state, \"step_row_based_override_multiple\", \"В pipeline может быть только один шаг rowBasedOverride.\");\n\t}\n\n\tif (counters.resolveValueState > 1) {\n\t\tpushError(state, \"step_resolve_value_state_multiple\", \"В pipeline может быть только один шаг resolveValueState.\");\n\t}\n\n\tif (counters.typedValueFormat > 1) {\n\t\tpushError(state, \"step_typed_value_format_multiple\", \"В pipeline может быть только один шаг typedValueFormat.\");\n\t}\n\n\tconst resolveIndex = steps.findIndex((step) => step.type === \"resolveValueState\");\n\tconst typedIndex = steps.findIndex((step) => step.type === \"typedValueFormat\");\n\tif (resolveIndex !== -1 && typedIndex !== -1 && typedIndex < resolveIndex) {\n\t\tpushError(state, \"step_typed_before_value_state\", \"Шаг typedValueFormat не может выполняться до шага resolveValueState.\");\n\t}\n\n\tfor (const step of steps) {\n\t\tif (step.type !== \"resolveValueState\") continue;\n\t\tif (!step.config.icon?.enabled && step.config.icon?.showValue === false) {\n\t\t\tpushWarning(\n\t\t\t\tstate,\n\t\t\t\t\"step_value_hidden_without_icon\",\n\t\t\t\t\"Для resolveValueState установлено showValue=false при выключенной иконке: значение не будет отображаться.\"\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Валидация облегчённого плана pipeline.\n */\nexport function validateFormattersPipelinePlan(plan: FormattersPipelinePlan): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tvalidateStepDefinitions(plan.steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps: [...plan.steps] } : undefined\n\t};\n}\n\nfunction buildLinearPathFromGraph(\n\tnodes: readonly FormattersPipelineNode[],\n\tedges: readonly FormattersPipelineEdge[],\n\tstate: MutableValidationState\n): string[] | undefined {\n\tconst nodeById = new Map(nodes.map((node) => [node.id, node]));\n\tconst outgoing = new Map<string, string[]>();\n\tconst incoming = new Map<string, string[]>();\n\n\tfor (const node of nodes) {\n\t\toutgoing.set(node.id, []);\n\t\tincoming.set(node.id, []);\n\t}\n\n\tfor (const edge of edges) {\n\t\tconst source = edge.source.trim();\n\t\tconst target = edge.target.trim();\n\t\tif (!nodeById.has(source) || !nodeById.has(target)) {\n\t\t\tpushError(state, \"edge_node_not_found\", `Ребро ${edge.id} ссылается на несуществующий узел: ${source} -> ${target}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\toutgoing.get(source)?.push(target);\n\t\tincoming.get(target)?.push(source);\n\t}\n\n\tconst sources = nodes.filter((node) => node.type === \"source\");\n\tconst sinks = nodes.filter((node) => node.type === \"sink\");\n\n\tif (sources.length !== 1) {\n\t\tpushError(state, \"source_count_invalid\", \"В графе должен быть ровно один узел source.\");\n\t}\n\tif (sinks.length !== 1) {\n\t\tpushError(state, \"sink_count_invalid\", \"В графе должен быть ровно один узел sink.\");\n\t}\n\tif (state.errors.length > 0) return undefined;\n\n\tconst sourceNodeId = sources[0]!.id;\n\tconst sinkNodeId = sinks[0]!.id;\n\n\tfor (const node of nodes) {\n\t\tconst inDegree = incoming.get(node.id)?.length ?? 0;\n\t\tconst outDegree = outgoing.get(node.id)?.length ?? 0;\n\n\t\tif (node.type === \"source\") {\n\t\t\tif (inDegree !== 0) {\n\t\t\t\tpushError(state, \"source_incoming_invalid\", \"Узел source не должен иметь входящих рёбер.\");\n\t\t\t}\n\t\t\tif (outDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел source должен иметь ровно одно исходящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (node.type === \"sink\") {\n\t\t\tif (outDegree !== 0) {\n\t\t\t\tpushError(state, \"sink_outgoing_invalid\", \"Узел sink не должен иметь исходящих рёбер.\");\n\t\t\t}\n\t\t\tif (inDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел sink должен иметь ровно одно входящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inDegree !== 1 || outDegree !== 1) {\n\t\t\tpushError(\n\t\t\t\tstate,\n\t\t\t\t\"node_degree_invalid\",\n\t\t\t\t`Узел ${node.id} должен иметь ровно одно входящее и одно исходящее ребро для линейного pipeline.`\n\t\t\t);\n\t\t}\n\t}\n\n\tif (state.errors.length > 0) return undefined;\n\n\tconst visited = new Set<string>();\n\tconst path: string[] = [];\n\tlet cursor = sourceNodeId;\n\n\twhile (true) {\n\t\tif (visited.has(cursor)) {\n\t\t\tpushError(state, \"path_cycle_detected\", \"В графе pipeline обнаружен цикл.\");\n\t\t\treturn undefined;\n\t\t}\n\t\tvisited.add(cursor);\n\t\tpath.push(cursor);\n\n\t\tif (cursor === sinkNodeId) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst nextCandidates = outgoing.get(cursor) ?? [];\n\t\tif (nextCandidates.length !== 1) {\n\t\t\tpushError(state, \"path_broken\", \"Не удалось построить линейный путь от source к sink.\");\n\t\t\treturn undefined;\n\t\t}\n\n\t\tcursor = nextCandidates[0]!;\n\t}\n\n\tif (visited.size !== nodes.length) {\n\t\tpushError(state, \"path_disconnected_nodes\", \"Граф содержит узлы, которые не входят в линейный путь source -> sink.\");\n\t\treturn undefined;\n\t}\n\n\treturn path;\n}\n\n/**\n * Валидация графа pipeline и построение линейного плана исполнения.\n */\nexport function validateFormattersPipelineGraph(graph: FormattersPipelineGraph): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!graph.nodes.length) {\n\t\tpushError(state, \"path_broken\", \"Граф pipeline не содержит узлов.\");\n\t\treturn { ok: false, errors: state.errors, warnings: state.warnings };\n\t}\n\n\tconst nodeById = new Map<string, FormattersPipelineNode>();\n\tfor (const node of graph.nodes) {\n\t\tconst normalizedId = node.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"node_id_duplicate\", \"Узел pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nodeById.has(normalizedId)) {\n\t\t\tpushError(state, \"node_id_duplicate\", `Найден дублирующийся id узла pipeline: ${normalizedId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tnodeById.set(normalizedId, node);\n\t}\n\n\tconst edgeIdSet = new Set<string>();\n\tfor (const edge of graph.edges) {\n\t\tconst normalizedEdgeId = edge.id.trim();\n\t\tif (!normalizedEdgeId) {\n\t\t\tpushError(state, \"edge_id_duplicate\", \"Ребро pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (edgeIdSet.has(normalizedEdgeId)) {\n\t\t\tpushError(state, \"edge_id_duplicate\", `Найден дублирующийся id ребра pipeline: ${normalizedEdgeId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tedgeIdSet.add(normalizedEdgeId);\n\t}\n\n\tif (state.errors.length > 0) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst path = buildLinearPathFromGraph(graph.nodes, graph.edges, state);\n\tif (!path) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst steps: FormattersPipelineStep[] = [];\n\tfor (const nodeId of path) {\n\t\tconst node = nodeById.get(nodeId);\n\t\tif (!node || node.type === \"source\" || node.type === \"sink\") continue;\n\n\t\tswitch (node.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"normalizeLeadingZeros\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"rowBasedOverride\",\n\t\t\t\t\tconfig:\n\t\t\t\t\t\tnode.config.mode === \"formula\"\n\t\t\t\t\t\t\t? { ...node.config, dependencyIds: node.config.dependencyIds ? [...node.config.dependencyIds] : undefined }\n\t\t\t\t\t\t\t: { ...node.config }\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"resolveValueState\",\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tresolver:\n\t\t\t\t\t\t\tnode.config.resolver.kind === \"fixed\"\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tkind: \"fixed\",\n\t\t\t\t\t\t\t\t\t\tentries: { ...node.config.resolver.entries },\n\t\t\t\t\t\t\t\t\t\tfallbackState: node.config.resolver.fallbackState\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\tkind: \"threshold\",\n\t\t\t\t\t\t\t\t\t\tthresholds: node.config.resolver.thresholds.map((item) =>\n\t\t\t\t\t\t\t\t\t\t\ttypeof item === \"number\" ? item : { ...item }\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tstates: [...node.config.resolver.states],\n\t\t\t\t\t\t\t\t\t\tinvalidState: node.config.resolver.invalidState\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\ticon: node.config.icon ? { ...node.config.icon } : undefined\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"typedValueFormat\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tvalidateStepDefinitions(steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps } : undefined\n\t};\n}\n\n/**\n * Валидация конфигурации pipeline c выбором рабочего плана исполнения.\n *\n * Приоритет источника плана:\n * 1) `plan` из конфигурации;\n * 2) построение плана из `graph`.\n */\nexport function validateFormattersPipelineConfig(config: FormattersPipelineConfig | undefined): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!config) {\n\t\tpushError(state, \"config_not_defined\", \"Конфигурация pipeline не задана.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.version !== 1) {\n\t\tpushError(state, \"unsupported_version\", `Неподдерживаемая версия pipeline: ${String(config.version)}.`);\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (!config.plan && !config.graph) {\n\t\tpushError(state, \"graph_or_plan_required\", \"Для pipeline должен быть задан хотя бы один источник: graph или plan.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.plan) {\n\t\tconst planResult = validateFormattersPipelinePlan(config.plan);\n\t\tstate.errors.push(...planResult.errors);\n\t\tstate.warnings.push(...planResult.warnings);\n\n\t\tif (planResult.ok && planResult.plan) {\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings,\n\t\t\t\tplan: planResult.plan\n\t\t\t};\n\t\t}\n\n\t\tif (config.graph) {\n\t\t\tpushWarning(state, \"path_broken\", \"Линейный plan невалиден. Выполнена попытка построить план из graph.\");\n\t\t\tstate.errors.length = 0;\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings\n\t\t\t};\n\t\t}\n\t}\n\n\tif (config.graph) {\n\t\tconst graphResult = validateFormattersPipelineGraph(config.graph);\n\t\treturn {\n\t\t\tok: graphResult.ok,\n\t\t\terrors: [...state.errors, ...graphResult.errors],\n\t\t\twarnings: [...state.warnings, ...graphResult.warnings],\n\t\t\tplan: graphResult.plan\n\t\t};\n\t}\n\n\treturn {\n\t\tok: false,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validate-nWY_Mla5.js","names":[],"sources":["../../src/formatters/number/presets.ts","../../src/formatters/rowBased/context.ts","../../src/formatters/rowBased/registry.ts","../../src/formatters/pipeline/validate.ts"],"sourcesContent":["import type { NumberFormatPreset, NumberFormatPresetConfig } from \"./types\";\n\n/** Символ группировки из ru-RU (U+00A0 или U+202F в зависимости от среды) */\nconst ruGroupChar = new Intl.NumberFormat(\"ru-RU\").formatToParts(1000).find((p) => p.type === \"group\")?.value ?? \"\\u00A0\";\n\n/** Значения по умолчанию — совпадают с ru-RU форматированием */\nexport const NUMBER_FORMAT_DEFAULTS: Omit<NumberFormatPreset, \"name\"> = {\n\tdecimals: 1,\n\tdecimalSeparator: \",\",\n\tgrouping: true,\n\tgroupingSeparator: ruGroupChar,\n\tgroupingSize: 3\n};\n\nexport const DEFAULT_NUMBER_PRESET_NAMES = Object.freeze({\n\tinteger: \"integer\",\n\tdecimal: \"decimal\",\n\tdecimal2: \"decimal-2\",\n\tdecimal3: \"decimal-3\",\n\tcurrency: \"currency\",\n\tprice: \"price\",\n\tpercent: \"percent\",\n\ttonnage: \"tonnage\",\n\tcompactCurrency: \"compact-currency\",\n\tcompactCurrencyRound: \"compact-currency-round\",\n\tcompactPercent: \"compact-percent\",\n\tcompactPercentRound: \"compact-percent-round\",\n\tcompactTonnage: \"compact-tonnage\",\n\tcompactTonnageRound: \"compact-tonnage-round\"\n});\n\n/**\n * Типовые предустановки числового форматирования.\n *\n * Compact-пресеты без суффикса сохраняют консервативное усечение, а парные\n * `*-round` дают явный математический режим без runtime-переопределения пресета.\n * Недостающие поля каждой предустановки заполняются из `NUMBER_FORMAT_DEFAULTS`.\n */\nconst BUILTIN: NumberFormatPresetConfig[] = [\n\t{ name: \"integer\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"decimal\" },\n\t{ name: \"decimal-2\", decimals: 2 },\n\t{ name: \"decimal-3\", decimals: 3 },\n\t{ name: \"currency\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"price\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"percent\", decimals: 2 },\n\t{ name: \"tonnage\" },\n\t{ name: \"compact-currency\", decimals: 0, decimalSeparator: \"\", compact: {} },\n\t{ name: \"compact-currency-round\", decimals: 0, decimalSeparator: \"\", compact: { roundingMode: \"round\" } },\n\t{ name: \"compact-percent\", decimals: 2, compact: { maxDecimals: 2 } },\n\t{ name: \"compact-percent-round\", decimals: 2, compact: { maxDecimals: 2, roundingMode: \"round\" } },\n\t{ name: \"compact-tonnage\", compact: { maxDecimals: 1 } },\n\t{ name: \"compact-tonnage-round\", compact: { maxDecimals: 1, roundingMode: \"round\" } }\n];\n\nconst registry = new Map<string, NumberFormatPreset>();\n\nfunction init(): void {\n\tfor (const cfg of BUILTIN) {\n\t\tregistry.set(cfg.name, { ...NUMBER_FORMAT_DEFAULTS, ...cfg });\n\t}\n}\n\ninit();\n\nexport function getNumberPreset(name: string): NumberFormatPreset | undefined {\n\treturn registry.get(name);\n}\n\nexport function getNumberPresetNames(): string[] {\n\treturn Array.from(registry.keys());\n}\n\n/** Зарегистрировать или перезаписать предустановку. Недостающие поля берутся из FORMAT_DEFAULTS. */\nexport function registerNumberPreset(config: NumberFormatPresetConfig): NumberFormatPreset {\n\tconst preset: NumberFormatPreset = { ...NUMBER_FORMAT_DEFAULTS, ...config };\n\tregistry.set(preset.name, preset);\n\treturn preset;\n}\n\n/** Сбросить реестр к начальному состоянию (только типовые предустановки) */\nexport function resetNumberPresets(): void {\n\tregistry.clear();\n\tinit();\n}\n\nexport function resolveNumberPreset(presetOrName: string | NumberFormatPreset): NumberFormatPreset {\n\tif (typeof presetOrName !== \"string\") return presetOrName;\n\n\tconst found = getNumberPreset(presetOrName);\n\tif (!found) throw new Error(`Предустановка \"${presetOrName}\" не найдена`);\n\n\treturn found;\n}\n","import { parseNumber } from \"../number\";\n\nimport type { RowBasedFormatterContext, RowBasedFormatterContextInstrumentation } from \"./types\";\n\nexport function createRowBasedFormatterContext(args: {\n\trowData: Record<string, unknown>;\n\trawValue: unknown;\n\tcolumnId: string;\n\tkeys?: readonly string[];\n\tinstrumentation?: RowBasedFormatterContextInstrumentation;\n}): RowBasedFormatterContext {\n\t// TODO: duplicate createTableFormulaContext src\\shared\\lib\\formulas\\execute.ts\n\tconst keys = [...(args.keys ?? [])];\n\n\tconst readKey = (index: number): string | undefined => {\n\t\tif (!Number.isInteger(index) || index < 0) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\targs.instrumentation?.onReadIndex?.(index);\n\n\t\tif (index >= keys.length) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn keys[index];\n\t};\n\n\tconst readValue = (index: number): unknown => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return undefined;\n\t\treturn args.rowData[key];\n\t};\n\n\tconst readNum = (index: number): number => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return 0;\n\t\treturn parseNumber(args.rowData[key]);\n\t};\n\n\treturn {\n\t\trowData: args.rowData,\n\t\trawValue: args.rawValue,\n\t\tcolumnId: args.columnId,\n\t\tkey: readKey,\n\t\tvalue: readValue,\n\t\tnum: readNum\n\t};\n}\n","import type { RowBasedFormatterDefinition } from \"./types\";\n\nexport type RowBasedFormatterRegistry = Readonly<{\n\tlist: readonly RowBasedFormatterDefinition[];\n\tbyId: ReadonlyMap<string, RowBasedFormatterDefinition>;\n}>;\n\n/**\n * Создаёт реестр формул для подмены значения в групповой строке.\n */\nexport function createRowBasedFormatterRegistry(definitions: readonly RowBasedFormatterDefinition[]): RowBasedFormatterRegistry {\n\tconst byId = new Map<string, RowBasedFormatterDefinition>();\n\tconst list: RowBasedFormatterDefinition[] = [];\n\n\tfor (const definition of definitions) {\n\t\tconst normalizedId = definition.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tthrow new Error(\"Formula id для RowBasedFormatter не может быть пустым\");\n\t\t}\n\n\t\tif (byId.has(normalizedId)) {\n\t\t\tthrow new Error(`Найден дублирующийся formulaId в RowBasedFormatter: ${normalizedId}`);\n\t\t}\n\n\t\tconst normalizedDefinition: RowBasedFormatterDefinition = Object.freeze({\n\t\t\t...definition,\n\t\t\tid: normalizedId,\n\t\t\tname: definition.name.trim(),\n\t\t\tdescription: definition.description.trim()\n\t\t});\n\n\t\tbyId.set(normalizedId, normalizedDefinition);\n\t\tlist.push(normalizedDefinition);\n\t}\n\n\treturn Object.freeze({\n\t\tlist: Object.freeze(list),\n\t\tbyId\n\t});\n}\n\nlet rowBasedFormatterRegistry = createRowBasedFormatterRegistry([]);\n\n/**\n * Устанавливает реестр row-based форматтеров host-приложения.\n *\n * Pipeline использует этот реестр при валидации и компиляции formula-режима,\n * поэтому конфигурация должна завершиться до первого построения runtime.\n */\nexport function configureRowBasedFormatterRegistry(registry: RowBasedFormatterRegistry): void {\n\trowBasedFormatterRegistry = registry;\n}\n\n/**\n * Возвращает список доступных формул для групповой подмены.\n */\nexport function getRowBasedFormatterList(): readonly RowBasedFormatterDefinition[] {\n\treturn rowBasedFormatterRegistry.list;\n}\n\n/**\n * Возвращает формулу по id.\n */\nexport function getRowBasedFormatterById(formulaId: string | undefined): RowBasedFormatterDefinition | undefined {\n\tconst normalizedId = formulaId?.trim();\n\tif (!normalizedId) return undefined;\n\treturn rowBasedFormatterRegistry.byId.get(normalizedId);\n}\n","import { getNumberPreset } from \"../number\";\nimport { createRowBasedFormatterContext, getRowBasedFormatterById } from \"../rowBased\";\n\nimport type {\n\tFormattersPipelineConfig,\n\tFormattersPipelineEdge,\n\tFormattersPipelineGraph,\n\tFormattersPipelineNode,\n\tFormattersPipelinePlan,\n\tFormattersPipelineRowBasedOverrideFormulaConfig,\n\tFormattersPipelineStep\n} from \"./types\";\n\nexport type FormattersPipelineValidationCode =\n\t| \"config_not_defined\"\n\t| \"unsupported_version\"\n\t| \"graph_or_plan_required\"\n\t| \"node_id_duplicate\"\n\t| \"edge_id_duplicate\"\n\t| \"edge_node_not_found\"\n\t| \"source_count_invalid\"\n\t| \"sink_count_invalid\"\n\t| \"source_incoming_invalid\"\n\t| \"sink_outgoing_invalid\"\n\t| \"node_degree_invalid\"\n\t| \"path_broken\"\n\t| \"path_cycle_detected\"\n\t| \"path_disconnected_nodes\"\n\t| \"step_id_duplicate\"\n\t| \"step_resolve_value_state_multiple\"\n\t| \"step_typed_value_format_multiple\"\n\t| \"step_row_based_override_multiple\"\n\t| \"step_normalize_leading_zeros_multiple\"\n\t| \"step_typed_before_value_state\"\n\t| \"step_row_based_override_field_key_empty\"\n\t| \"step_row_based_override_formula_id_empty\"\n\t| \"step_row_based_override_formula_not_found\"\n\t| \"step_row_based_override_dependency_index_out_of_range\"\n\t| \"step_row_based_override_unused_dependencies\"\n\t| \"step_row_based_override_formula_does_not_use_dependencies\"\n\t| \"step_row_based_override_formula_runtime_error\"\n\t| \"step_threshold_states_count_invalid\"\n\t| \"step_value_hidden_without_icon\"\n\t| \"step_typed_value_format_preset_empty\"\n\t| \"step_typed_value_format_preset_not_found\";\n\nexport type FormattersPipelineValidationMessage = {\n\tcode: FormattersPipelineValidationCode;\n\tmessage: string;\n};\n\nexport type FormattersPipelineValidationResult = {\n\tok: boolean;\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n\tplan?: FormattersPipelinePlan;\n};\n\ntype MutableValidationState = {\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n};\n\nfunction pushError(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.errors.push({ code, message });\n}\n\nfunction pushWarning(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.warnings.push({ code, message });\n}\n\nfunction toSortedArray(items: Set<number>): number[] {\n\treturn [...items].sort((left, right) => left - right);\n}\n\nfunction createSampleRowData(dependencies: readonly string[], multiplier: number): Record<string, unknown> {\n\treturn dependencies.reduce<Record<string, unknown>>((acc, dependencyId, index) => {\n\t\tacc[dependencyId] = (index + 1) * multiplier;\n\t\treturn acc;\n\t}, {});\n}\n\nfunction validateRowBasedOverrideFormulaConfig(config: FormattersPipelineRowBasedOverrideFormulaConfig, state: MutableValidationState) {\n\tif (!config.formulaId.trim()) {\n\t\tpushError(state, \"step_row_based_override_formula_id_empty\", \"Для rowBasedOverride (formula) необходимо заполнить formulaId.\");\n\t\treturn;\n\t}\n\n\tconst formula = getRowBasedFormatterById(config.formulaId);\n\tconst dependencies = [...(config.dependencyIds ?? [])];\n\n\tif (!formula) {\n\t\tpushError(state, \"step_row_based_override_formula_not_found\", \"Формула rowBasedOverride не найдена в реестре.\");\n\t\treturn;\n\t}\n\n\tconst usedIndexes = new Set<number>();\n\tconst outOfRangeIndexes = new Set<number>();\n\tlet runtimeErrorCount = 0;\n\n\tconst runValidationPass = (sampleRowData: Record<string, unknown>) => {\n\t\ttry {\n\t\t\tconst context = createRowBasedFormatterContext({\n\t\t\t\trowData: sampleRowData,\n\t\t\t\trawValue: 100,\n\t\t\t\tcolumnId: \"__validation__\",\n\t\t\t\tkeys: dependencies,\n\t\t\t\tinstrumentation: {\n\t\t\t\t\tonReadIndex: (index) => {\n\t\t\t\t\t\tusedIndexes.add(index);\n\t\t\t\t\t},\n\t\t\t\t\tonOutOfRangeIndex: (index) => {\n\t\t\t\t\t\toutOfRangeIndexes.add(index);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tformula.fn(context);\n\t\t} catch {\n\t\t\truntimeErrorCount += 1;\n\t\t}\n\t};\n\n\t// Несколько прогонов повышают шанс увидеть обращения к индексам в разных ветках формулы.\n\trunValidationPass(createSampleRowData(dependencies, 100));\n\trunValidationPass(createSampleRowData(dependencies, -100));\n\n\tconst sortedUsedIndexes = toSortedArray(usedIndexes);\n\tconst requiredDependencyCount = sortedUsedIndexes.length > 0 ? sortedUsedIndexes[sortedUsedIndexes.length - 1] + 1 : 0;\n\n\tif (outOfRangeIndexes.size > 0) {\n\t\tpushError(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_dependency_index_out_of_range\",\n\t\t\t`Формула rowBasedOverride обращается к несуществующим индексам. Минимально требуется зависимостей: ${requiredDependencyCount}, выбрано: ${dependencies.length}.`\n\t\t);\n\t}\n\n\tif (sortedUsedIndexes.length === 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_does_not_use_dependencies\",\n\t\t\t\"Формула rowBasedOverride не использует dependencyIds.\"\n\t\t);\n\t}\n\n\tconst unusedDependencies = dependencies.filter((_, index) => !usedIndexes.has(index));\n\tif (unusedDependencies.length > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_unused_dependencies\",\n\t\t\t`Выбраны, но не используются формулой rowBasedOverride: ${unusedDependencies.join(\", \")}.`\n\t\t);\n\t}\n\n\tif (runtimeErrorCount > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_runtime_error\",\n\t\t\t\"На тестовых данных формула rowBasedOverride завершилась с ошибкой.\"\n\t\t);\n\t}\n}\n\nfunction validateStepDefinitions(steps: readonly FormattersPipelineStep[], state: MutableValidationState) {\n\tconst stepIdSet = new Set<string>();\n\tconst counters = {\n\t\tnormalizeLeadingZeros: 0,\n\t\trowBasedOverride: 0,\n\t\tresolveValueState: 0,\n\t\ttypedValueFormat: 0\n\t};\n\n\tfor (const step of steps) {\n\t\tconst normalizedId = step.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"step_id_duplicate\", \"Шаг pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (stepIdSet.has(normalizedId)) {\n\t\t\tpushError(state, \"step_id_duplicate\", `Найден дублирующийся id шага pipeline: ${normalizedId}.`);\n\t\t}\n\t\tstepIdSet.add(normalizedId);\n\n\t\tswitch (step.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tcounters.normalizeLeadingZeros += 1;\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tcounters.rowBasedOverride += 1;\n\n\t\t\t\tif (step.config.mode === \"field\" && !step.config.fieldKey.trim()) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_row_based_override_field_key_empty\",\n\t\t\t\t\t\t\"Для rowBasedOverride (field) необходимо заполнить fieldKey.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (step.config.mode === \"formula\") {\n\t\t\t\t\tvalidateRowBasedOverrideFormulaConfig(step.config, state);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tcounters.resolveValueState += 1;\n\n\t\t\t\tif (\n\t\t\t\t\tstep.config.resolver.kind === \"threshold\" &&\n\t\t\t\t\tstep.config.resolver.states.length !== step.config.resolver.thresholds.length + 1\n\t\t\t\t) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_threshold_states_count_invalid\",\n\t\t\t\t\t\t\"Для threshold-резолвера количество states должно быть равно thresholds + 1.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tcounters.typedValueFormat += 1;\n\t\t\t\tif (step.config?.numberPresetName !== undefined) {\n\t\t\t\t\tconst normalizedPresetName = step.config.numberPresetName.trim();\n\t\t\t\t\tif (!normalizedPresetName) {\n\t\t\t\t\t\tpushError(state, \"step_typed_value_format_preset_empty\", \"Для typedValueFormat указан пустой numberPresetName.\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!getNumberPreset(normalizedPresetName)) {\n\t\t\t\t\t\tpushError(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\t\"step_typed_value_format_preset_not_found\",\n\t\t\t\t\t\t\t`Для typedValueFormat указан неизвестный пресет: ${normalizedPresetName}.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (counters.normalizeLeadingZeros > 1) {\n\t\tpushError(state, \"step_normalize_leading_zeros_multiple\", \"В pipeline может быть только один шаг normalizeLeadingZeros.\");\n\t}\n\n\tif (counters.rowBasedOverride > 1) {\n\t\tpushError(state, \"step_row_based_override_multiple\", \"В pipeline может быть только один шаг rowBasedOverride.\");\n\t}\n\n\tif (counters.resolveValueState > 1) {\n\t\tpushError(state, \"step_resolve_value_state_multiple\", \"В pipeline может быть только один шаг resolveValueState.\");\n\t}\n\n\tif (counters.typedValueFormat > 1) {\n\t\tpushError(state, \"step_typed_value_format_multiple\", \"В pipeline может быть только один шаг typedValueFormat.\");\n\t}\n\n\tconst resolveIndex = steps.findIndex((step) => step.type === \"resolveValueState\");\n\tconst typedIndex = steps.findIndex((step) => step.type === \"typedValueFormat\");\n\tif (resolveIndex !== -1 && typedIndex !== -1 && typedIndex < resolveIndex) {\n\t\tpushError(state, \"step_typed_before_value_state\", \"Шаг typedValueFormat не может выполняться до шага resolveValueState.\");\n\t}\n\n\tfor (const step of steps) {\n\t\tif (step.type !== \"resolveValueState\") continue;\n\t\tif (!step.config.icon?.enabled && step.config.icon?.showValue === false) {\n\t\t\tpushWarning(\n\t\t\t\tstate,\n\t\t\t\t\"step_value_hidden_without_icon\",\n\t\t\t\t\"Для resolveValueState установлено showValue=false при выключенной иконке: значение не будет отображаться.\"\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Валидация облегчённого плана pipeline.\n */\nexport function validateFormattersPipelinePlan(plan: FormattersPipelinePlan): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tvalidateStepDefinitions(plan.steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps: [...plan.steps] } : undefined\n\t};\n}\n\nfunction buildLinearPathFromGraph(\n\tnodes: readonly FormattersPipelineNode[],\n\tedges: readonly FormattersPipelineEdge[],\n\tstate: MutableValidationState\n): string[] | undefined {\n\tconst nodeById = new Map(nodes.map((node) => [node.id, node]));\n\tconst outgoing = new Map<string, string[]>();\n\tconst incoming = new Map<string, string[]>();\n\n\tfor (const node of nodes) {\n\t\toutgoing.set(node.id, []);\n\t\tincoming.set(node.id, []);\n\t}\n\n\tfor (const edge of edges) {\n\t\tconst source = edge.source.trim();\n\t\tconst target = edge.target.trim();\n\t\tif (!nodeById.has(source) || !nodeById.has(target)) {\n\t\t\tpushError(state, \"edge_node_not_found\", `Ребро ${edge.id} ссылается на несуществующий узел: ${source} -> ${target}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\toutgoing.get(source)?.push(target);\n\t\tincoming.get(target)?.push(source);\n\t}\n\n\tconst sources = nodes.filter((node) => node.type === \"source\");\n\tconst sinks = nodes.filter((node) => node.type === \"sink\");\n\n\tif (sources.length !== 1) {\n\t\tpushError(state, \"source_count_invalid\", \"В графе должен быть ровно один узел source.\");\n\t}\n\tif (sinks.length !== 1) {\n\t\tpushError(state, \"sink_count_invalid\", \"В графе должен быть ровно один узел sink.\");\n\t}\n\tif (state.errors.length > 0) return undefined;\n\n\tconst sourceNodeId = sources[0]!.id;\n\tconst sinkNodeId = sinks[0]!.id;\n\n\tfor (const node of nodes) {\n\t\tconst inDegree = incoming.get(node.id)?.length ?? 0;\n\t\tconst outDegree = outgoing.get(node.id)?.length ?? 0;\n\n\t\tif (node.type === \"source\") {\n\t\t\tif (inDegree !== 0) {\n\t\t\t\tpushError(state, \"source_incoming_invalid\", \"Узел source не должен иметь входящих рёбер.\");\n\t\t\t}\n\t\t\tif (outDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел source должен иметь ровно одно исходящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (node.type === \"sink\") {\n\t\t\tif (outDegree !== 0) {\n\t\t\t\tpushError(state, \"sink_outgoing_invalid\", \"Узел sink не должен иметь исходящих рёбер.\");\n\t\t\t}\n\t\t\tif (inDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел sink должен иметь ровно одно входящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inDegree !== 1 || outDegree !== 1) {\n\t\t\tpushError(\n\t\t\t\tstate,\n\t\t\t\t\"node_degree_invalid\",\n\t\t\t\t`Узел ${node.id} должен иметь ровно одно входящее и одно исходящее ребро для линейного pipeline.`\n\t\t\t);\n\t\t}\n\t}\n\n\tif (state.errors.length > 0) return undefined;\n\n\tconst visited = new Set<string>();\n\tconst path: string[] = [];\n\tlet cursor = sourceNodeId;\n\n\twhile (true) {\n\t\tif (visited.has(cursor)) {\n\t\t\tpushError(state, \"path_cycle_detected\", \"В графе pipeline обнаружен цикл.\");\n\t\t\treturn undefined;\n\t\t}\n\t\tvisited.add(cursor);\n\t\tpath.push(cursor);\n\n\t\tif (cursor === sinkNodeId) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst nextCandidates = outgoing.get(cursor) ?? [];\n\t\tif (nextCandidates.length !== 1) {\n\t\t\tpushError(state, \"path_broken\", \"Не удалось построить линейный путь от source к sink.\");\n\t\t\treturn undefined;\n\t\t}\n\n\t\tcursor = nextCandidates[0]!;\n\t}\n\n\tif (visited.size !== nodes.length) {\n\t\tpushError(state, \"path_disconnected_nodes\", \"Граф содержит узлы, которые не входят в линейный путь source -> sink.\");\n\t\treturn undefined;\n\t}\n\n\treturn path;\n}\n\n/**\n * Валидация графа pipeline и построение линейного плана исполнения.\n */\nexport function validateFormattersPipelineGraph(graph: FormattersPipelineGraph): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!graph.nodes.length) {\n\t\tpushError(state, \"path_broken\", \"Граф pipeline не содержит узлов.\");\n\t\treturn { ok: false, errors: state.errors, warnings: state.warnings };\n\t}\n\n\tconst nodeById = new Map<string, FormattersPipelineNode>();\n\tfor (const node of graph.nodes) {\n\t\tconst normalizedId = node.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"node_id_duplicate\", \"Узел pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nodeById.has(normalizedId)) {\n\t\t\tpushError(state, \"node_id_duplicate\", `Найден дублирующийся id узла pipeline: ${normalizedId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tnodeById.set(normalizedId, node);\n\t}\n\n\tconst edgeIdSet = new Set<string>();\n\tfor (const edge of graph.edges) {\n\t\tconst normalizedEdgeId = edge.id.trim();\n\t\tif (!normalizedEdgeId) {\n\t\t\tpushError(state, \"edge_id_duplicate\", \"Ребро pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (edgeIdSet.has(normalizedEdgeId)) {\n\t\t\tpushError(state, \"edge_id_duplicate\", `Найден дублирующийся id ребра pipeline: ${normalizedEdgeId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tedgeIdSet.add(normalizedEdgeId);\n\t}\n\n\tif (state.errors.length > 0) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst path = buildLinearPathFromGraph(graph.nodes, graph.edges, state);\n\tif (!path) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst steps: FormattersPipelineStep[] = [];\n\tfor (const nodeId of path) {\n\t\tconst node = nodeById.get(nodeId);\n\t\tif (!node || node.type === \"source\" || node.type === \"sink\") continue;\n\n\t\tswitch (node.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"normalizeLeadingZeros\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"rowBasedOverride\",\n\t\t\t\t\tconfig:\n\t\t\t\t\t\tnode.config.mode === \"formula\"\n\t\t\t\t\t\t\t? { ...node.config, dependencyIds: node.config.dependencyIds ? [...node.config.dependencyIds] : undefined }\n\t\t\t\t\t\t\t: { ...node.config }\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"resolveValueState\",\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tresolver:\n\t\t\t\t\t\t\tnode.config.resolver.kind === \"fixed\"\n\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\tkind: \"fixed\",\n\t\t\t\t\t\t\t\t\t\tentries: { ...node.config.resolver.entries },\n\t\t\t\t\t\t\t\t\t\tfallbackState: node.config.resolver.fallbackState\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\tkind: \"threshold\",\n\t\t\t\t\t\t\t\t\t\tthresholds: node.config.resolver.thresholds.map((item) =>\n\t\t\t\t\t\t\t\t\t\t\ttypeof item === \"number\" ? item : { ...item }\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tstates: [...node.config.resolver.states],\n\t\t\t\t\t\t\t\t\t\tinvalidState: node.config.resolver.invalidState\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\ticon: node.config.icon ? { ...node.config.icon } : undefined\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"typedValueFormat\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tvalidateStepDefinitions(steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps } : undefined\n\t};\n}\n\n/**\n * Валидация конфигурации pipeline c выбором рабочего плана исполнения.\n *\n * Приоритет источника плана:\n * 1) `plan` из конфигурации;\n * 2) построение плана из `graph`.\n */\nexport function validateFormattersPipelineConfig(config: FormattersPipelineConfig | undefined): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!config) {\n\t\tpushError(state, \"config_not_defined\", \"Конфигурация pipeline не задана.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.version !== 1) {\n\t\tpushError(state, \"unsupported_version\", `Неподдерживаемая версия pipeline: ${String(config.version)}.`);\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (!config.plan && !config.graph) {\n\t\tpushError(state, \"graph_or_plan_required\", \"Для pipeline должен быть задан хотя бы один источник: graph или plan.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.plan) {\n\t\tconst planResult = validateFormattersPipelinePlan(config.plan);\n\t\tstate.errors.push(...planResult.errors);\n\t\tstate.warnings.push(...planResult.warnings);\n\n\t\tif (planResult.ok && planResult.plan) {\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings,\n\t\t\t\tplan: planResult.plan\n\t\t\t};\n\t\t}\n\n\t\tif (config.graph) {\n\t\t\tpushWarning(state, \"path_broken\", \"Линейный plan невалиден. Выполнена попытка построить план из graph.\");\n\t\t\tstate.errors.length = 0;\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings\n\t\t\t};\n\t\t}\n\t}\n\n\tif (config.graph) {\n\t\tconst graphResult = validateFormattersPipelineGraph(config.graph);\n\t\treturn {\n\t\t\tok: graphResult.ok,\n\t\t\terrors: [...state.errors, ...graphResult.errors],\n\t\t\twarnings: [...state.warnings, ...graphResult.warnings],\n\t\t\tplan: graphResult.plan\n\t\t};\n\t}\n\n\treturn {\n\t\tok: false,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings\n\t};\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { _ as e } from "../chunks/array-BBSjoTRy.js";
2
- import { qt as t } from "../chunks/formatters-CEsXVZ7n.js";
2
+ import { qt as t } from "../chunks/formatters--mhLir82.js";
3
3
  import { stableStringify as n } from "../utils/index.js";
4
4
  import { hashString128 as r, uuidv4 as i } from "../crypto/index.js";
5
- import { x as a } from "../chunks/dateUtils-BWIaWh13.js";
5
+ import { x as a } from "../chunks/dateUtils-B5V5aXB-.js";
6
6
  import { createIndexedDbQueryStorage as o } from "../query-client/index.js";
7
7
  import { getSessionStorageId as s } from "../session-storage/index.js";
8
8
  //#region src/error-report/safeValue.ts
@@ -1,6 +1,6 @@
1
- import { c as e, l as t, s as n, u as r } from "../chunks/odata-service-D8oFjUah.js";
2
- import { F as i, I as a, k as o } from "../chunks/dateUtils-BWIaWh13.js";
3
- import { d as s, t as c } from "../chunks/validate-DrKdjesg.js";
1
+ import { c as e, l as t, s as n, u as r } from "../chunks/odata-service-DnPlNGpU.js";
2
+ import { L as i, R as a, k as o } from "../chunks/dateUtils-B5V5aXB-.js";
3
+ import { d as s, t as c } from "../chunks/validate-nWY_Mla5.js";
4
4
  import l from "write-excel-file/browser";
5
5
  //#region src/excel/excel.ts
6
6
  var u = {
@@ -3,7 +3,7 @@ export { getCalendarPeriod, isCalendarPeriodWithinDateBounds, isDateInsideCalend
3
3
  export * from "./dateRange";
4
4
  export * from "./educationDate";
5
5
  export { formatDate, formatDateAsAbapDate, formatDateAsAbapDatetime, formatDateAsAbapMonth, formatDateAsAbapYear, formatDateAsDate, formatDateAsDateLong, formatDateAsDateMedium, formatDateAsDateShort, formatDateAsDateTime, formatDateAsDatetimeLong, formatDateAsDatetimeMedium, formatDateAsDatetimeShort, formatDateAsMonthShort, formatDateAsMonthMedium, formatDateAsMonthLong, formatDateAsMonthYearMedium, formatDateAsMonthYearLong, formatDateAsODataDate, formatDateAsODataDatetime, formatDateAsODataTime, formatDateAsTime, formatDateAsTimeLong, formatDateAsTimeMedium, formatDateAsTimeSeconds, formatDateAsTimeShort, formatDateRange } from "./formatDate";
6
- export { parseDate, parseDateByFormat, parseDateByPattern, parseDateValue } from "./parseDate";
6
+ export { parseDate, parseDateByFormat, parseDateByPattern, parseDateTZ, parseDateValue, parseDateValueTZ } from "./parseDate";
7
7
  export type { ParseDateByFormatOptions, ParseDateByPatternOptions } from "./parseDate";
8
8
  export { DATE_PATTERN_DATE_TOKENS, DATE_PATTERN_TIME_TOKENS, DATE_PATTERN_TOKEN_RE, DATE_PATTERN_TOKENS } from "./pattern";
9
9
  export { DATE_FORMAT_DEFAULTS, DATE_FORMAT_STYLE_PRESET_NAMES, DEFAULT_DATE_PRESET_NAMES, getDatePreset, getDatePresetNames, isDateFormatPrecision, isDateFormatStyle, registerDatePreset, resetDatePresets, resolveDateFormatName, resolveDateFormatPreset } from "./presets";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/formatters/date/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,iBAAiB,EACjB,gCAAgC,EAChC,0BAA0B,EAC1B,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACN,UAAU,EACV,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,eAAe,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/F,YAAY,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC3H,OAAO,EACN,oBAAoB,EACpB,8BAA8B,EAC9B,yBAAyB,EACzB,aAAa,EACb,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,8BAA8B,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EACN,+BAA+B,EAC/B,oBAAoB,EACpB,6BAA6B,EAC7B,iCAAiC,EACjC,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClE,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/formatters/date/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,iBAAiB,EACjB,gCAAgC,EAChC,0BAA0B,EAC1B,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,EACvB,MAAM,kBAAkB,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACN,UAAU,EACV,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,eAAe,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9H,YAAY,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC3H,OAAO,EACN,oBAAoB,EACpB,8BAA8B,EAC9B,yBAAyB,EACzB,aAAa,EACb,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,8BAA8B,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EACN,+BAA+B,EAC/B,oBAAoB,EACpB,6BAA6B,EAC7B,iCAAiC,EACjC,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClE,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,MAAM,SAAS,CAAC"}
@@ -34,11 +34,23 @@ export interface ParseDateByFormatOptions {
34
34
  */
35
35
  export declare function parseDateByFormat(value: unknown, dateFormat?: string, options?: ParseDateByFormatOptions): ParsedDateTimeValue | null;
36
36
  /**
37
- * Универсально парсит вход даты/времени из `unknown`.
37
+ * Универсально парсит вход даты/времени из `unknown`, сохраняя исторические
38
+ * видимые календарные компоненты без применения timezone.
38
39
  */
39
40
  export declare function parseDateValue(value: unknown): ParsedDateValue | null;
41
+ /**
42
+ * Универсально парсит вход даты/времени из `unknown` как абсолютный instant.
43
+ *
44
+ * Явные timezone в ISO/OData и Unix timestamp преобразуются в `Date`
45
+ * с сохранением момента времени; форматы без timezone остаются календарными.
46
+ */
47
+ export declare function parseDateValueTZ(value: unknown): ParsedDateValue | null;
40
48
  /**
41
49
  * Универсально парсит вход и всегда возвращает `Date | null`.
42
50
  */
43
51
  export declare function parseDate(value: unknown): Date | null;
52
+ /**
53
+ * Универсально парсит вход с учётом timezone и возвращает `Date | null`.
54
+ */
55
+ export declare function parseDateTZ(value: unknown): Date | null;
44
56
  //# sourceMappingURL=parseDate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseDate.d.ts","sourceRoot":"","sources":["../../../src/formatters/date/parseDate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAsiB5G;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;CAChC;AAED,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,SAAe,EACtB,OAAO,GAAE,yBAA8B,GACrC,eAAe,GAAG,IAAI,CA8DxB;AAED,MAAM,WAAW,wBAAwB;IACxC;;OAEG;IACH,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC;;OAEG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC;CACrB;AAgBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,wBAA6B,GAAG,mBAAmB,GAAG,IAAI,CAkCzI;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CA2BrE;AAkBD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAErD"}
1
+ {"version":3,"file":"parseDate.d.ts","sourceRoot":"","sources":["../../../src/formatters/date/parseDate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA2mB5G;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;CAChC;AAED,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,OAAO,EACd,OAAO,SAAe,EACtB,OAAO,GAAE,yBAA8B,GACrC,eAAe,GAAG,IAAI,CA8DxB;AAED,MAAM,WAAW,wBAAwB;IACxC;;OAEG;IACH,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC;;OAEG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC;CACrB;AAgBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,wBAA6B,GAAG,mBAAmB,GAAG,IAAI,CAkCzI;AAsCD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAEvE;AAkBD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAErD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAEvD"}
@@ -1,6 +1,6 @@
1
1
  import { _ as e, b as t, g as n, v as r, x as i, y as a } from "../chunks/array-BBSjoTRy.js";
2
- import { $ as o, A as s, At as c, B as l, Bt as u, C as d, Ct as f, D as p, Dt as m, E as h, Et as g, F as _, Ft as v, G as y, Gt as b, H as x, Ht as S, I as C, It as w, J as T, Jt as E, K as D, Kt as O, L as k, Lt as A, M as j, Mt as M, N, Nt as P, O as F, Ot as I, P as L, Pt as R, Q as z, R as B, Rt as V, S as H, St as U, T as W, Tt as G, U as K, Ut as q, V as J, Vt as Y, W as X, Wt as Z, X as Q, Xt as $, Y as ee, Yt as te, Z as ne, _ as re, _t as ie, a as ae, at as oe, b as se, bt as ce, c as le, ct as ue, d as de, dt as fe, et as pe, f as me, ft as he, g as ge, gt as _e, h as ve, ht as ye, i as be, it as xe, j as Se, jt as Ce, k as we, kt as Te, l as Ee, lt as De, m as Oe, mt as ke, n as Ae, nt as je, o as Me, ot as Ne, p as Pe, pt as Fe, q as Ie, qt as Le, r as Re, rt as ze, s as Be, st as Ve, t as He, tt as Ue, u as We, ut as Ge, v as Ke, vt as qe, w as Je, wt as Ye, x as Xe, xt as Ze, y as Qe, yt as $e, z as et, zt as tt } from "../chunks/formatters-CEsXVZ7n.js";
3
- import { Ft as nt, It as rt, Mt as it, Nt as at, Pt as ot, jt as st } from "../chunks/odata-service-D8oFjUah.js";
4
- import { A as ct, B as lt, C as ut, D as dt, E as ft, F as pt, G as mt, H as ht, I as gt, K as _t, L as vt, M as yt, N as bt, O as xt, P as St, R as Ct, S as wt, T as Tt, U as Et, V as Dt, W as Ot, _ as kt, a as At, b as jt, c as Mt, d as Nt, f as Pt, g as Ft, h as It, i as Lt, j as Rt, k as zt, l as Bt, m as Vt, n as Ht, o as Ut, p as Wt, q as Gt, r as Kt, s as qt, u as Jt, v as Yt, w as Xt, x as Zt, y as Qt, z as $t } from "../chunks/dateUtils-BWIaWh13.js";
5
- import { a as en, c as tn, d as nn, f as rn, i as an, l as on, m as sn, n as cn, o as ln, p as un, r as dn, s as fn, t as pn, u as mn } from "../chunks/validate-DrKdjesg.js";
6
- export { bt as DATE_FORMAT_DEFAULTS, St as DATE_FORMAT_STYLE_PRESET_NAMES, Ot as DATE_PATTERN_DATE_TOKENS, mt as DATE_PATTERN_TIME_TOKENS, _t as DATE_PATTERN_TOKENS, Gt as DATE_PATTERN_TOKEN_RE, pt as DEFAULT_DATE_PRESET_NAMES, on as DEFAULT_NUMBER_PRESET_NAMES, Ae as DEFAULT_VALUE_STATES, mn as NUMBER_FORMAT_DEFAULTS, Re as VALUE_STATE_COLOR_TOKENS, M as addCalendarDays, P as addCalendarMonths, R as addCalendarYears, _ as clearFormatCache, S as clearPhone, Ze as cloneDate, h as cloneFormatterPipelinePlanStep, p as cloneFormatterPipelinePlanStepToNode, F as cloneFormattersPipelineConfig, we as cloneNormalizeLeadingZerosConfig, s as cloneResolveValueStateConfig, Se as cloneRowBasedOverrideConfig, j as cloneTypedValueFormatConfig, Je as collectFormattersPipelineDependencyIds, W as collectRuntimeFieldDependencyIds, de as compileFormattersPipelineExecutor, be as compileFormattersPipelineRuntime, ae as compileFormattersPipelineRuntimeFields, re as computeShortHash, an as configureRowBasedFormatterRegistry, U as countCalendarDaysInDateRange, v as createCalendarDate, Ve as createEducationDateTime, ve as createFixedResolver, tn as createRowBasedFormatterContext, en as createRowBasedFormatterRegistry, Pe as createThresholdResolver, Ke as findResolverByCanonicalKey, Ht as formatDate, Kt as formatDateAsAbapDate, Lt as formatDateAsAbapDatetime, At as formatDateAsAbapMonth, Ut as formatDateAsAbapYear, qt as formatDateAsDate, Mt as formatDateAsDateLong, Bt as formatDateAsDateMedium, Jt as formatDateAsDateShort, Nt as formatDateAsDateTime, Pt as formatDateAsDatetimeLong, Wt as formatDateAsDatetimeMedium, Vt as formatDateAsDatetimeShort, It as formatDateAsMonthLong, Ft as formatDateAsMonthMedium, kt as formatDateAsMonthShort, Yt as formatDateAsMonthYearLong, Qt as formatDateAsMonthYearMedium, jt as formatDateAsODataDate, Zt as formatDateAsODataDatetime, wt as formatDateAsODataTime, ut as formatDateAsTime, Xt as formatDateAsTimeLong, Tt as formatDateAsTimeMedium, ft as formatDateAsTimeSeconds, dt as formatDateAsTimeShort, xt as formatDateRange, ue as formatEducationDateKey, De as formatEducationTimeKey, Z as formatFullName, C as formatNumber, k as formatNumberAsCurrency, B as formatNumberAsCurrencyOrEmpty, et as formatNumberAsDecimal, l as formatNumberAsDecimal2, J as formatNumberAsDecimal2OrEmpty, x as formatNumberAsDecimal3, K as formatNumberAsDecimal3OrEmpty, X as formatNumberAsDecimalOrEmpty, y as formatNumberAsInteger, D as formatNumberAsIntegerOrEmpty, Ie as formatNumberAsPercent, T as formatNumberAsPercentOrEmpty, ee as formatNumberAsPrice, Q as formatNumberAsPriceOrEmpty, ne as formatNumberAsTonnage, z as formatNumberAsTonnageOrEmpty, q as formatPhone, Me as formatPipelineDisplayValue, b as formatShortName, me as formatTypedCellValue, Te as getCalendarPeriod, Ge as getCurrentEducationWeekKey, gt as getDatePreset, vt as getDatePresetNames, fe as getEducationWeekDays, he as getEducationWeekRange, Fe as getEducationWeekStartDate, ke as getEducationYear, ye as getEducationYearRange, w as getEndOfDay, le as getFormattersPipelineDefinitionById, Ee as getFormattersPipelineDefinitions, nn as getNumberPreset, rn as getNumberPresetNames, ln as getRowBasedFormatterById, fn as getRowBasedFormatterList, A as getStartOfDay, V as getStartOfMonth, tt as getStartOfWeek, u as getStartOfYear, Qe as getValueStateResolver, se as getValueStateResolverIds, c as isCalendarPeriodWithinDateBounds, _e as isCurrentEducationWeek, Ct as isDateFormatPrecision, $t as isDateFormatStyle, Ce as isDateInsideCalendarPeriod, f as isDateRangeTuple, ie as isEducationDateInCurrentYear, st as isPositiveValue, Y as isSameCalendarDay, Ye as isValidDate, pe as isZeroValue, G as normalizeDateRange, Ue as normalizeDateRangeReferenceDate, qe as normalizeEducationWeekKey, We as normalizeFormattersPipelineConfig, N as normalizeLeadingZeros, L as normalizeLeadingZerosStrict, n as normalizeRequiredText, e as normalizeText, r as normalizeTextSpaces, a as normalizeTextToLower, t as normalizeTextWithFallback, g as orderDates, nt as parseAbapBoolean, rt as parseBoolean, zt as parseDate, ct as parseDateByFormat, Rt as parseDateByPattern, yt as parseDateValue, $e as parseEducationDateKey, it as parseNumber, lt as registerDatePreset, ge as registerFixedResolver, un as registerNumberPreset, Xe as registerResolver, Oe as registerThresholdResolver, Be as rekeyFormattersPipelineConfig, m as requireDateRange, Dt as resetDatePresets, sn as resetNumberPresets, H as resetValueStateResolvers, ht as resolveDateFormatName, Et as resolveDateFormatPreset, I as resolveDateRangePair, ce as resolveEducationWeekKey, je as resolveMonthAgoRange, ze as resolveMonthStartToTodayRange, xe as resolveMonthStartToYesterdayRange, oe as resolveTodayRange, d as resolveValueState, He as resolveValueStateClassName, Ne as resolveYesterdayRange, $ as startsWithIgnoringZeros, te as stripInnerSpaces, E as stripLeadingZeros, O as toAbapBoolean, at as toFiniteNumber, ot as toPositiveInteger, i as toSafeString, o as truncateNumber, Le as truncateText, pn as validateFormattersPipelineConfig, cn as validateFormattersPipelineGraph, dn as validateFormattersPipelinePlan };
2
+ import { $ as o, A as s, At as c, B as l, Bt as u, C as d, Ct as f, D as p, Dt as m, E as h, Et as g, F as _, Ft as v, G as y, Gt as b, H as x, Ht as S, I as C, It as w, J as T, Jt as E, K as D, Kt as O, L as k, Lt as A, M as j, Mt as M, N, Nt as P, O as F, Ot as I, P as L, Pt as R, Q as z, R as B, Rt as V, S as H, St as U, T as W, Tt as G, U as K, Ut as q, V as J, Vt as Y, W as X, Wt as Z, X as Q, Xt as $, Y as ee, Yt as te, Z as ne, _ as re, _t as ie, a as ae, at as oe, b as se, bt as ce, c as le, ct as ue, d as de, dt as fe, et as pe, f as me, ft as he, g as ge, gt as _e, h as ve, ht as ye, i as be, it as xe, j as Se, jt as Ce, k as we, kt as Te, l as Ee, lt as De, m as Oe, mt as ke, n as Ae, nt as je, o as Me, ot as Ne, p as Pe, pt as Fe, q as Ie, qt as Le, r as Re, rt as ze, s as Be, st as Ve, t as He, tt as Ue, u as We, ut as Ge, v as Ke, vt as qe, w as Je, wt as Ye, x as Xe, xt as Ze, y as Qe, yt as $e, z as et, zt as tt } from "../chunks/formatters--mhLir82.js";
3
+ import { Ft as nt, It as rt, Mt as it, Nt as at, Pt as ot, jt as st } from "../chunks/odata-service-DnPlNGpU.js";
4
+ import { A as ct, B as lt, C as ut, D as dt, E as ft, F as pt, G as mt, H as ht, I as gt, J as _t, K as vt, L as yt, M as bt, N as xt, O as St, P as Ct, R as wt, S as Tt, T as Et, U as Dt, V as Ot, W as kt, Y as At, _ as jt, a as Mt, b as Nt, c as Pt, d as Ft, f as It, g as Lt, h as Rt, i as zt, j as Bt, k as Vt, l as Ht, m as Ut, n as Wt, o as Gt, p as Kt, q as qt, r as Jt, s as Yt, u as Xt, v as Zt, w as Qt, x as $t, y as en, z as tn } from "../chunks/dateUtils-B5V5aXB-.js";
5
+ import { a as nn, c as rn, d as an, f as on, i as sn, l as cn, m as ln, n as un, o as dn, p as fn, r as pn, s as mn, t as hn, u as gn } from "../chunks/validate-nWY_Mla5.js";
6
+ export { pt as DATE_FORMAT_DEFAULTS, gt as DATE_FORMAT_STYLE_PRESET_NAMES, vt as DATE_PATTERN_DATE_TOKENS, qt as DATE_PATTERN_TIME_TOKENS, _t as DATE_PATTERN_TOKENS, At as DATE_PATTERN_TOKEN_RE, yt as DEFAULT_DATE_PRESET_NAMES, cn as DEFAULT_NUMBER_PRESET_NAMES, Ae as DEFAULT_VALUE_STATES, gn as NUMBER_FORMAT_DEFAULTS, Re as VALUE_STATE_COLOR_TOKENS, M as addCalendarDays, P as addCalendarMonths, R as addCalendarYears, _ as clearFormatCache, S as clearPhone, Ze as cloneDate, h as cloneFormatterPipelinePlanStep, p as cloneFormatterPipelinePlanStepToNode, F as cloneFormattersPipelineConfig, we as cloneNormalizeLeadingZerosConfig, s as cloneResolveValueStateConfig, Se as cloneRowBasedOverrideConfig, j as cloneTypedValueFormatConfig, Je as collectFormattersPipelineDependencyIds, W as collectRuntimeFieldDependencyIds, de as compileFormattersPipelineExecutor, be as compileFormattersPipelineRuntime, ae as compileFormattersPipelineRuntimeFields, re as computeShortHash, sn as configureRowBasedFormatterRegistry, U as countCalendarDaysInDateRange, v as createCalendarDate, Ve as createEducationDateTime, ve as createFixedResolver, rn as createRowBasedFormatterContext, nn as createRowBasedFormatterRegistry, Pe as createThresholdResolver, Ke as findResolverByCanonicalKey, Wt as formatDate, Jt as formatDateAsAbapDate, zt as formatDateAsAbapDatetime, Mt as formatDateAsAbapMonth, Gt as formatDateAsAbapYear, Yt as formatDateAsDate, Pt as formatDateAsDateLong, Ht as formatDateAsDateMedium, Xt as formatDateAsDateShort, Ft as formatDateAsDateTime, It as formatDateAsDatetimeLong, Kt as formatDateAsDatetimeMedium, Ut as formatDateAsDatetimeShort, Rt as formatDateAsMonthLong, Lt as formatDateAsMonthMedium, jt as formatDateAsMonthShort, Zt as formatDateAsMonthYearLong, en as formatDateAsMonthYearMedium, Nt as formatDateAsODataDate, $t as formatDateAsODataDatetime, Tt as formatDateAsODataTime, ut as formatDateAsTime, Qt as formatDateAsTimeLong, Et as formatDateAsTimeMedium, ft as formatDateAsTimeSeconds, dt as formatDateAsTimeShort, St as formatDateRange, ue as formatEducationDateKey, De as formatEducationTimeKey, Z as formatFullName, C as formatNumber, k as formatNumberAsCurrency, B as formatNumberAsCurrencyOrEmpty, et as formatNumberAsDecimal, l as formatNumberAsDecimal2, J as formatNumberAsDecimal2OrEmpty, x as formatNumberAsDecimal3, K as formatNumberAsDecimal3OrEmpty, X as formatNumberAsDecimalOrEmpty, y as formatNumberAsInteger, D as formatNumberAsIntegerOrEmpty, Ie as formatNumberAsPercent, T as formatNumberAsPercentOrEmpty, ee as formatNumberAsPrice, Q as formatNumberAsPriceOrEmpty, ne as formatNumberAsTonnage, z as formatNumberAsTonnageOrEmpty, q as formatPhone, Me as formatPipelineDisplayValue, b as formatShortName, me as formatTypedCellValue, Te as getCalendarPeriod, Ge as getCurrentEducationWeekKey, wt as getDatePreset, tn as getDatePresetNames, fe as getEducationWeekDays, he as getEducationWeekRange, Fe as getEducationWeekStartDate, ke as getEducationYear, ye as getEducationYearRange, w as getEndOfDay, le as getFormattersPipelineDefinitionById, Ee as getFormattersPipelineDefinitions, an as getNumberPreset, on as getNumberPresetNames, dn as getRowBasedFormatterById, mn as getRowBasedFormatterList, A as getStartOfDay, V as getStartOfMonth, tt as getStartOfWeek, u as getStartOfYear, Qe as getValueStateResolver, se as getValueStateResolverIds, c as isCalendarPeriodWithinDateBounds, _e as isCurrentEducationWeek, lt as isDateFormatPrecision, Ot as isDateFormatStyle, Ce as isDateInsideCalendarPeriod, f as isDateRangeTuple, ie as isEducationDateInCurrentYear, st as isPositiveValue, Y as isSameCalendarDay, Ye as isValidDate, pe as isZeroValue, G as normalizeDateRange, Ue as normalizeDateRangeReferenceDate, qe as normalizeEducationWeekKey, We as normalizeFormattersPipelineConfig, N as normalizeLeadingZeros, L as normalizeLeadingZerosStrict, n as normalizeRequiredText, e as normalizeText, r as normalizeTextSpaces, a as normalizeTextToLower, t as normalizeTextWithFallback, g as orderDates, nt as parseAbapBoolean, rt as parseBoolean, Vt as parseDate, ct as parseDateByFormat, Bt as parseDateByPattern, bt as parseDateTZ, xt as parseDateValue, Ct as parseDateValueTZ, $e as parseEducationDateKey, it as parseNumber, ht as registerDatePreset, ge as registerFixedResolver, fn as registerNumberPreset, Xe as registerResolver, Oe as registerThresholdResolver, Be as rekeyFormattersPipelineConfig, m as requireDateRange, Dt as resetDatePresets, ln as resetNumberPresets, H as resetValueStateResolvers, kt as resolveDateFormatName, mt as resolveDateFormatPreset, I as resolveDateRangePair, ce as resolveEducationWeekKey, je as resolveMonthAgoRange, ze as resolveMonthStartToTodayRange, xe as resolveMonthStartToYesterdayRange, oe as resolveTodayRange, d as resolveValueState, He as resolveValueStateClassName, Ne as resolveYesterdayRange, $ as startsWithIgnoringZeros, te as stripInnerSpaces, E as stripLeadingZeros, O as toAbapBoolean, at as toFiniteNumber, ot as toPositiveInteger, i as toSafeString, o as truncateNumber, Le as truncateText, hn as validateFormattersPipelineConfig, un as validateFormattersPipelineGraph, pn as validateFormattersPipelinePlan };
@@ -1,4 +1,4 @@
1
- import { t as e } from "../chunks/dateUtils-BWIaWh13.js";
1
+ import { t as e } from "../chunks/dateUtils-B5V5aXB-.js";
2
2
  import { t } from "../chunks/string-comparison-BKT7PXmq.js";
3
3
  import { create as n } from "zustand";
4
4
  import { immer as r } from "zustand/middleware/immer";
@@ -1,2 +1,2 @@
1
- import { $ as e, A as t, At as n, B as r, C as i, Ct as a, D as o, Dt as s, E as c, Et as l, F as u, G as d, H as f, I as p, J as m, K as h, L as g, M as _, N as v, O as y, Ot as b, P as x, Q as S, R as C, S as w, St as T, T as E, Tt as D, U as O, V as k, W as A, X as j, Y as M, Z as N, _ as P, _t as F, a as I, at as L, b as R, bt as z, c as B, ct as V, d as H, dt as U, et as W, f as G, ft as K, g as q, gt as J, h as Y, ht as X, i as Z, it as Q, j as $, k as ee, kt as te, l as ne, lt as re, m as ie, mt as ae, n as oe, nt as se, o as ce, ot as le, p as ue, pt as de, q as fe, r as pe, rt as me, s as he, st as ge, t as _e, tt as ve, u as ye, ut as be, v as xe, vt as Se, w as Ce, wt as we, x as Te, xt as Ee, y as De, yt as Oe, z as ke } from "../chunks/odata-service-D8oFjUah.js";
1
+ import { $ as e, A as t, At as n, B as r, C as i, Ct as a, D as o, Dt as s, E as c, Et as l, F as u, G as d, H as f, I as p, J as m, K as h, L as g, M as _, N as v, O as y, Ot as b, P as x, Q as S, R as C, S as w, St as T, T as E, Tt as D, U as O, V as k, W as A, X as j, Y as M, Z as N, _ as P, _t as F, a as I, at as L, b as R, bt as z, c as B, ct as V, d as H, dt as U, et as W, f as G, ft as K, g as q, gt as J, h as Y, ht as X, i as Z, it as Q, j as $, k as ee, kt as te, l as ne, lt as re, m as ie, mt as ae, n as oe, nt as se, o as ce, ot as le, p as ue, pt as de, q as fe, r as pe, rt as me, s as he, st as ge, t as _e, tt as ve, u as ye, ut as be, v as xe, vt as Se, w as Ce, wt as we, x as Te, xt as Ee, y as De, yt as Oe, z as ke } from "../chunks/odata-service-DnPlNGpU.js";
2
2
  export { s as BASE_META_TYPES, b as BASE_META_TYPE_LABELS, k as FILTER_OPERATIONS, i as FORCED_CODE_TEXT_IDS, f as FilterOperation, H as assertSqlFilterFieldId, ve as buildEntityOperationPath, se as buildEntityParameters, me as buildEntityPath, Q as buildFunctionImportParameters, L as buildFunctionImportPath, O as buildODataFilter, A as buildODataFilterRecursive, P as buildODataOrder, xe as buildODataOrderBy, le as buildParameterEntries, G as buildSqlFilter, y as collapseChainedODataSegmentFilterValues, e as collectFilterableColumns, W as collectFilterableColumnsIds, ee as compileFiltersToExpression, ge as createBooleanFormatter, V as createDateFormatter, d as createFilter, h as createFilterBetween, fe as createFilterContains, m as createFilterEqual, M as createFilterEqualFalsy, re as createFormatter, be as createNumberFormatter, ue as createSqlFilterEqual, ie as createSqlFilterGroup, Y as createSqlFilterIn, U as createStringFormatter, K as defaultControlTypeValue, de as defaultODataTypeValue, t as flattenFilterValuesToODataDependencies, ae as getBaseTypeFromODataType, X as getFormatter, J as getFormatterForBaseType, F as getFormattersFor, Se as getFormattersForBaseType, De as getSortIndex, R as getSortIndicator, te as isBaseMetaType, pe as isBaseValue, T as isBooleanSafe, a as isDateSafe, $ as isFilterLocalComponentId, j as isFilterOperation, Ce as isForcedCodeTextFamilyId, E as isForcedCodeTextId, we as isNumberSafe, he as isODataBooleanType, B as isODataDateType, ne as isODataIntegerType, ye as isODataNumericType, q as isSqlFilterScalarValue, D as isStringSafe, N as mergeFilterExpressions, _ as mergeFilterValuePatch, Z as normalizeBaseValue, v as normalizeDictionaryCodeKey, I as normalizeRangeValue, Oe as odataFormatValue, z as odataParseValue, Ee as odataParseValueByMetadata, l as odataTypeSchemas, c as parseServiceMetadata, n as resolveBaseTypeLabel, Te as resolveEffectiveSorts, o as resolveMetadataColumnLabel, x as resolveODataFilterDefinitionActiveColumnIds, u as resolveODataFilterDefinitionColumnIds, S as resolveOperationLabel, p as sanitizeFilterBinding, g as sanitizeFilterConditionGroup, C as sanitizeFilterDefinitions, ke as sanitizeFilterValue, r as sanitizeFilterValues, w as toggleSort, _e as unwrapODataParams, ce as unwrapODataQueryResult, oe as wrapODataParams };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuzaki13/react-foundation-lib",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "description": "Reusable React and TypeScript foundation utilities, hooks, and primitives.",
5
5
  "license": "MIT",
6
6
  "author": "Ryuzaki13",
@@ -3,6 +3,8 @@
3
3
  Утилитарный модуль для форматирования, парсинга и простых календарных операций в "плавающей" календарной семантике.
4
4
  Человекочитаемые форматы строятся на заранее созданных `Intl.DateTimeFormat`, чтобы переиспользовать formatter в больших таблицах и не создавать `Intl` на каждый вызов.
5
5
 
6
+ Для источников, где важен абсолютный момент времени, модуль предоставляет параллельные функции `parseDateValueTZ` и `parseDateTZ`. Они применяют явный timezone и не меняют поведение основного API.
7
+
6
8
  ## Ключевая идея
7
9
 
8
10
  Модуль намеренно не пересчитывает входные значения по timezone клиента. Для него важны видимые календарные компоненты:
@@ -30,6 +32,7 @@
30
32
  - форматировать даты и диапазоны
31
33
  - нормализовать `Date | null | [Date | null, Date | null]` в диапазон `Date`
32
34
  - парсить вход из `unknown`
35
+ - явно парсить timezone-aware значения как абсолютный instant
33
36
  - разбирать даты по пользовательскому шаблону
34
37
  - приводить результат парсинга к `Date | null`
35
38
  - хранить и переопределять именованные пресеты форматирования
@@ -294,6 +297,32 @@ parseDateValue("PT2H30M");
294
297
  - неподдерживаемых типов
295
298
  - битых дат и duration-строк
296
299
 
300
+ ### `parseDateValueTZ`
301
+
302
+ Возвращает тот же подробный результат, но сохраняет абсолютный instant для источников с timezone:
303
+
304
+ ```ts
305
+ import { parseDateValueTZ } from "@/shared/lib";
306
+
307
+ parseDateValueTZ("2026-03-03T18:03:50.327+05:30");
308
+ // {
309
+ // kind: "date-time",
310
+ // source: "iso-zoned",
311
+ // date: Date("2026-03-03T12:33:50.327Z")
312
+ // }
313
+
314
+ parseDateValueTZ("/Date(1234567890+0200)/");
315
+ // {
316
+ // kind: "date-time",
317
+ // source: "odata-ticks",
318
+ // date: Date(1234567890)
319
+ // }
320
+ ```
321
+
322
+ Timezone-aware режим применяется к `Date`, numeric timestamp, ISO `Z|±HH:mm`, OData ticks и `datetimeoffset` literal. Форматы без timezone (`2026-03-03T18:03:50`, ABAP compact/dotted, slash-date) остаются локальными календарными значениями.
323
+
324
+ В OData v2 ticks уже содержат миллисекунды от Unix epoch. Суффикс offset описывает сервисное timezone-представление, поэтому `parseDateValueTZ` не прибавляет его к instant повторно. Обычный `parseDateValue` по-прежнему использует offset для восстановления видимых сервисных компонентов.
325
+
297
326
  ### `parseDateByPattern`
298
327
 
299
328
  Парсит строку по пользовательскому шаблону с токенами:
@@ -320,18 +349,21 @@ parseDateByPattern("03+03+2026", "dd+MM+yyyy");
320
349
 
321
350
  ## Обёртки с результатом `Date | null`
322
351
 
323
- ### `parseDate`
352
+ ### `parseDate`, `parseDateTZ`
324
353
 
325
354
  Если нужен не подробный объект, а сразу `Date | null`, используй эту обёртку:
326
355
 
327
356
  ```ts
328
- import { parseDate } from "@/shared/lib";
357
+ import { parseDate, parseDateTZ } from "@/shared/lib";
329
358
 
330
359
  parseDate("2026-03-03T18:03:50Z");
331
360
  // Date(2026-03-03 18:03:50)
332
361
 
333
362
  parseDate("PT2H30M");
334
363
  // Date(1970-01-01 02:30:00)
364
+
365
+ parseDateTZ("2026-03-03T18:03:50.327+05:30");
366
+ // Date("2026-03-03T12:33:50.327Z")
335
367
  ```
336
368
 
337
369
  Для `duration` модуль строит `Date` из длительности без timezone-сдвига, сохраняя видимые UTC-компоненты. Это удобно для унификации API, но важно помнить: длительность и календарная дата не одно и то же.
@@ -455,8 +487,10 @@ isSameCalendarDay(new Date(2026, 2, 3, 1, 0, 0), new Date(2026, 2, 3, 23, 59, 59
455
487
  - `formatDateAsTime`
456
488
  - `formatDateRange`
457
489
  - `parseDateValue`
490
+ - `parseDateValueTZ`
458
491
  - `parseDateByPattern`
459
492
  - `parseDate`
493
+ - `parseDateTZ`
460
494
  - `registerDatePreset`
461
495
  - `getDatePreset`
462
496
  - `getDatePresetNames`