pi-apexlang 0.2.2 → 0.4.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.
- package/README.md +22 -5
- package/THIRD_PARTY_NOTICES.md +2 -2
- package/UPSTREAM.json +2 -2
- package/docs/assets/overview.en.png +0 -0
- package/docs/assets/overview.en.svg +89 -0
- package/docs/assets/overview.uk.png +0 -0
- package/docs/assets/overview.uk.svg +89 -0
- package/docs/en/README.md +41 -0
- package/docs/en/architecture.md +73 -0
- package/docs/en/getting-started.md +77 -0
- package/docs/en/maintenance.md +83 -0
- package/docs/en/tool-reference.md +85 -0
- package/docs/uk/README.md +41 -0
- package/docs/uk/architecture.md +73 -0
- package/docs/uk/getting-started.md +77 -0
- package/docs/uk/maintenance.md +83 -0
- package/docs/uk/tool-reference.md +85 -0
- package/extensions/apexlang/index.ts +19 -10
- package/extensions/lib/apexlang-cli.d.mts +1 -2
- package/extensions/lib/apexlang-cli.mjs +18 -13
- package/extensions/lib/apexlang-local-validate.mjs +83 -0
- package/extensions/lib/apexlang-local-validator.py +116 -0
- package/extensions/lib/apexlang-runtime-validate.mjs +76 -0
- package/package.json +2 -1
- package/skills/apexlang/APEXlang Skills and Workflows.md +325 -0
- package/skills/apexlang/README.md +6 -6
- package/skills/apexlang/RELEASE-NOTES.md +2 -2
- package/skills/apexlang/SKILL.md +24 -19
- package/skills/apexlang/agents/openai.yaml +4 -3
- package/skills/apexlang/assets/apex-generation/components.registry.json +1001 -16
- package/skills/apexlang/assets/apexlang/domains-catalog.json +6 -1
- package/skills/apexlang/assets/component-attributes.json +1924 -180
- package/skills/apexlang/assets/component-policies.json +19 -10
- package/skills/apexlang/assets/contracts/grammar-semantic-rules.json +134 -0
- package/skills/apexlang/assets/contracts/package-layers.json +56 -0
- package/skills/apexlang/assets/contracts/page-construction-packs.json +154 -0
- package/skills/apexlang/assets/contracts/page-patterns.json +119 -0
- package/skills/apexlang/assets/grammar/apexlang.ebnf +11743 -0
- package/skills/apexlang/assets/indexes/font-apex-icon-index.json +1699 -0
- package/skills/apexlang/assets/routing-catalog-main.json +11 -10
- package/skills/apexlang/assets/routing-load-policy.json +35 -9
- package/skills/apexlang/assets/rules-mapping.json +110 -2
- package/skills/apexlang/assets/rules.catalog.json +1298 -0
- package/skills/apexlang/assets/validator-fix-recipes.json +372 -17
- package/skills/apexlang/assets/workspace-intelligence.json +7 -10
- package/skills/apexlang/manifest.json +268 -12
- package/skills/apexlang/references/domains/README.md +1 -1
- package/skills/apexlang/references/domains/page-components/buttons.md +2 -2
- package/skills/apexlang/references/domains/page-components/page-items.md +3 -3
- package/skills/apexlang/references/domains/page-components/regions/region-display-selector/workflow-region-display-selector.md +69 -0
- package/skills/apexlang/references/domains/page-components/regions.md +1 -0
- package/skills/apexlang/references/domains/template-components/comments.md +61 -0
- package/skills/apexlang/references/domains/template-components/registry.md +2 -0
- package/skills/apexlang/references/domains/template-components/templates.md +47 -0
- package/skills/apexlang/references/domains/template-components/timeline.md +51 -0
- package/skills/apexlang/references/ops/one-message-router-contract.md +2 -2
- package/skills/apexlang/references/ops/runtime-gates/01-direct-sqlcl-import.md +1 -1
- package/skills/apexlang/references/ops/runtime-gates/02-direct-sqlcl-validate-gate.md +1 -1
- package/skills/apexlang/references/ops/runtime-gates.md +17 -16
- package/skills/apexlang/references/ops/sqlcl-agents/00-connection-gate.md +7 -7
- package/skills/apexlang/references/ops/sqlcl.md +7 -8
- package/skills/apexlang/references/policies/compiler-prop-map.md +6 -4
- package/skills/apexlang/references/policies/governance/00-governance.md +2 -2
- package/skills/apexlang/references/policies/memory-bank/00-guard/ai.guard.md +126 -922
- package/skills/apexlang/references/policies/memory-bank/20-data/apex.logic.md +3 -3
- package/skills/apexlang/references/policies/memory-bank/20-data/db.connection.md +9 -11
- package/skills/apexlang/references/policies/memory-bank/30-pages/apex.cards-page.md +95 -0
- package/skills/apexlang/references/policies/memory-bank/30-pages/apex.page.md +2 -2
- package/skills/apexlang/references/policies/memory-bank/30-pages/apex.smart-filter-search.md +145 -74
- package/skills/apexlang/references/policies/memory-bank/40-components/apex.region-interactions.md +9 -2
- package/skills/apexlang/references/policies/memory-bank/40-components/apex.region-media.md +6 -5
- package/skills/apexlang/references/policies/memory-bank/systemPatterns.md +9 -1
- package/skills/apexlang/references/workflows/apex-generation/agents/20-agent-draft.md +51 -232
- package/skills/apexlang/references/workflows/apex-generation/agents/30-agent-critique.md +49 -449
- package/skills/apexlang/references/workflows/apex-generation/agents/40-agent-revision.md +38 -238
- package/skills/apexlang/references/workflows/apex-generation/nlu/nlu-routing-test-matrix.md +8 -2
- package/skills/apexlang/references/workflows/apex-generation/nlu/nlu-routing-validation-notes.md +19 -3
- package/skills/apexlang/references/workflows/apex-generation/registry.md +15 -1
- package/skills/apexlang/references/workflows/apex-generation/templates.md +1 -1
- package/skills/apexlang/references/workflows/apex-generation.md +1 -1
- package/skills/apexlang/references/workflows/apexlang/apexlang-execution-model.md +5 -5
- package/skills/apexlang/references/workflows/apexlang/prompt-contracts.md +81 -10
- package/skills/apexlang/references/workflows/apexlang/workflow-create-app-from-fr-and-model.md +18 -7
- package/skills/apexlang/release-notes.json +156 -0
- package/skills/apexlang/runtime/grammar_contract.mjs +1166 -0
- package/skills/apexlang/runtime/internal/python/format_apexlang.py +210 -0
- package/skills/apexlang/runtime/internal/python/validate_apexlang.py +14142 -5843
- package/skills/apexlang/runtime/internal/python/validator_common.py +2 -0
- package/skills/apexlang/runtime/lib/catalogs.mjs +1026 -0
- package/skills/apexlang/runtime/lib/common.mjs +35 -0
- package/skills/apexlang/runtime/runtime.bundle.mjs +457 -57
- package/skills/apexlang/templates/items/combobox/combobox.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/date-picker/date-picker._common.md +1 -1
- package/skills/apexlang/templates/items/date-picker/date-picker.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/file-upload/file-upload._common.md +30 -24
- package/skills/apexlang/templates/items/file-upload/file-upload.compact-template.md +6 -0
- package/skills/apexlang/templates/items/file-upload/file-upload.explicit-defaults.md +23 -8
- package/skills/apexlang/templates/items/file-upload/file-upload.minimal.md +6 -0
- package/skills/apexlang/templates/items/hidden-item/hidden-item._common.md +1 -1
- package/skills/apexlang/templates/items/hidden-item/hidden-item.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/items._common.md +3 -2
- package/skills/apexlang/templates/items/list-manager/list-manager.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/markdown-editor/markdown-editor._common.md +1 -1
- package/skills/apexlang/templates/items/markdown-editor/markdown-editor.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/number-field/number-field._common.md +8 -6
- package/skills/apexlang/templates/items/number-field/number-field.explicit-defaults.md +12 -2
- package/skills/apexlang/templates/items/popup-lov/popup-lov.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/rich-text-editor/rich-text-editor._common.md +1 -1
- package/skills/apexlang/templates/items/rich-text-editor/rich-text-editor.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/select-many/standard.md +1 -1
- package/skills/apexlang/templates/items/shuttle/shuttle.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/switch/switch._common.md +8 -8
- package/skills/apexlang/templates/items/switch/switch.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/text-area/text-area._common.md +2 -3
- package/skills/apexlang/templates/items/text-area/text-area.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/text-area/text-area.required-length.md +1 -3
- package/skills/apexlang/templates/items/text-autocomplete/text-autocomplete.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/text-autocomplete/text-autocomplete.required-length.md +1 -3
- package/skills/apexlang/templates/items/text-field/text-field._common.md +2 -3
- package/skills/apexlang/templates/items/text-field/text-field.explicit-defaults.md +1 -1
- package/skills/apexlang/templates/items/text-field/text-field.required-length.md +1 -3
- package/skills/apexlang/templates/page-examples/faceted-search/faceted-search.example.md +0 -5
- package/skills/apexlang/templates/page-examples/form-page/form-page.example.md +0 -9
- package/skills/apexlang/templates/page-examples/interactive-report-page/interactive-report-page.example.md +2 -2
- package/skills/apexlang/templates/page-examples/login-page/login-page.example.md +0 -8
- package/skills/apexlang/templates/page-examples/task-definition-initiated-tasks-page/task-definition-initiated-tasks-page.example.md +7 -17
- package/skills/apexlang/templates/page-examples/task-definition-my-tasks-page/task-definition-my-tasks-page.example.md +7 -65
- package/skills/apexlang/templates/page-examples/task-definition-task-details/task-definition-task-details.example.md +38 -201
- package/skills/apexlang/templates/region-components/calendar/calendar.custom-styling.md +3 -1
- package/skills/apexlang/templates/region-components/calendar/calendar.faceted-search.md +3 -2
- package/skills/apexlang/templates/region-components/cards/README.md +12 -4
- package/skills/apexlang/templates/region-components/cards/cards._common.md +176 -37
- package/skills/apexlang/templates/region-components/cards/cards._index.md +2 -1
- package/skills/apexlang/templates/region-components/cards/cards.refresh-after-dialog.md +46 -0
- package/skills/apexlang/templates/region-components/cards/cards.refresh-on-change.md +58 -0
- package/skills/apexlang/templates/region-components/cards/cards.rest-source.md +54 -18
- package/skills/apexlang/templates/region-components/cards/cards.standard.md +37 -21
- package/skills/apexlang/templates/region-components/chart/chart._series._common.md +1 -4
- package/skills/apexlang/templates/region-components/chart/chart.pie.md +6 -2
- package/skills/apexlang/templates/region-components/chart/chart.status-meter-gauge.md +1 -1
- package/skills/apexlang/templates/region-components/chart/chart.stock.md +2 -0
- package/skills/apexlang/templates/region-components/chart/features/chart.feature-chart-links.md +9 -7
- package/skills/apexlang/templates/region-components/faceted-search/faceted-search._common.md +1 -14
- package/skills/apexlang/templates/region-components/form/form._items._common.md +1 -5
- package/skills/apexlang/templates/region-components/interactive-report/interactive-report._columns._common.md +2 -6
- package/skills/apexlang/templates/region-components/interactive-report/interactive-report.page-header-actions.md +1 -7
- package/skills/apexlang/templates/region-components/list/README.md +1 -1
- package/skills/apexlang/templates/region-components/list/list._common.md +1 -1
- package/skills/apexlang/templates/region-components/map/map.backgrounds.md +12 -10
- package/skills/apexlang/templates/region-components/map/map.layer.extruded-polygons.md +16 -12
- package/skills/apexlang/templates/region-components/map/map.layer.heat-map.md +10 -7
- package/skills/apexlang/templates/region-components/map/map.layer.lines.md +10 -8
- package/skills/apexlang/templates/region-components/map/map.layer.polygons.md +21 -18
- package/skills/apexlang/templates/region-components/map/map.region.background-custom.md +25 -19
- package/skills/apexlang/templates/region-components/map/map.region.background-shared.md +19 -13
- package/skills/apexlang/templates/region-components/map/map.region.bbox-sql.md +13 -13
- package/skills/apexlang/templates/region-components/map/map.region.bbox-static.md +2 -2
- package/skills/apexlang/templates/region-components/map/map.region.browser-location.md +3 -7
- package/skills/apexlang/templates/region-components/map/map.region.init-position-sql.md +7 -7
- package/skills/apexlang/templates/region-components/region-display-selector/README.md +5 -2
- package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector._common.md +60 -7
- package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector._index.md +4 -1
- package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector.permutations.md +55 -0
- package/skills/apexlang/templates/region-components/region-display-selector/region-display-selector.standard.md +91 -5
- package/skills/apexlang/templates/region-components/smart-filter-search/README.md +6 -2
- package/skills/apexlang/templates/region-components/smart-filter-search/smart-filter-search._common.md +107 -46
- package/skills/apexlang/templates/region-components/smart-filter-search/smart-filter-search._index.md +4 -3
- package/skills/apexlang/templates/region-components/smart-filter-search/smart-filter-search.standard.md +33 -17
- package/skills/apexlang/templates/shared-components/component-settings/component-settings._common.md +1 -0
- package/skills/apexlang/templates/shared-components/component-settings.example.md +1 -0
- package/skills/apexlang/templates/shared-components/email-templates.example.md +1 -1
- package/skills/apexlang/templates/shared-components/rest-data-sources/example_rest_data_source.example.md +40 -46
- package/skills/apexlang/templates/shared-components/task-definitions/action-task.example.md +2 -30
- package/skills/apexlang/templates/shared-components/task-definitions/approve-request.example.md +3 -31
- package/skills/apexlang/templates/template-components/README.md +27 -15
- package/skills/apexlang/templates/template-components/avatar/README.md +56 -0
- package/skills/apexlang/templates/template-components/avatar/avatar._common.md +149 -0
- package/skills/apexlang/templates/template-components/avatar/avatar._index.md +42 -0
- package/skills/apexlang/templates/template-components/{avatar._template_options.md → avatar/avatar._template_options.md} +1 -1
- package/skills/apexlang/templates/template-components/avatar/avatar.report-icon.md +48 -0
- package/skills/apexlang/templates/template-components/avatar/avatar.report-image-url-column.md +62 -0
- package/skills/apexlang/templates/template-components/avatar/avatar.report-initials.md +54 -0
- package/skills/apexlang/templates/template-components/badge/README.md +38 -0
- package/skills/apexlang/templates/template-components/badge/badge._common.md +183 -0
- package/skills/apexlang/templates/template-components/badge/badge._index.md +20 -0
- package/skills/apexlang/templates/template-components/badge/badge.report-link.md +66 -0
- package/skills/apexlang/templates/template-components/badge/badge.report-minimal.md +76 -0
- package/skills/apexlang/templates/template-components/comments/README.md +20 -0
- package/skills/apexlang/templates/template-components/comments/comments._common.md +43 -0
- package/skills/apexlang/templates/template-components/comments/comments._index.md +25 -0
- package/skills/apexlang/templates/template-components/{comments._template_options.md → comments/comments._template_options.md} +2 -1
- package/skills/apexlang/templates/template-components/comments/comments.apex-task-comments.md +77 -0
- package/skills/apexlang/templates/template-components/comments/comments.partial-column.md +120 -0
- package/skills/apexlang/templates/template-components/comments/comments.permutations.md +425 -0
- package/skills/apexlang/templates/template-components/content-row/README.md +1 -1
- package/skills/apexlang/templates/template-components/content-row/content-row._common.md +1 -1
- package/skills/apexlang/templates/template-components/content-row/content-row._index.md +1 -1
- package/skills/apexlang/templates/template-components/content-row/content-row._template_options.md +1 -1
- package/skills/apexlang/templates/template-components/flexbox-container/README.md +9 -0
- package/skills/apexlang/templates/template-components/flexbox-container/flexbox-container._index.md +13 -0
- package/skills/apexlang/templates/template-components/media-list/README.md +100 -0
- package/skills/apexlang/templates/template-components/media-list/media-list._common.md +174 -0
- package/skills/apexlang/templates/template-components/media-list/media-list._index.md +50 -0
- package/skills/apexlang/templates/template-components/{media-list._template_options.md → media-list/media-list._template_options.md} +8 -2
- package/skills/apexlang/templates/template-components/media-list/media-list.partial.md +50 -0
- package/skills/apexlang/templates/template-components/media-list/media-list.report-avatar-badge.md +76 -0
- package/skills/apexlang/templates/template-components/media-list/media-list.report-base.md +71 -0
- package/skills/apexlang/templates/template-components/media-list/media-list.report-grouped.md +40 -0
- package/skills/apexlang/templates/template-components/media-list/media-list.report-layouts.md +50 -0
- package/skills/apexlang/templates/template-components/media-list/media-list.report-link.md +53 -0
- package/skills/apexlang/templates/template-components/metric-card/README.md +19 -4
- package/skills/apexlang/templates/template-components/metric-card/metric-card._common.md +122 -29
- package/skills/apexlang/templates/template-components/metric-card/metric-card._index.md +6 -0
- package/skills/apexlang/templates/template-components/metric-card/metric-card._template_options.md +47 -2
- package/skills/apexlang/templates/template-components/metric-card/metric-card.partial-minimal.md +51 -0
- package/skills/apexlang/templates/template-components/metric-card/metric-card.permutations.md +56 -0
- package/skills/apexlang/templates/template-components/metric-card/metric-card.report-avatar-badge.md +98 -0
- package/skills/apexlang/templates/template-components/metric-card/metric-card.report-grouping-selection.md +131 -0
- package/skills/apexlang/templates/template-components/metric-card/metric-card.report-link.md +66 -0
- package/skills/apexlang/templates/template-components/metric-card/metric-card.report-minimal.md +97 -0
- package/skills/apexlang/templates/template-components/template-components.registry.json +90 -1
- package/skills/apexlang/templates/template-components/timeline/README.md +19 -0
- package/skills/apexlang/templates/template-components/timeline/timeline._common.md +43 -0
- package/skills/apexlang/templates/template-components/timeline/timeline._index.md +24 -0
- package/skills/apexlang/templates/template-components/{timeline._template_options.md → timeline/timeline._template_options.md} +2 -1
- package/skills/apexlang/templates/template-components/timeline/timeline.permutations.md +399 -0
- package/skills/apexlang/templates/template-components/timeline/timeline.report-sample-data.md +168 -0
- package/skills/apexlang/templates/workspace-components/credentials/credentials-for-open-ai.example.md +1 -1
- package/skills/apexlang/templates/workspace-components/generative-ai-services/open-ai.example.md +8 -6
- package/skills/apexlang/tools/apexctl.mjs +167 -4
- package/skills/apexlang/tools/compiler-truth-audit.mjs +95 -63
- package/skills/apexlang/tools/query-valid-props-context.mjs +30 -0
- package/skills/apexlang/tools/query-valid-props-normalize.mjs +1 -0
- package/skills/apexlang/tools/query-valid-props-runtime.mjs +13 -8
- package/skills/apexlang/tools/query-valid-props-semantics.mjs +391 -0
- package/skills/apexlang/tools/query-valid-props-template-components.mjs +15 -1
- package/skills/apexlang/tools/query-valid-props.mjs +198 -216
- /package/skills/apexlang/templates/template-components/{badge._template_options.md → badge/badge._template_options.md} +0 -0
- /package/skills/apexlang/templates/template-components/{flexbox-container._template_options.md → flexbox-container/flexbox-container._template_options.md} +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Canonical whitespace formatter for the line-oriented APEXlang DSL."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import re
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
PROPERTY_START = re.compile(r"(?<=\s)(?=[A-Za-z][A-Za-z0-9]*\s*:)")
|
|
14
|
+
DECLARATION_START = re.compile(r"^[A-Za-z][A-Za-z0-9]*\b")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def collect_apx_files(root: Path) -> list[Path]:
|
|
18
|
+
if root.is_file():
|
|
19
|
+
return [root] if root.suffix == ".apx" else []
|
|
20
|
+
return sorted(path for path in root.rglob("*.apx") if "apex-exports" not in path.parts)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def structural_tokens(text: str) -> list[str]:
|
|
24
|
+
"""Split structural delimiters while leaving quoted/fenced values untouched."""
|
|
25
|
+
tokens: list[str] = []
|
|
26
|
+
current: list[str] = []
|
|
27
|
+
quoted = False
|
|
28
|
+
escaped = False
|
|
29
|
+
for char in text:
|
|
30
|
+
if char == '"' and not escaped:
|
|
31
|
+
quoted = not quoted
|
|
32
|
+
if not quoted and char in "(){}":
|
|
33
|
+
if "".join(current).strip():
|
|
34
|
+
tokens.append("".join(current).strip())
|
|
35
|
+
tokens.append(char)
|
|
36
|
+
current = []
|
|
37
|
+
else:
|
|
38
|
+
current.append(char)
|
|
39
|
+
escaped = char == "\\" and not escaped
|
|
40
|
+
if char != "\\":
|
|
41
|
+
escaped = False
|
|
42
|
+
if "".join(current).strip():
|
|
43
|
+
tokens.append("".join(current).strip())
|
|
44
|
+
return tokens
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def split_properties(token: str) -> list[str]:
|
|
48
|
+
if not token or token.startswith("```") or "sqlQuery:" in token or "plsql" in token:
|
|
49
|
+
return [token]
|
|
50
|
+
parts = [part.strip() for part in PROPERTY_START.split(token) if part.strip()]
|
|
51
|
+
return parts or [token]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def shape_fingerprint(text: str) -> tuple[str, ...]:
|
|
55
|
+
"""Capture line-level structure while ignoring indentation and whitespace."""
|
|
56
|
+
fingerprint: list[str] = []
|
|
57
|
+
in_fence = False
|
|
58
|
+
for line in text.replace("\r\n", "\n").replace("\r", "\n").splitlines():
|
|
59
|
+
stripped = line.strip()
|
|
60
|
+
if stripped.startswith("```"):
|
|
61
|
+
in_fence = not in_fence
|
|
62
|
+
if not stripped or in_fence:
|
|
63
|
+
fingerprint.append("fence-or-blank" if in_fence else "blank")
|
|
64
|
+
continue
|
|
65
|
+
fingerprint.append(re.sub(r"\s+", " ", stripped))
|
|
66
|
+
return tuple(fingerprint)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def structural_violations(text: str) -> list[str]:
|
|
70
|
+
"""Reject structures that the canonical renderer must never emit."""
|
|
71
|
+
violations: list[str] = []
|
|
72
|
+
in_fence = False
|
|
73
|
+
for line_number, line in enumerate(text.replace("\r\n", "\n").replace("\r", "\n").splitlines(), 1):
|
|
74
|
+
stripped = line.strip()
|
|
75
|
+
if stripped.startswith("```"):
|
|
76
|
+
in_fence = not in_fence
|
|
77
|
+
continue
|
|
78
|
+
if not stripped or in_fence:
|
|
79
|
+
continue
|
|
80
|
+
if "{" in stripped or "(" in stripped:
|
|
81
|
+
for opener in ("{", "("):
|
|
82
|
+
if opener in stripped:
|
|
83
|
+
tail = stripped[stripped.index(opener) + 1:].strip()
|
|
84
|
+
if tail or ("}" in stripped or ")" in stripped):
|
|
85
|
+
violations.append(f"line {line_number}: structural block must be multiline and opening delimiter must end its line")
|
|
86
|
+
break
|
|
87
|
+
assignments = re.findall(r"\b[A-Za-z][A-Za-z0-9]*\s*:", stripped)
|
|
88
|
+
if len(assignments) > 1 and "sqlQuery:" not in stripped and "plsql" not in stripped:
|
|
89
|
+
violations.append(f"line {line_number}: properties must occupy separate lines")
|
|
90
|
+
return violations
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def format_text(text: str) -> tuple[str, bool, list[str]]:
|
|
94
|
+
original_text = text
|
|
95
|
+
if "\r" in text:
|
|
96
|
+
text = text.replace("\r\n", "\n").replace("\r", "\n")
|
|
97
|
+
findings: list[str] = []
|
|
98
|
+
output: list[str] = []
|
|
99
|
+
indent = 0
|
|
100
|
+
bracket_indent = 0
|
|
101
|
+
in_fence = False
|
|
102
|
+
trailing_newlines = max(1, len(text) - len(text.rstrip("\n")))
|
|
103
|
+
|
|
104
|
+
for original in text.splitlines():
|
|
105
|
+
stripped = original.strip()
|
|
106
|
+
if not stripped:
|
|
107
|
+
if output and output[-1] != "":
|
|
108
|
+
output.append("")
|
|
109
|
+
continue
|
|
110
|
+
if stripped.startswith("```"):
|
|
111
|
+
in_fence = not in_fence
|
|
112
|
+
output.append(original.rstrip())
|
|
113
|
+
continue
|
|
114
|
+
if in_fence:
|
|
115
|
+
output.append(original.rstrip())
|
|
116
|
+
continue
|
|
117
|
+
prefix = re.split(r"[({]", stripped, maxsplit=1)[0]
|
|
118
|
+
if ":" in prefix and not re.match(r"^[A-Za-z][A-Za-z0-9]*\s*:\s*\{", stripped):
|
|
119
|
+
output.append(original.rstrip())
|
|
120
|
+
bracket_indent += stripped.count("[") - stripped.count("]")
|
|
121
|
+
continue
|
|
122
|
+
|
|
123
|
+
tokens = structural_tokens(stripped)
|
|
124
|
+
if len(tokens) == 1 and ("(" in stripped or "{" in stripped or "}" in stripped or ")" in stripped):
|
|
125
|
+
findings.append("compact structural line expanded")
|
|
126
|
+
expanded: list[str] = []
|
|
127
|
+
for token in tokens:
|
|
128
|
+
expanded.extend(split_properties(token))
|
|
129
|
+
for index, token in enumerate(expanded):
|
|
130
|
+
if token.startswith("]"):
|
|
131
|
+
bracket_indent = max(0, bracket_indent - 1)
|
|
132
|
+
if token == "}":
|
|
133
|
+
indent = max(0, indent - 1)
|
|
134
|
+
elif token == ")":
|
|
135
|
+
indent = max(0, indent - 1)
|
|
136
|
+
if token == "(":
|
|
137
|
+
if output and DECLARATION_START.match(output[-1].strip()):
|
|
138
|
+
output[-1] = output[-1].rstrip() + " ("
|
|
139
|
+
else:
|
|
140
|
+
output.append(" " * (indent + bracket_indent) + token)
|
|
141
|
+
indent += 1
|
|
142
|
+
elif token == "{":
|
|
143
|
+
if output and ":" in output[-1]:
|
|
144
|
+
match = re.match(r"^(?P<value>.*:\s+.+)\s+(?P<block>[A-Za-z][A-Za-z0-9]*)$", output[-1])
|
|
145
|
+
if match:
|
|
146
|
+
output[-1] = match.group("value")
|
|
147
|
+
output.append(" " * (indent + bracket_indent) + match.group("block"))
|
|
148
|
+
if output:
|
|
149
|
+
output[-1] = output[-1].rstrip() + " {"
|
|
150
|
+
else:
|
|
151
|
+
output.append(" " * (indent + bracket_indent) + token)
|
|
152
|
+
indent += 1
|
|
153
|
+
elif token in {"}", ")"}:
|
|
154
|
+
output.append(" " * (indent + bracket_indent) + token)
|
|
155
|
+
else:
|
|
156
|
+
output.append(" " * (indent + bracket_indent) + token)
|
|
157
|
+
bracket_delta = token.count("[") - token.count("]")
|
|
158
|
+
if bracket_delta > 0:
|
|
159
|
+
bracket_indent += bracket_delta
|
|
160
|
+
|
|
161
|
+
while output and output[-1] == "":
|
|
162
|
+
output.pop()
|
|
163
|
+
formatted = "\n".join(output) + "\n" * trailing_newlines
|
|
164
|
+
changed = formatted != original_text
|
|
165
|
+
return formatted, changed, findings
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def main() -> int:
|
|
169
|
+
parser = argparse.ArgumentParser()
|
|
170
|
+
parser.add_argument("root", type=Path)
|
|
171
|
+
parser.add_argument("--check", action="store_true")
|
|
172
|
+
parser.add_argument("--strict-structure", action="store_true")
|
|
173
|
+
parser.add_argument("--report-path", type=Path)
|
|
174
|
+
args = parser.parse_args()
|
|
175
|
+
|
|
176
|
+
files = collect_apx_files(args.root)
|
|
177
|
+
report = {"status": "ok", "files": [], "changed_files": 0, "findings": []}
|
|
178
|
+
for path in files:
|
|
179
|
+
with path.open("r", encoding="utf-8", newline="") as stream:
|
|
180
|
+
original = stream.read()
|
|
181
|
+
original_shape = shape_fingerprint(original)
|
|
182
|
+
formatted, changed, findings = format_text(original)
|
|
183
|
+
formatted_shape = shape_fingerprint(formatted)
|
|
184
|
+
violations = structural_violations(formatted)
|
|
185
|
+
structural_changed = original_shape != formatted_shape
|
|
186
|
+
if args.strict_structure and structural_changed:
|
|
187
|
+
report["status"] = "structural_change_rejected"
|
|
188
|
+
report["findings"].append({"path": str(path), "finding": "formatter would change structural shape"})
|
|
189
|
+
if violations:
|
|
190
|
+
report["status"] = "invalid_structure"
|
|
191
|
+
report["findings"].extend({"path": str(path), "finding": violation} for violation in violations)
|
|
192
|
+
if changed and not args.check and not (args.strict_structure and structural_changed):
|
|
193
|
+
with path.open("w", encoding="utf-8", newline="\n") as stream:
|
|
194
|
+
stream.write(formatted)
|
|
195
|
+
if changed:
|
|
196
|
+
report["changed_files"] += 1
|
|
197
|
+
report["files"].append(str(path))
|
|
198
|
+
report["findings"].extend({"path": str(path), "finding": finding} for finding in findings)
|
|
199
|
+
|
|
200
|
+
if args.check and report["changed_files"] and report["status"] == "ok":
|
|
201
|
+
report["status"] = "needs_formatting"
|
|
202
|
+
if args.report_path:
|
|
203
|
+
args.report_path.parent.mkdir(parents=True, exist_ok=True)
|
|
204
|
+
args.report_path.write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8")
|
|
205
|
+
print(json.dumps(report, indent=2))
|
|
206
|
+
return 1 if report["status"] != "ok" else 0
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
if __name__ == "__main__":
|
|
210
|
+
sys.exit(main())
|