@cratis/pi 7.34.1 → 7.36.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/package/corpus/agents/security-reviewer.md +1 -0
- package/package/corpus/agents/spec-writer.md +1 -1
- package/package/corpus/harnesses/pi/extensions/shared/rules.ts +3 -1
- package/package/corpus/hooks/scripts/cratis-nuget-pins.txt +7 -6
- package/package/corpus/hooks/scripts/cratis-release-notes-reviewed.cjs +7 -6
- package/package/corpus/hooks/scripts/cratis-store-mutations.json +7 -3
- package/package/corpus/product-sync.json +896 -0
- package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
- package/package/corpus/prompts/ship-changes.prompt.md +2 -2
- package/package/corpus/rules/ai-distribution.md +31 -3
- package/package/corpus/rules/application-profile.md +2 -1
- package/package/corpus/rules/components.md +66 -7
- package/package/corpus/rules/concepts.md +11 -3
- package/package/corpus/rules/csharp.md +3 -1
- package/package/corpus/rules/dialogs.md +9 -0
- package/package/corpus/rules/efcore.md +1 -1
- package/package/corpus/rules/elixir.md +49 -0
- package/package/corpus/rules/framework.md +5 -3
- package/package/corpus/rules/general.md +1 -0
- package/package/corpus/rules/glossary.md +4 -4
- package/package/corpus/rules/go-engineering.md +60 -0
- package/package/corpus/rules/go.md +115 -0
- package/package/corpus/rules/java.md +5 -2
- package/package/corpus/rules/kotlin.md +7 -5
- package/package/corpus/rules/orleans.md +65 -9
- package/package/corpus/rules/profiles.md +43 -6
- package/package/corpus/rules/pull-requests.md +3 -3
- package/package/corpus/rules/react.md +8 -1
- package/package/corpus/rules/reactors.md +27 -3
- package/package/corpus/rules/specs.csharp.md +11 -4
- package/package/corpus/rules/specs.scenarios.csharp.md +35 -4
- package/package/corpus/rules/specs.typescript.md +2 -1
- package/package/corpus/rules/storybook.md +1 -1
- package/package/corpus/rules/typescript.md +1 -1
- package/package/corpus/rules/vertical-slices.md +37 -5
- package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -2
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +18 -8
- package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +65 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +53 -57
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +38 -42
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +18 -7
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authproxy.md +30 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +12 -9
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +9 -9
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +8 -5
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +20 -4
- package/package/corpus/skills/cratis-arc-command/SKILL.md +32 -10
- package/package/corpus/skills/cratis-arc-command/references/command-result.md +12 -5
- package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -0
- package/package/corpus/skills/cratis-arc-command/references/generated-values.md +3 -2
- package/package/corpus/skills/cratis-arc-command/references/handler-shapes.md +8 -8
- package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +22 -3
- package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +13 -1
- package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +19 -9
- package/package/corpus/skills/cratis-arc-command-kotlin/SKILL.md +44 -18
- package/package/corpus/skills/cratis-arc-command-kotlin/references/read-model-naming.md +29 -0
- package/package/corpus/skills/cratis-arc-command-operation/SKILL.md +10 -9
- package/package/corpus/skills/cratis-arc-command-operation/references/execution-and-recovery.md +2 -2
- package/package/corpus/skills/cratis-arc-command-operation/references/testing.md +4 -3
- package/package/corpus/skills/cratis-arc-command-typescript/SKILL.md +42 -22
- package/package/corpus/skills/cratis-arc-command-typescript/references/chronicle-events.md +36 -5
- package/package/corpus/skills/cratis-arc-command-typescript/references/command-operations.md +114 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/hosting-and-storage.md +37 -16
- package/package/corpus/skills/cratis-arc-command-typescript/references/identity-and-introspection.md +88 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/observability-and-host-scopes.md +25 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/proxy-generation.md +35 -4
- package/package/corpus/skills/cratis-arc-command-typescript/references/slice-layout.md +11 -0
- package/package/corpus/skills/cratis-arc-command-typescript/verification.json +8 -1
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +49 -19
- package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +12 -6
- package/package/corpus/skills/cratis-arc-go/SKILL.md +148 -0
- package/package/corpus/skills/cratis-arc-go/references/queries.md +80 -0
- package/package/corpus/skills/cratis-arc-hosting/SKILL.md +96 -0
- package/package/corpus/skills/cratis-arc-hosting/references/integrations-and-publish.md +80 -0
- package/package/corpus/skills/cratis-arc-identity-and-tenancy-kotlin/SKILL.md +137 -0
- package/package/corpus/skills/cratis-arc-observable-query-http/SKILL.md +20 -2
- package/package/corpus/skills/cratis-arc-query-kotlin/SKILL.md +26 -6
- package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +25 -20
- package/package/corpus/skills/cratis-arc-query-typescript/SKILL.md +32 -6
- package/package/corpus/skills/cratis-arc-query-typescript/references/storage-observation-and-compliance.md +66 -0
- package/package/corpus/skills/cratis-arc-query-typescript/verification.json +5 -1
- package/package/corpus/skills/cratis-arc-react-page/SKILL.md +24 -13
- package/package/corpus/skills/cratis-arc-react-page/references/data-page.md +20 -10
- package/package/corpus/skills/cratis-arc-react-page/references/data-tables.md +17 -3
- package/package/corpus/skills/cratis-arc-react-page/references/dialogs.md +14 -3
- package/package/corpus/skills/cratis-arc-react-page/references/from-screenplay.md +6 -1
- package/package/corpus/skills/cratis-arc-react-page/references/provenance.md +1 -1
- package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +11 -1
- package/package/corpus/skills/cratis-arc-react-page/verification.json +6 -1
- package/package/corpus/skills/cratis-arc-spring-data-kotlin/SKILL.md +163 -0
- package/package/corpus/skills/cratis-arc-testing-kotlin/SKILL.md +131 -0
- package/package/corpus/skills/cratis-arc-validation-kotlin/SKILL.md +44 -11
- package/package/corpus/skills/cratis-arc-validation-typescript/SKILL.md +5 -3
- package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +79 -25
- package/package/corpus/skills/cratis-chronicle-cli-operations/references/command-effects.md +57 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +87 -99
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/additional-surfaces.md +65 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/client-construction.md +42 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/compatibility-check.md +12 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/discovery.md +43 -19
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/hosting.md +29 -1
- package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +158 -162
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/append-api.md +36 -15
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/compliance.md +32 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/connections.md +56 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/event-sources.md +64 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/pitfalls.md +25 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/projections.md +48 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/upgrading.md +34 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/variants.md +13 -5
- package/package/corpus/skills/cratis-chronicle-client-elixir/verification.json +23 -0
- package/package/corpus/skills/cratis-chronicle-client-go/SKILL.md +162 -0
- package/package/corpus/skills/cratis-chronicle-client-go/references/projections.md +73 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +87 -88
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/connection-lifecycle.md +13 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/discovery-and-registration.md +14 -4
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/event-sources.md +65 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/options.md +29 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/spring-boot.md +13 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/variants.md +5 -4
- package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +165 -156
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/read-models-and-projections.md +54 -11
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/testing.md +126 -0
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/variants.md +3 -5
- package/package/corpus/skills/cratis-chronicle-client-typescript/verification.json +19 -0
- package/package/corpus/skills/cratis-chronicle-compliance/SKILL.md +36 -13
- package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +110 -0
- package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +57 -0
- package/package/corpus/skills/cratis-chronicle-decision-reads/verification.json +12 -0
- package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +58 -19
- package/package/corpus/skills/cratis-chronicle-event-constraints/references/closing-streams.md +73 -0
- package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +32 -3
- package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +18 -5
- package/package/corpus/skills/cratis-chronicle-event-type-migration/SKILL.md +32 -2
- package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +134 -0
- package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +89 -0
- package/package/corpus/skills/cratis-chronicle-hosting/verification.json +14 -0
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/SKILL.md +93 -66
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/blocked-tools.md +21 -7
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/deployment.md +77 -0
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/observational-tools.md +46 -4
- package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +15 -1
- package/package/corpus/skills/cratis-chronicle-projection/SKILL.md +44 -10
- package/package/corpus/skills/cratis-chronicle-projection/references/fluent-builder.md +7 -1
- package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
- package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +85 -105
- package/package/corpus/skills/cratis-chronicle-reactor/references/specifications.md +20 -1
- package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +35 -16
- package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +15 -3
- package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +23 -4
- package/package/corpus/skills/cratis-chronicle-web-workbench/SKILL.md +40 -15
- package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +20 -6
- package/package/corpus/skills/cratis-code-review/SKILL.md +25 -3
- package/package/corpus/skills/cratis-components-accessibility/SKILL.md +20 -4
- package/package/corpus/skills/cratis-components-schema-editor/SKILL.md +40 -28
- package/package/corpus/skills/cratis-components-schema-editor/references/tree-layout.md +62 -0
- package/package/corpus/skills/cratis-components-schema-editor/verification.json +14 -0
- package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +16 -8
- package/package/corpus/skills/cratis-components-styling/SKILL.md +57 -20
- package/package/corpus/skills/cratis-components-styling/verification.json +13 -0
- package/package/corpus/skills/cratis-components-toolbar/SKILL.md +37 -7
- package/package/corpus/skills/cratis-components-toolbar/verification.json +12 -0
- package/package/corpus/skills/cratis-engineering-csharp-conventions/SKILL.md +6 -0
- package/package/corpus/skills/cratis-engineering-csharp-conventions/references/exceptions-logging-and-di.md +5 -3
- package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +19 -6
- package/package/corpus/skills/cratis-fundamentals-concept/references/typescript-concepts.md +97 -0
- package/package/corpus/skills/cratis-fundamentals-concept/verification.json +4 -1
- package/package/corpus/skills/cratis-fundamentals-concept-go/SKILL.md +112 -0
- package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +54 -17
- package/package/corpus/skills/cratis-fundamentals-type-discovery/verification.json +14 -0
- package/package/corpus/skills/cratis-lens-browser-extension/SKILL.md +55 -28
- package/package/corpus/skills/cratis-performance-review/SKILL.md +5 -2
- package/package/corpus/skills/cratis-release-notes/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +5 -4
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +7 -11
- package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +26 -6
- package/package/corpus/skills/cratis-screenplay-command-surface/references/enum-numbers.md +4 -2
- package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +4 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +7 -1
- package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +3 -2
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +6 -2
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -0
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generate-notes.md +34 -4
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +17 -24
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +19 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +11 -3
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/property-links.md +90 -4
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +19 -2
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -1
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +48 -0
- package/package/corpus/skills/cratis-screenplay-specifications/verification.json +3 -1
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +4 -2
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +5 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +8 -6
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +8 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +4 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +7 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +24 -11
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +10 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1543 -131
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +9 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +23 -7
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +1 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +2 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +27 -9
- package/package/corpus/skills/cratis-security-review/SKILL.md +9 -3
- package/package/corpus/skills/cratis-security-review/references/arc-boundaries.md +59 -0
- package/package/corpus/skills/cratis-specification-by-example/SKILL.md +7 -0
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +43 -11
- package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +16 -4
- package/package/corpus/skills/cratis-specifications-csharp/references/csharp-patterns.md +18 -5
- package/package/corpus/skills/cratis-specifications-csharp/references/integration-specs.md +21 -0
- package/package/corpus/skills/cratis-specifications-csharp/references/shared-lifecycle.md +34 -0
- package/package/corpus/skills/cratis-specifications-csharp/verification.json +13 -0
- package/package/corpus/skills/cratis-specifications-typescript/SKILL.md +14 -5
- package/package/corpus/skills/cratis-specifications-typescript/verification.json +12 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +8 -2
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +6 -3
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +10 -1
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/scene-runtime.md +75 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +5 -0
- package/package/corpus/skills/cratis-studio-mcp-safety-guidance/SKILL.md +14 -1
- package/package/profile-catalog.json +68 -1
- package/package.json +1 -1
- package/src/index.ts +3 -1
|
@@ -11,13 +11,13 @@ third-party theme engine, preset or provider underneath it: what a Cratis
|
|
|
11
11
|
application looks like is decided by three Cratis-owned stylesheet entries and
|
|
12
12
|
the `--cratis-*` custom properties they read. Getting the setup wrong shows up as
|
|
13
13
|
components rendering completely unstyled, which is the single most common
|
|
14
|
-
first-run problem —
|
|
14
|
+
first-run problem — start by checking the CSS entry.
|
|
15
15
|
|
|
16
16
|
## Verified product sources
|
|
17
17
|
|
|
18
18
|
| Package | Version | Verified from |
|
|
19
19
|
| --- | --- | --- |
|
|
20
|
-
| `@cratis/components` | `4.
|
|
20
|
+
| `@cratis/components` | `4.26.4` | its package manifest (`exports`, no vendor UI dependency or peer), `Source/tokens.css`, `Source/MIGRATION.md`, `Documentation/Styling/*`, `Documentation/Common/cratis-components-provider.md`, `Documentation/renderers/*` |
|
|
21
21
|
|
|
22
22
|
Components declares **no** PrimeReact, PrimeIcons or PrimeUI dependency or peer.
|
|
23
23
|
React Aria supplies focus, overlay, collection and date behavior *internally* —
|
|
@@ -31,23 +31,39 @@ license are the application's.
|
|
|
31
31
|
|
|
32
32
|
Two things, or the components render unstyled:
|
|
33
33
|
|
|
34
|
-
1. **Import the stylesheets, in this order**,
|
|
34
|
+
1. **Import the stylesheets, in this order**, in `index.css`; the entry point
|
|
35
|
+
imports that file with `import './index.css'`:
|
|
35
36
|
|
|
36
|
-
```
|
|
37
|
-
import '@cratis/components/tokens';
|
|
38
|
-
import '@cratis/components/styles';
|
|
39
|
-
import '@cratis/components/theme';
|
|
37
|
+
```css
|
|
38
|
+
@import '@cratis/components/tokens';
|
|
39
|
+
@import '@cratis/components/styles';
|
|
40
|
+
@import '@cratis/components/theme'; /* optional baseline */
|
|
40
41
|
```
|
|
41
42
|
|
|
43
|
+
Direct CSS subpath imports from TypeScript need ambient declarations on
|
|
44
|
+
TypeScript 6, otherwise TS2882. To avoid the roughly 32 KiB gzip aggregate,
|
|
45
|
+
replace `styles` with `styles/base` and the needed `<subpath>/styles` entries
|
|
46
|
+
(for example `Dialogs/styles`, `DataTables/styles`). Area order does not matter.
|
|
47
|
+
|
|
42
48
|
`tokens` first — `styles` and `theme` both read it. `styles` also carries the
|
|
43
|
-
split-pane CSS the `DataPage` details pane needs
|
|
44
|
-
in a fully custom-styled app. `styles` contains **no** Tailwind Preflight, no
|
|
49
|
+
split-pane CSS the `DataPage` details pane needs; use the aggregate or the
|
|
50
|
+
corresponding area sheets even in a fully custom-styled app. `styles` contains **no** Tailwind Preflight, no
|
|
45
51
|
global reset and no copy of the token values.
|
|
46
52
|
|
|
47
53
|
2. **Mount `CratisComponentsProvider`** (from the package root,
|
|
48
54
|
`@cratis/components`) above every Cratis component. It carries `locale` and
|
|
49
55
|
the Components-owned `messages`, and mounts the toast region with `toaster`;
|
|
50
|
-
it carries **no**
|
|
56
|
+
it carries **no** theme. `toaster` accepts `boolean | ToasterProps`: without
|
|
57
|
+
it or a standalone `<Toaster />`, no toast appears; mount one, never both.
|
|
58
|
+
Message groups are `paginator`, `datePicker`, `dropdown`, `dialog`, `stepper`,
|
|
59
|
+
`notifications`, `dataTable`, `filter`, `columnFilter`, `toolbar`. `locales`
|
|
60
|
+
is deprecated. `value.icons` replaces `close`, `remove`, `expand`,
|
|
61
|
+
`sortAscending`, `sortDescending`, `previous`, `next`, `clear`; a component
|
|
62
|
+
prop wins over the provider, then the built-in glyph (`null` draws none).
|
|
63
|
+
`useCratisIcon()` resolves that vocabulary. Provider props also include
|
|
64
|
+
`overlayEnvironment`, `rendererSetup` (non-secret booleans), experimental
|
|
65
|
+
`libraryMode` (`strict` / `degrade`) and `rendererFallback` (`core` / `throw`).
|
|
66
|
+
The Components 3 renderer keys — `license`, `theme`,
|
|
51
67
|
`defaults`, global `pt`, `ptOptions`, `ripple`, `unstyled`, z-index — are a
|
|
52
68
|
type error on purpose, so a migrated app cannot compile a provider whose
|
|
53
69
|
visual configuration silently does nothing.
|
|
@@ -72,8 +88,10 @@ A theme is **CSS**. No JavaScript preset, provider option or wrapper class is
|
|
|
72
88
|
required for the normal whole-application setup. The product's CSS is written
|
|
73
89
|
*outside* a cascade layer, so it wins over all three Components layers
|
|
74
90
|
(`cratis-theme`, `cratis-components`, `cratis-utilities`) without specificity
|
|
75
|
-
tricks
|
|
76
|
-
the
|
|
91
|
+
tricks for structural rules. Tokens and theme are unlayered: their overrides
|
|
92
|
+
still need the correct specificity. If the product uses layers, name the
|
|
93
|
+
`cratis-*` layers in its **first** layer-order statement, before any stylesheet
|
|
94
|
+
(see Tailwind below).
|
|
77
95
|
|
|
78
96
|
### Baseline theme and dark mode
|
|
79
97
|
|
|
@@ -91,7 +109,14 @@ document.documentElement.classList.toggle('cratis-dark', darkMode);
|
|
|
91
109
|
wins over an ambient root `cratis-dark`.
|
|
92
110
|
- An independently themed island puts `cratis-theme` on the subtree and adds
|
|
93
111
|
`cratis-dark` or `cratis-light` there (on the same element, or on an ancestor).
|
|
94
|
-
-
|
|
112
|
+
- A plain `:root` override after `theme` loses to dark selectors such as
|
|
113
|
+
`:root.cratis-dark`, `.cratis-theme.cratis-dark`, and the system-dark
|
|
114
|
+
`:root:not(.cratis-light)`. Match the scheme selectors' specificity and place
|
|
115
|
+
overrides after the import, including subtree selectors when using islands.
|
|
116
|
+
Or omit `theme` and use the product-theme setup below.
|
|
117
|
+
- Components 4.22.1+ maps Arc's `--color-error` / `--color-error-bg` in both dark
|
|
118
|
+
schemes. A product theme omitting `theme` must define those variables itself;
|
|
119
|
+
do not carry forward the old dark-error contrast workaround.
|
|
95
120
|
|
|
96
121
|
### Product theme
|
|
97
122
|
|
|
@@ -188,7 +213,8 @@ The typed part families: `ButtonParts`/`IconButtonParts` (`root`, `icon`,
|
|
|
188
213
|
(`root`, `trigger`, `value`, `clear`, `indicator`, `popover`, `listbox`, `option`,
|
|
189
214
|
`filter`, `multiple`); `DataTableParts` (`root`, `search`, `searchInput`,
|
|
190
215
|
`tableContainer`, `table`, `head`, `headerRow`, `headerCell`, `body`, `row`,
|
|
191
|
-
`cell`, `emptyRow`, `emptyCell
|
|
216
|
+
`cell`, `emptyRow`, `emptyCell`, `loadingRow`, `loadingCell`, `failureRow`,
|
|
217
|
+
`failureCell`); `TablePaginatorParts` (`root`, `range`, `info`,
|
|
192
218
|
`first`, `previous`, `next`, `last`); `StepperParts` (`root`, `list`, `step`,
|
|
193
219
|
`header`, `number`, `title`, `separator`, `panels`, `panel`);
|
|
194
220
|
`ToasterPassThrough` (`region`, `toast`, `icon`, `content`, `title`,
|
|
@@ -218,7 +244,11 @@ The default renderer is built in; omit `library` on the provider. Three optional
|
|
|
218
244
|
adapter packages exist — `@cratis/components.mui` (MUI 9),
|
|
219
245
|
`@cratis/components.primereact` (PrimeReact 11), `@cratis/components.primereact10`
|
|
220
246
|
— and each adapts exactly **nine primitive slots**: button, icon-button, text
|
|
221
|
-
input, text area, checkbox, radio, switch, progress bar
|
|
247
|
+
input, text area, checkbox, radio, switch, progress bar (`common.progress`, not
|
|
248
|
+
`common.progressBar`), surface. Install and upgrade each adapter at **exactly
|
|
249
|
+
the same version** as `@cratis/components`; Node >=22 is required. The broader
|
|
250
|
+
renderer contract also has an atomic `common.tooltip` slot accepting any React
|
|
251
|
+
node, but it is not one of the nine stable presentation slots. Pass the
|
|
222
252
|
adapter's manifest to the provider's `library` prop. Dialogs, dropdowns, tables,
|
|
223
253
|
date pickers, tooltips, paginators, toasts and steppers stay Components-owned
|
|
224
254
|
regardless; an adapter never restores a vendor's public API, and the vendor's
|
|
@@ -232,16 +262,23 @@ Tailwind is **one supported way to write the CSS above, not the Cratis default.*
|
|
|
232
262
|
It is a fine tool for authoring the token mapping and part rules; it is not a
|
|
233
263
|
substitute for them. Components' own internal utilities are prefixed (`cratis:*`)
|
|
234
264
|
and are not public styling hooks. `styles` ships no Preflight and no reset of its
|
|
235
|
-
own
|
|
236
|
-
|
|
237
|
-
|
|
265
|
+
own. A host with layers must put this order in its **first** `@layer` statement,
|
|
266
|
+
parsed before any stylesheet (for example an inline `<style>` in the host):
|
|
267
|
+
|
|
268
|
+
```css
|
|
269
|
+
@layer properties, theme, base, cratis-theme, cratis-components, cratis-utilities, components, utilities;
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Components layers belong above the product reset and below product utilities.
|
|
273
|
+
Declaring them after the imports cannot reorder layers already established;
|
|
274
|
+
otherwise component rules beat product utilities and `pt` classes lose.
|
|
238
275
|
|
|
239
276
|
## Verify
|
|
240
277
|
|
|
241
278
|
- No PrimeReact / PrimeIcons / PrimeUI package remains in the manifest unless the
|
|
242
279
|
application itself imports it directly — and then it has its own provider.
|
|
243
|
-
- `CratisComponentsProvider` (root import) wraps the tree
|
|
244
|
-
|
|
280
|
+
- `CratisComponentsProvider` (root import) wraps the tree with locale/messages;
|
|
281
|
+
exactly one toaster is mounted when notifications are used.
|
|
245
282
|
- `@cratis/components/tokens` and `@cratis/components/styles` are imported once
|
|
246
283
|
at the entry point, tokens first; `theme` is imported or deliberately omitted;
|
|
247
284
|
product CSS comes after.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "cratis-components-styling",
|
|
3
|
+
"input": "Set up Components styles under host cascade layers and customize dark mode without breaking notifications.",
|
|
4
|
+
"fixtures": [],
|
|
5
|
+
"assertions": [
|
|
6
|
+
{ "kind": "skill-contains", "value": "@import '@cratis/components/tokens'" },
|
|
7
|
+
{ "kind": "skill-contains", "value": "first** `@layer` statement" },
|
|
8
|
+
{ "kind": "skill-contains", "value": "plain `:root` override after `theme` loses" },
|
|
9
|
+
{ "kind": "skill-contains", "value": "--color-error-bg" },
|
|
10
|
+
{ "kind": "skill-contains", "value": "mount one, never both" },
|
|
11
|
+
{ "kind": "skill-contains", "value": "common.progress`" }
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -9,15 +9,16 @@ license: MIT
|
|
|
9
9
|
The `Toolbar` family builds **canvas-style tool palettes** — the pill-shaped bar
|
|
10
10
|
of icon buttons you find in a drawing or diagram editor. For a page action menu
|
|
11
11
|
over a list, use `DataPage.MenuItems` instead (see the
|
|
12
|
-
**cratis-arc-react-page** skill).
|
|
12
|
+
**cratis-arc-react-page** skill). `ActionMenubar` (`Common`) shares the toolbar's
|
|
13
|
+
`focusMode` contract when building an action bar outside DataPage.
|
|
13
14
|
|
|
14
15
|
## Verified product sources
|
|
15
16
|
|
|
16
17
|
| Package | Version | Verified from |
|
|
17
18
|
| --- | --- | --- |
|
|
18
|
-
| `@cratis/components` | `4.
|
|
19
|
-
| `react-icons` | `5.7.0` | dependency of `@cratis/components@4.
|
|
20
|
-
| `react` | `^19.0.0` | peer of `@cratis/components@4.
|
|
19
|
+
| `@cratis/components` | `4.26.4` | its package manifest, `Source/Toolbar/*` (exports and props), `Documentation/Toolbar/*`, `Documentation/Common/icon.md` |
|
|
20
|
+
| `react-icons` | `5.7.0` | dependency of `@cratis/components@4.26.4` — the icon source the examples use |
|
|
21
|
+
| `react` | `^19.0.0` | peer of `@cratis/components@4.26.4` |
|
|
21
22
|
|
|
22
23
|
## Import from the subpath
|
|
23
24
|
|
|
@@ -28,7 +29,7 @@ is `<ToolbarGroup>`, never `<Toolbar.Group>`.
|
|
|
28
29
|
import {
|
|
29
30
|
Toolbar, ToolbarButton, ToolbarSeparator, ToolbarGroup,
|
|
30
31
|
ToolbarSection, ToolbarContext, ToolbarFanOutItem, ToolbarFolder,
|
|
31
|
-
ToolbarSlot, ToolbarSlotProvider, ToolbarLayout, useToolbarSlot,
|
|
32
|
+
ToolbarSlot, ToolbarSlotProvider, ToolbarLayout, useToolbarSlot, ToolbarFocusMode,
|
|
32
33
|
} from '@cratis/components/Toolbar';
|
|
33
34
|
```
|
|
34
35
|
|
|
@@ -86,6 +87,13 @@ const [activeTool, setActiveTool] = useState('select');
|
|
|
86
87
|
</Toolbar>
|
|
87
88
|
```
|
|
88
89
|
|
|
90
|
+
When `active` is supplied, `ToolbarButton` sets `aria-pressed`; omission keeps
|
|
91
|
+
it an ordinary button. `ToolbarFocusMode.Arrows` (default) enables arrows and
|
|
92
|
+
Home/End while keeping each tool's Tab stop. `SingleTabStop` uses the WAI-ARIA
|
|
93
|
+
pattern (returns to the last focused tool); custom widgets and explicit tab
|
|
94
|
+
indices retain their own behavior. `None` disables toolbar keyboard handling.
|
|
95
|
+
Name the toolbar with `aria-label` or `aria-labelledby`.
|
|
96
|
+
|
|
89
97
|
## Step 3 — Separators and horizontal layout
|
|
90
98
|
|
|
91
99
|
Give `ToolbarSeparator` the same `orientation` as its `Toolbar`, and move
|
|
@@ -157,6 +165,21 @@ away from the screen edge the toolbar sits against.
|
|
|
157
165
|
`mode` is `'grid'` (default) or `'list'`; `maxColumns` (default `5`) applies to
|
|
158
166
|
grid mode only, and `folderDirection` is `'right'` or `'left'`.
|
|
159
167
|
|
|
168
|
+
For a headed catalog use `presentation='drawer'` and `items` (children optional):
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<ToolbarFolder icon={<FaShapes />} title='Shapes' presentation='drawer'
|
|
172
|
+
items={[{ id: 'rect', title: 'Rectangle', icon: <FaVectorSquare />, payload: 'rect' }]}
|
|
173
|
+
onActivate={item => insertShape(item.payload)} />
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This excerpt assumes the host's `insertShape` and icons. Each `ToolbarDrawerItem`
|
|
177
|
+
has `id`, `title`, `icon`, `payload`, optional `disabled` and `disabledReason`.
|
|
178
|
+
`heading` defaults to `title`; `closeLabel` falls back to
|
|
179
|
+
`messages.toolbar.closeDrawer`, then English. `onItemDragStart/End` receive the
|
|
180
|
+
item and drag event; drawer tiles are `draggable` by default. `closeOnInsert`
|
|
181
|
+
(default false) closes on activation or successful drop, never cancelled drag.
|
|
182
|
+
|
|
160
183
|
## Step 6 — Contributing buttons from elsewhere
|
|
161
184
|
|
|
162
185
|
A slot lets a component far from the toolbar contribute buttons without prop
|
|
@@ -189,6 +212,9 @@ a `slotName`.
|
|
|
189
212
|
| --- | --- | --- |
|
|
190
213
|
| `children` | `ReactNode` | required |
|
|
191
214
|
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` |
|
|
215
|
+
| `focusMode` | `ToolbarFocusMode` (also exported by `Common`) | `Arrows` |
|
|
216
|
+
| `aria-label` / `aria-labelledby` | `string` | provider `messages.toolbar.label` fallback |
|
|
217
|
+
| `className` / `pt` | class / `ToolbarParts` | root presentation |
|
|
192
218
|
| `draggable` | `boolean` | `false` — makes child buttons draggable |
|
|
193
219
|
| `onItemDragStart` | `(data: unknown, event: React.DragEvent) => void` | — |
|
|
194
220
|
|
|
@@ -199,7 +225,8 @@ a `slotName`.
|
|
|
199
225
|
| `title` | `string` | **required** — the accessible name and the tooltip text |
|
|
200
226
|
| `icon` | `string \| ReactNode` | — |
|
|
201
227
|
| `text` | `string` | — |
|
|
202
|
-
| `active` | `boolean` | `
|
|
228
|
+
| `active` | `boolean` | when supplied, sets `aria-pressed` |
|
|
229
|
+
| `className` / `pt` | class / `ToolbarButtonParts` | per-instance presentation |
|
|
203
230
|
| `onClick` | `() => void` | — |
|
|
204
231
|
| `tooltipPosition` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` |
|
|
205
232
|
| `draggable` | `boolean` | inherited from the enclosing `Toolbar` |
|
|
@@ -236,7 +263,10 @@ Renders nothing itself — it is a marker `ToolbarSection` reads.
|
|
|
236
263
|
`tooltipPosition?` (default `'right'`) ·
|
|
237
264
|
`folderDirection?: 'right' | 'left'` (default `'right'`) ·
|
|
238
265
|
`mode?: 'grid' | 'list'` (default `'grid'`) · `maxColumns?: number` (default `5`) ·
|
|
239
|
-
`children
|
|
266
|
+
`children?: ReactNode` · `className?: string` · `pt?: ToolbarFolderParts`.
|
|
267
|
+
`presentation?: 'compact' | 'drawer'` (default compact), `heading`, `closeLabel`,
|
|
268
|
+
`items`, `onActivate`, `onItemDragStart/End`, `draggable`, `closeOnInsert` configure
|
|
269
|
+
the drawer described above (default `maxColumns` is 3 there).
|
|
240
270
|
|
|
241
271
|
### `ToolbarSlot` / `ToolbarSlotProvider` / `ToolbarLayout`
|
|
242
272
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "cratis-components-toolbar",
|
|
3
|
+
"input": "Build a keyboard-navigable toolbar with a drawer catalog and pressed-state buttons.",
|
|
4
|
+
"fixtures": [],
|
|
5
|
+
"assertions": [
|
|
6
|
+
{ "kind": "skill-contains", "value": "ToolbarFocusMode.Arrows" },
|
|
7
|
+
{ "kind": "skill-contains", "value": "SingleTabStop" },
|
|
8
|
+
{ "kind": "skill-contains", "value": "aria-pressed" },
|
|
9
|
+
{ "kind": "skill-contains", "value": "presentation='drawer'" },
|
|
10
|
+
{ "kind": "skill-contains", "value": "messages.toolbar.closeDrawer" }
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -11,6 +11,12 @@ repository. They are **conventions**, not framework contracts: nothing here is
|
|
|
11
11
|
enforced by an analyzer unless this skill says so. Follow them for consistency;
|
|
12
12
|
do not claim the framework requires them.
|
|
13
13
|
|
|
14
|
+
## Verified product sources
|
|
15
|
+
|
|
16
|
+
| Package | Version | Purpose |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `Cratis.Fundamentals` | `7.23.0` | DI lifetime attributes and `IInstancesOf<T>` instance resolution |
|
|
19
|
+
|
|
14
20
|
## Route near misses
|
|
15
21
|
|
|
16
22
|
- The question is what a Cratis product API *does*: resolve it against the
|
|
@@ -280,9 +280,11 @@ Rules:
|
|
|
280
280
|
- Never register a type that exists to be discovered. Mark it `[Singleton]`, or
|
|
281
281
|
rely on the `IFoo → Foo` convention for a transient, and delete the
|
|
282
282
|
registration line.
|
|
283
|
-
- `IInstancesOf<T>`
|
|
284
|
-
|
|
285
|
-
|
|
283
|
+
- `IInstancesOf<T>` fixes its type set at construction and resolves instances on
|
|
284
|
+
each enumeration through the consumer's provider (Fundamentals 7.23.0). Late
|
|
285
|
+
assemblies do not update that set. A singleton captures the root provider;
|
|
286
|
+
never use it to enumerate scoped implementations. Resolve a scoped or
|
|
287
|
+
transient consumer inside a scope instead; follow `csharp.md`'s lifetime rule.
|
|
286
288
|
- `IEnumerable<T>` remains the right type to **return** from a method that
|
|
287
289
|
yields a sequence of values. The rule applies only to enumerating
|
|
288
290
|
*implementations* of an abstraction.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cratis-fundamentals-concept
|
|
3
|
-
description: Create strongly typed Cratis domain values with ConceptAs and Chronicle event-source identities with EventSourceId. Use when a C# domain value has meaning beyond its primitive or when an identity is actually used as a Chronicle event-source/stream ID. Do not use for enums, DTO-only transport values, arbitrary non-stream entity IDs, or event schema migration.
|
|
3
|
+
description: Create strongly typed Cratis domain values with ConceptAs and Chronicle event-source identities with EventSourceId. Use when a C# or TypeScript domain value has meaning beyond its primitive or when an identity is actually used as a Chronicle event-source/stream ID. Do not use for enums, DTO-only transport values, arbitrary non-stream entity IDs, or event schema migration.
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -17,6 +17,7 @@ This skill is verified against these exact public releases:
|
|
|
17
17
|
| --- | --- | --- |
|
|
18
18
|
| `Cratis.Fundamentals` | `7.23.0` | `Cratis.Concepts.ConceptAs<T>`, `IGeneratable<TSelf>` and `GenerateValue` |
|
|
19
19
|
| `Cratis.Chronicle` | `18.3.0` | `Cratis.Chronicle.Events.EventSourceId` and `EventSourceId<T>` |
|
|
20
|
+
| `@cratis/fundamentals` | `7.23.0` | TypeScript `ConceptAs<T>`, `field`, `Guid`, and JSON conversion |
|
|
20
21
|
|
|
21
22
|
Reverify product sources before claiming support for another version.
|
|
22
23
|
|
|
@@ -81,7 +82,7 @@ Do not assume `string.Empty`, `0`, or `Guid.Empty` is universally invalid.
|
|
|
81
82
|
Check the Cratis.Fundamentals version the project resolves first. Arc first
|
|
82
83
|
pinned **7.23.0 in v22.66.0** (also verified at v22.68.0); the older-version
|
|
83
84
|
caveat is not a reason to add a direct reference for Arc 22.66.0+ when it already
|
|
84
|
-
resolves 7.23.0 or later. Chronicle **v19.
|
|
85
|
+
resolves 7.23.0 or later. Chronicle **v19.50.0** still pins **7.22.0** in
|
|
85
86
|
`Directory.Packages.props`. For older Arc or Chronicle-only applications, when
|
|
86
87
|
the resolved version is below 7.23.0, add a direct `Cratis.Fundamentals` 7.23.0
|
|
87
88
|
or later package reference, or keep the existing `static New()` (without the
|
|
@@ -133,6 +134,14 @@ it; see `cratis-arc-command` for declaration and migration, and
|
|
|
133
134
|
`cratis-specifications-csharp` for named scenario pins (Arc **22.67.0+**).
|
|
134
135
|
Guide: `/fundamentals/csharp/generating-values/`.
|
|
135
136
|
|
|
137
|
+
## Create a TypeScript value concept
|
|
138
|
+
|
|
139
|
+
Read [typescript-concepts.md](references/typescript-concepts.md) when declaring
|
|
140
|
+
TypeScript concepts, choosing union versus instance-only types, or converting
|
|
141
|
+
Guid-backed values with `@field` and `JsonSerializer`. A union accepts the raw
|
|
142
|
+
primitive too; it does not enforce nominal separation between domain values.
|
|
143
|
+
C#'s `IComparable` and null-value constraints above are not TypeScript contracts.
|
|
144
|
+
|
|
136
145
|
## Create a Guid-backed Chronicle stream identity
|
|
137
146
|
|
|
138
147
|
Use this shape only for an identity actually supplied to Chronicle append/read
|
|
@@ -203,10 +212,14 @@ untyped `EventSourceId`, and `EventSourceId<T>`. Those operators do not create
|
|
|
203
212
|
your derived `<ConceptName>` from `T`, string, or untyped `EventSourceId`.
|
|
204
213
|
Declare only the derived-type conversions your domain API needs.
|
|
205
214
|
|
|
206
|
-
String and Guid
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
215
|
+
String and Guid remain the safest stream-id primitives. At **Chronicle v19.50.0**
|
|
216
|
+
(`Source/Clients/DotNET/Events/EventSourceId.cs:148-174`), numeric/date/time ids
|
|
217
|
+
and concepts wrapping them convert with invariant culture (since 19.37.3).
|
|
218
|
+
`DateTime`, `DateTimeOffset`, `DateOnly`, `TimeOnly` use `"O"`; `TimeSpan` uses
|
|
219
|
+
`"c"`. Decimal `123.45` stays `"123.45"` even under nb-NO.
|
|
220
|
+
**Existing streams may have different legacy ids** if written under date/time or
|
|
221
|
+
decimal-comma formats: read/append them with their old untyped id, rather than
|
|
222
|
+
silently opening a new stream under the new format.
|
|
210
223
|
|
|
211
224
|
### Unspecified and sensitive identities
|
|
212
225
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
2
|
+
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
3
|
+
|
|
4
|
+
# TypeScript value concepts
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- Declare a concept
|
|
9
|
+
- Convert non-primitive values
|
|
10
|
+
- Serialization boundaries
|
|
11
|
+
- Other typed values
|
|
12
|
+
|
|
13
|
+
Verified against `@cratis/fundamentals` 7.23.0: `ConceptAs.ts`,
|
|
14
|
+
`JsonSerializer.ts`, and `Documentation/typescript/concept_as.md` in Fundamentals.
|
|
15
|
+
|
|
16
|
+
## Declare a concept
|
|
17
|
+
|
|
18
|
+
The convenient union pattern (7.13.0+) accepts either a concept instance or its
|
|
19
|
+
underlying primitive. Supply the runtime class, not the union type, to `@field`:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
23
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
24
|
+
|
|
25
|
+
import { ConceptAs, field, JsonSerializer } from '@cratis/fundamentals';
|
|
26
|
+
|
|
27
|
+
class UserIdConcept extends ConceptAs<string> {}
|
|
28
|
+
export type UserId = UserIdConcept | string;
|
|
29
|
+
|
|
30
|
+
class User {
|
|
31
|
+
@field(UserIdConcept)
|
|
32
|
+
id!: UserId;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const user = new User();
|
|
36
|
+
user.id = 'user-123';
|
|
37
|
+
const json = JsonSerializer.serialize(user);
|
|
38
|
+
const restored = JsonSerializer.deserialize(User, json);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`json` is `{"id":"user-123"}` and `restored.id` is a `UserIdConcept` instance.
|
|
42
|
+
The union is an assignment convenience, not nominal type safety: different
|
|
43
|
+
string-backed concepts still accept the same string. When callers must use
|
|
44
|
+
instances, export the class directly instead, as the Arc TypeScript validation
|
|
45
|
+
skill does with `Name`. `static readonly valueType = String` is valid but optional
|
|
46
|
+
for a string-backed concept; it does not require a different naming pattern.
|
|
47
|
+
|
|
48
|
+
## Convert non-primitive values
|
|
49
|
+
|
|
50
|
+
From 7.19.5, `valueType` tells deserialization to convert the inner payload before
|
|
51
|
+
constructing the concept. Without it, a Guid wire value remains a string:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
55
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
56
|
+
|
|
57
|
+
import { ConceptAs, field, Guid } from '@cratis/fundamentals';
|
|
58
|
+
|
|
59
|
+
class UserIdConcept extends ConceptAs<Guid> {
|
|
60
|
+
static readonly valueType = Guid;
|
|
61
|
+
}
|
|
62
|
+
export type UserId = UserIdConcept | Guid;
|
|
63
|
+
|
|
64
|
+
class User {
|
|
65
|
+
@field(UserIdConcept)
|
|
66
|
+
id!: UserId;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Serialization boundaries
|
|
71
|
+
|
|
72
|
+
Use `JsonSerializer.serialize(instance)` and
|
|
73
|
+
`JsonSerializer.deserialize(Type, json)` for typed conversion. Concepts serialize
|
|
74
|
+
to their inner value and deserialize to instances when their runtime class is
|
|
75
|
+
supplied as metadata. Collections and maps unwrap concepts too (7.17.0+).
|
|
76
|
+
|
|
77
|
+
Keep one resolved copy of `@cratis/fundamentals`: duplicate copies trigger a
|
|
78
|
+
warning and can cause identity/`instanceof` problems. The 7.23.0 serializer uses
|
|
79
|
+
stable type keys for concepts and converters, but that does not make all
|
|
80
|
+
cross-copy identity checks safe.
|
|
81
|
+
|
|
82
|
+
## Other typed values
|
|
83
|
+
|
|
84
|
+
The root exports `Guid`, `DateOnly`, `TimeOnly`, `TimeSpan`, `ValueMap`, `field`,
|
|
85
|
+
and `JsonSerializer`. Subpaths `/json`, `/geospatial`, and `/reflection` are
|
|
86
|
+
exported too. The package declarations support NodeNext resolution (7.19.6+).
|
|
87
|
+
Use `JsonSerializer.registerConverter(converter)` for a custom `JsonConverter`
|
|
88
|
+
instance, rather than replacing the serializer.
|
|
89
|
+
|
|
90
|
+
`@field` supports legacy and standard decorators (7.18.0+); standard fields need
|
|
91
|
+
decorator metadata support. Load `@cratis/fundamentals/reflection` before defining
|
|
92
|
+
metadata-dependent types. For arrays, declare the element constructor with
|
|
93
|
+
`@field(Array, { genericArguments: [Item] })`, where `Item` is the model's runtime
|
|
94
|
+
class, not a type alias (7.19.5+).
|
|
95
|
+
|
|
96
|
+
Dependent Arc/Chronicle peer ranges are not feature guarantees: check the actual
|
|
97
|
+
resolved Fundamentals version before relying on these version-qualified APIs.
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
{ "kind": "skill-contains", "value": "ConceptAs<T>" },
|
|
7
7
|
{ "kind": "skill-contains", "value": "IGeneratable<TSelf>" },
|
|
8
8
|
{ "kind": "skill-contains", "value": "GenerateValue.Uuid()" },
|
|
9
|
-
{ "kind": "skill-contains", "value": "not** monotonic within a" }
|
|
9
|
+
{ "kind": "skill-contains", "value": "not** monotonic within a" },
|
|
10
|
+
{ "kind": "skill-contains", "value": "@cratis/fundamentals" },
|
|
11
|
+
{ "kind": "skill-contains", "value": "typescript-concepts.md" },
|
|
12
|
+
{ "kind": "skill-contains", "value": "does not enforce nominal separation" }
|
|
10
13
|
]
|
|
11
14
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-fundamentals-concept-go
|
|
3
|
+
description: Define named Go domain values with Fundamentals.Go concepts, explicit UUID text and JSON codecs, and scalar recognition. Use when an identity or scalar must not be interchangeable with its primitive. Do not use for C# ConceptAs types, event migration or dependency-injection setup.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Go 1.26 or later for Fundamentals.Go v0.3.2.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
9
|
+
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
10
|
+
|
|
11
|
+
# Typed domain values in Go
|
|
12
|
+
|
|
13
|
+
> **Experimental v0:** Fundamentals.Go **v0.3.2**. Companion product guidance
|
|
14
|
+
> targets Chronicle.Go **v0.9.1** and Arc.Go **v0.1.1**; minor releases may break APIs.
|
|
15
|
+
|
|
16
|
+
Use a defined type for each domain value, not a type alias that remains
|
|
17
|
+
interchangeable with every UUID/string. Plain constructors are enough; adopting
|
|
18
|
+
concepts does not require a dependency-injection container.
|
|
19
|
+
|
|
20
|
+
## Verified product sources
|
|
21
|
+
|
|
22
|
+
| Product | Tag | Source checked |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| Fundamentals.Go (`github.com/cratis/fundamentals.go`) | `v0.3.2` | `concepts/concept.go`, `concepts/uuid.go`, `concepts/uuid_dotnet.go`, `concepts/underlying.go`, `concepts/check_json.go`, `documentation_examples_test.go` |
|
|
25
|
+
|
|
26
|
+
[Source at v0.3.2](https://github.com/Cratis/Fundamentals.Go/tree/v0.3.2)
|
|
27
|
+
is authoritative, not the getting-started page's older v0.3.0 installation pin.
|
|
28
|
+
The root module is standard-library-only and requires Go 1.26.
|
|
29
|
+
|
|
30
|
+
## Define and encode an identity
|
|
31
|
+
|
|
32
|
+
Install `github.com/cratis/fundamentals.go@v0.3.2` into a consumer module.
|
|
33
|
+
This complete package defines an author identity and its codecs:
|
|
34
|
+
|
|
35
|
+
```go
|
|
36
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
37
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
38
|
+
|
|
39
|
+
package domain
|
|
40
|
+
|
|
41
|
+
import "github.com/cratis/fundamentals.go/concepts"
|
|
42
|
+
|
|
43
|
+
// AuthorID identifies an author in the domain.
|
|
44
|
+
type AuthorID concepts.UUID
|
|
45
|
+
|
|
46
|
+
var _ concepts.Concept[concepts.UUID] = AuthorID{}
|
|
47
|
+
|
|
48
|
+
// ConceptValue exposes the declared scalar representation.
|
|
49
|
+
func (id AuthorID) ConceptValue() concepts.UUID { return concepts.UUID(id) }
|
|
50
|
+
|
|
51
|
+
// MarshalText encodes canonical dashed UUID text.
|
|
52
|
+
func (id AuthorID) MarshalText() ([]byte, error) {
|
|
53
|
+
return concepts.UUID(id).MarshalText()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// MarshalJSON encodes a UUID string, not a byte array.
|
|
57
|
+
func (id AuthorID) MarshalJSON() ([]byte, error) {
|
|
58
|
+
return concepts.UUID(id).MarshalJSON()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// UnmarshalText decodes UUID text without changing id on failure.
|
|
62
|
+
func (id *AuthorID) UnmarshalText(data []byte) error {
|
|
63
|
+
return (*concepts.UUID)(id).UnmarshalText(data)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// UnmarshalJSON decodes a UUID string without changing id on failure.
|
|
67
|
+
func (id *AuthorID) UnmarshalJSON(data []byte) error {
|
|
68
|
+
return (*concepts.UUID)(id).UnmarshalJSON(data)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ParseAuthorID reads an identity in dashed UUID notation.
|
|
72
|
+
func ParseAuthorID(text string) (AuthorID, error) {
|
|
73
|
+
id, err := concepts.ParseUUID(text)
|
|
74
|
+
return AuthorID(id), err
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Defined types do **not** inherit methods. Without these forwarding codecs, a
|
|
79
|
+
UUID-derived value can serialize as an array. Value encoding receivers also work
|
|
80
|
+
for unaddressable map entries; decoding needs a pointer receiver. Test text,
|
|
81
|
+
JSON, map-key and invalid-input round trips, not just the marker assertion.
|
|
82
|
+
|
|
83
|
+
`ParseUUID` accepts dashed 8-4-4-4-12 notation, including uppercase hex, and emits
|
|
84
|
+
lowercase dashed text. UUID bytes are RFC/network order, not .NET
|
|
85
|
+
`Guid.ToByteArray` order. Zero is `Guid.Empty`; UUID JSON decoding rejects `null`.
|
|
86
|
+
Use an explicit nullable representation when absence is part of the contract.
|
|
87
|
+
`NewUUID` returns a cryptographically random v4 UUID **and an error**.
|
|
88
|
+
|
|
89
|
+
## Recognition is not business validation
|
|
90
|
+
|
|
91
|
+
`Concept[T]` declares `ConceptValue() T`. A recognized declaration also needs
|
|
92
|
+
value text/JSON encoders and pointer decoders representing that scalar. Supported
|
|
93
|
+
representations are the built-in string/bool/numeric types and Fundamentals'
|
|
94
|
+
`UUID`, `DateOnly`, `TimeOnly`, `TimeSpan`; arbitrary defined replacements are not
|
|
95
|
+
accepted as scalar representations.
|
|
96
|
+
|
|
97
|
+
`Underlying` checks declaration metadata without running application code.
|
|
98
|
+
`CheckJSON` checks encoded scalar shape, not business invariants or equality to
|
|
99
|
+
`ConceptValue`. Put domain rules in your constructor/validation boundary and test
|
|
100
|
+
them; do not assume implementing a marker validates input everywhere.
|
|
101
|
+
|
|
102
|
+
`ParseDotNetGUID` is an opt-in compatibility parser for broader .NET forms. It
|
|
103
|
+
does not change `ParseUUID` or text/JSON/SQL codecs. Limit untrusted input and use
|
|
104
|
+
it only when importing that compatibility contract, not for canonical admission.
|
|
105
|
+
|
|
106
|
+
## Verify
|
|
107
|
+
|
|
108
|
+
- Compile and round-trip the named value against the pinned module without local replacements.
|
|
109
|
+
- Verify canonical wire bytes, zero/null policy and failure-atomic decoders.
|
|
110
|
+
- Check domain invariants separately from scalar recognition.
|
|
111
|
+
- Chronicle.Go v0.9.1 and Arc.Go v0.1.1 each require Fundamentals.Go v0.1.0;
|
|
112
|
+
this standalone v0.3.2 example is not a demand to upgrade their dependencies.
|