codexkit 1.0.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/.codex/.env.example +27 -0
- package/.codex/.template-manifest.json +631 -0
- package/.codex/.version +1 -0
- package/.codex/agents/builder.toml +104 -0
- package/.codex/agents/debugger.toml +67 -0
- package/.codex/agents/general.toml +41 -0
- package/.codex/agents/painter.toml +40 -0
- package/.codex/agents/planner.toml +60 -0
- package/.codex/agents/refactorer.toml +76 -0
- package/.codex/agents/reviewer.toml +60 -0
- package/.codex/agents/runner.toml +40 -0
- package/.codex/agents/scout.toml +133 -0
- package/.codex/agents/shipper.toml +69 -0
- package/.codex/agents/vision.toml +69 -0
- package/.codex/config.toml +146 -0
- package/.codex/context/architecture.md +66 -0
- package/.codex/context/conventions.md +98 -0
- package/.codex/context/current-priorities.md +33 -0
- package/.codex/context/decision-log.md +93 -0
- package/.codex/context/gotchas.md +42 -0
- package/.codex/context/index.md +21 -0
- package/.codex/context/session-context.md +11 -0
- package/.codex/context/worklog.md +9 -0
- package/.codex/hooks/README.md +17 -0
- package/.codex/hooks/after_agent.sh +11 -0
- package/.codex/hooks/after_tool_use.sh +10 -0
- package/.codex/hooks/post_commit.sh +10 -0
- package/.codex/hooks/pre_commit.sh +6 -0
- package/.codex/hooks/session_start.sh +18 -0
- package/.codex/hooks/stop.sh +10 -0
- package/.codex/mcp/README.md +143 -0
- package/.codex/mcp/basic-memory.toml.example +10 -0
- package/.codex/mcp/context7.toml.example +13 -0
- package/.codex/mcp/exa.toml.example +12 -0
- package/.codex/mcp/memory-bridge.toml.example +15 -0
- package/.codex/mcp/memory.toml.example +6 -0
- package/.codex/mcp/ref.toml.example +13 -0
- package/.codex/mcp/tilth.toml.example +10 -0
- package/.codex/memory/README.md +29 -0
- package/.codex/memory/_templates/README.md +26 -0
- package/.codex/memory/_templates/design.md +15 -0
- package/.codex/memory/_templates/gotcha.md +9 -0
- package/.codex/memory/_templates/handoff.md +9 -0
- package/.codex/memory/_templates/prd.md +13 -0
- package/.codex/memory/_templates/project.md +9 -0
- package/.codex/memory/_templates/proposal.md +13 -0
- package/.codex/memory/_templates/research.md +9 -0
- package/.codex/memory/_templates/roadmap.md +11 -0
- package/.codex/memory/_templates/session-context.md +7 -0
- package/.codex/memory/_templates/state.md +11 -0
- package/.codex/memory/_templates/tasks.md +9 -0
- package/.codex/memory/_templates/tech-stack.md +9 -0
- package/.codex/memory/_templates/user.md +7 -0
- package/.codex/memory/project/gotchas.md +5 -0
- package/.codex/memory/project/project.md +12 -0
- package/.codex/memory/project/roadmap.md +15 -0
- package/.codex/memory/project/state.md +22 -0
- package/.codex/memory/project/tech-stack.md +19 -0
- package/.codex/memory/project/user.md +10 -0
- package/.codex/memory/research/.gitkeep +1 -0
- package/.codex/memory/session-context.md +18 -0
- package/.codex/plans/README.md +7 -0
- package/.codex/prompts/compound.md +154 -0
- package/.codex/prompts/create.md +238 -0
- package/.codex/prompts/design.md +90 -0
- package/.codex/prompts/handoff.md +184 -0
- package/.codex/prompts/init-context.md +185 -0
- package/.codex/prompts/init-user.md +93 -0
- package/.codex/prompts/init.md +103 -0
- package/.codex/prompts/lfg.md +140 -0
- package/.codex/prompts/plan.md +140 -0
- package/.codex/prompts/pr.md +150 -0
- package/.codex/prompts/research.md +137 -0
- package/.codex/prompts/resume.md +105 -0
- package/.codex/prompts/review-codebase.md +147 -0
- package/.codex/prompts/ship.md +334 -0
- package/.codex/prompts/start.md +141 -0
- package/.codex/prompts/status.md +102 -0
- package/.codex/prompts/ui-inspire.md +151 -0
- package/.codex/prompts/ui-review.md +86 -0
- package/.codex/prompts/verify.md +181 -0
- package/.codex/scripts/append_worklog.sh +20 -0
- package/.codex/scripts/apply_worklog_archive.sh +48 -0
- package/.codex/scripts/audit_memory_hygiene.sh +102 -0
- package/.codex/scripts/build_memory_index.sh +167 -0
- package/.codex/scripts/build_prior_related_work.sh +127 -0
- package/.codex/scripts/build_startup_brief.sh +52 -0
- package/.codex/scripts/close_bead.sh +103 -0
- package/.codex/scripts/detect_changed_files.sh +38 -0
- package/.codex/scripts/ensure_beads.sh +14 -0
- package/.codex/scripts/memory_search.sh +292 -0
- package/.codex/scripts/prepare_worklog_archive.sh +115 -0
- package/.codex/scripts/search_bead_context.sh +214 -0
- package/.codex/scripts/start_bead.sh +129 -0
- package/.codex/scripts/sync_bead_context.sh +288 -0
- package/.codex/scripts/validate_memory_docs.sh +44 -0
- package/.codex/scripts/verify_bead.sh +154 -0
- package/.codex/skills/accessibility-audit/SKILL.md +191 -0
- package/.codex/skills/agent-browser/SKILL.md +413 -0
- package/.codex/skills/agent-teams/SKILL.md +268 -0
- package/.codex/skills/augment-context-engine/SKILL.md +115 -0
- package/.codex/skills/augment-context-engine/mcp.json +6 -0
- package/.codex/skills/beads/SKILL.md +181 -0
- package/.codex/skills/beads/references/BEST_PRACTICES.md +27 -0
- package/.codex/skills/beads/references/BOUNDARIES.md +219 -0
- package/.codex/skills/beads/references/DEPENDENCIES.md +124 -0
- package/.codex/skills/beads/references/EXAMPLES.md +45 -0
- package/.codex/skills/beads/references/FILE_CLAIMING.md +101 -0
- package/.codex/skills/beads/references/GIT_SYNC.md +25 -0
- package/.codex/skills/beads/references/HIERARCHY.md +71 -0
- package/.codex/skills/beads/references/MULTI_AGENT.md +40 -0
- package/.codex/skills/beads/references/RESUMABILITY.md +177 -0
- package/.codex/skills/beads/references/SESSION_PROTOCOL.md +61 -0
- package/.codex/skills/beads/references/TASK_CREATION.md +38 -0
- package/.codex/skills/beads/references/TROUBLESHOOTING.md +38 -0
- package/.codex/skills/beads/references/WORKFLOWS.md +226 -0
- package/.codex/skills/beads-bridge/SKILL.md +321 -0
- package/.codex/skills/brainstorming/SKILL.md +114 -0
- package/.codex/skills/bug-triage/SKILL.md +191 -0
- package/.codex/skills/chrome-devtools/SKILL.md +76 -0
- package/.codex/skills/chrome-devtools/mcp.json +19 -0
- package/.codex/skills/cloudflare/SKILL.md +253 -0
- package/.codex/skills/cloudflare/references/agents-sdk/README.md +35 -0
- package/.codex/skills/cloudflare/references/agents-sdk/api.md +100 -0
- package/.codex/skills/cloudflare/references/agents-sdk/configuration.md +99 -0
- package/.codex/skills/cloudflare/references/agents-sdk/gotchas.md +59 -0
- package/.codex/skills/cloudflare/references/agents-sdk/patterns.md +89 -0
- package/.codex/skills/cloudflare/references/ai-gateway/README.md +695 -0
- package/.codex/skills/cloudflare/references/ai-search/README.md +14 -0
- package/.codex/skills/cloudflare/references/ai-search/api.md +38 -0
- package/.codex/skills/cloudflare/references/ai-search/configuration.md +52 -0
- package/.codex/skills/cloudflare/references/ai-search/gotchas.md +41 -0
- package/.codex/skills/cloudflare/references/ai-search/patterns.md +45 -0
- package/.codex/skills/cloudflare/references/analytics-engine/README.md +14 -0
- package/.codex/skills/cloudflare/references/analytics-engine/api.md +27 -0
- package/.codex/skills/cloudflare/references/analytics-engine/configuration.md +45 -0
- package/.codex/skills/cloudflare/references/analytics-engine/gotchas.md +3 -0
- package/.codex/skills/cloudflare/references/analytics-engine/patterns.md +36 -0
- package/.codex/skills/cloudflare/references/api/README.md +21 -0
- package/.codex/skills/cloudflare/references/api/api.md +31 -0
- package/.codex/skills/cloudflare/references/api/configuration.md +20 -0
- package/.codex/skills/cloudflare/references/api/gotchas.md +28 -0
- package/.codex/skills/cloudflare/references/api/patterns.md +47 -0
- package/.codex/skills/cloudflare/references/api-shield/README.md +20 -0
- package/.codex/skills/cloudflare/references/api-shield/api.md +78 -0
- package/.codex/skills/cloudflare/references/api-shield/configuration.md +128 -0
- package/.codex/skills/cloudflare/references/api-shield/gotchas.md +51 -0
- package/.codex/skills/cloudflare/references/api-shield/patterns.md +145 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/README.md +16 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/api.md +50 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/configuration.md +53 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/gotchas.md +16 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/patterns.md +45 -0
- package/.codex/skills/cloudflare/references/bindings/README.md +14 -0
- package/.codex/skills/cloudflare/references/bindings/api.md +3 -0
- package/.codex/skills/cloudflare/references/bindings/configuration.md +58 -0
- package/.codex/skills/cloudflare/references/bindings/gotchas.md +35 -0
- package/.codex/skills/cloudflare/references/bindings/patterns.md +37 -0
- package/.codex/skills/cloudflare/references/bot-management/README.md +71 -0
- package/.codex/skills/cloudflare/references/bot-management/api.md +168 -0
- package/.codex/skills/cloudflare/references/bot-management/configuration.md +114 -0
- package/.codex/skills/cloudflare/references/bot-management/gotchas.md +99 -0
- package/.codex/skills/cloudflare/references/bot-management/patterns.md +125 -0
- package/.codex/skills/cloudflare/references/browser-rendering/README.md +16 -0
- package/.codex/skills/cloudflare/references/browser-rendering/api.md +54 -0
- package/.codex/skills/cloudflare/references/browser-rendering/configuration.md +47 -0
- package/.codex/skills/cloudflare/references/browser-rendering/gotchas.md +29 -0
- package/.codex/skills/cloudflare/references/browser-rendering/patterns.md +29 -0
- package/.codex/skills/cloudflare/references/c3/README.md +264 -0
- package/.codex/skills/cloudflare/references/cache-reserve/README.md +93 -0
- package/.codex/skills/cloudflare/references/cache-reserve/api.md +176 -0
- package/.codex/skills/cloudflare/references/cache-reserve/configuration.md +164 -0
- package/.codex/skills/cloudflare/references/cache-reserve/gotchas.md +203 -0
- package/.codex/skills/cloudflare/references/cache-reserve/patterns.md +180 -0
- package/.codex/skills/cloudflare/references/containers/README.md +16 -0
- package/.codex/skills/cloudflare/references/containers/api.md +43 -0
- package/.codex/skills/cloudflare/references/containers/configuration.md +56 -0
- package/.codex/skills/cloudflare/references/containers/gotchas.md +21 -0
- package/.codex/skills/cloudflare/references/containers/patterns.md +40 -0
- package/.codex/skills/cloudflare/references/cron-triggers/README.md +85 -0
- package/.codex/skills/cloudflare/references/cron-triggers/api.md +198 -0
- package/.codex/skills/cloudflare/references/cron-triggers/configuration.md +151 -0
- package/.codex/skills/cloudflare/references/cron-triggers/gotchas.md +129 -0
- package/.codex/skills/cloudflare/references/cron-triggers/patterns.md +122 -0
- package/.codex/skills/cloudflare/references/d1/README.md +92 -0
- package/.codex/skills/cloudflare/references/d1/api.md +141 -0
- package/.codex/skills/cloudflare/references/d1/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/d1/gotchas.md +70 -0
- package/.codex/skills/cloudflare/references/d1/patterns.md +144 -0
- package/.codex/skills/cloudflare/references/ddos/README.md +34 -0
- package/.codex/skills/cloudflare/references/ddos/api.md +136 -0
- package/.codex/skills/cloudflare/references/ddos/configuration.md +67 -0
- package/.codex/skills/cloudflare/references/ddos/gotchas.md +114 -0
- package/.codex/skills/cloudflare/references/ddos/patterns.md +158 -0
- package/.codex/skills/cloudflare/references/do-storage/README.md +62 -0
- package/.codex/skills/cloudflare/references/do-storage/api.md +89 -0
- package/.codex/skills/cloudflare/references/do-storage/configuration.md +116 -0
- package/.codex/skills/cloudflare/references/do-storage/gotchas.md +93 -0
- package/.codex/skills/cloudflare/references/do-storage/patterns.md +112 -0
- package/.codex/skills/cloudflare/references/durable-objects/README.md +125 -0
- package/.codex/skills/cloudflare/references/durable-objects/api.md +152 -0
- package/.codex/skills/cloudflare/references/durable-objects/configuration.md +148 -0
- package/.codex/skills/cloudflare/references/durable-objects/gotchas.md +158 -0
- package/.codex/skills/cloudflare/references/durable-objects/patterns.md +255 -0
- package/.codex/skills/cloudflare/references/email-routing/README.md +18 -0
- package/.codex/skills/cloudflare/references/email-routing/api.md +46 -0
- package/.codex/skills/cloudflare/references/email-routing/configuration.md +63 -0
- package/.codex/skills/cloudflare/references/email-routing/gotchas.md +16 -0
- package/.codex/skills/cloudflare/references/email-routing/patterns.md +46 -0
- package/.codex/skills/cloudflare/references/email-workers/README.md +598 -0
- package/.codex/skills/cloudflare/references/hyperdrive/README.md +62 -0
- package/.codex/skills/cloudflare/references/hyperdrive/api.md +137 -0
- package/.codex/skills/cloudflare/references/hyperdrive/configuration.md +133 -0
- package/.codex/skills/cloudflare/references/hyperdrive/gotchas.md +184 -0
- package/.codex/skills/cloudflare/references/hyperdrive/patterns.md +176 -0
- package/.codex/skills/cloudflare/references/images/README.md +14 -0
- package/.codex/skills/cloudflare/references/images/api.md +3 -0
- package/.codex/skills/cloudflare/references/images/configuration.md +45 -0
- package/.codex/skills/cloudflare/references/images/gotchas.md +23 -0
- package/.codex/skills/cloudflare/references/images/patterns.md +31 -0
- package/.codex/skills/cloudflare/references/kv/README.md +60 -0
- package/.codex/skills/cloudflare/references/kv/api.md +114 -0
- package/.codex/skills/cloudflare/references/kv/configuration.md +92 -0
- package/.codex/skills/cloudflare/references/kv/gotchas.md +117 -0
- package/.codex/skills/cloudflare/references/kv/patterns.md +139 -0
- package/.codex/skills/cloudflare/references/miniflare/README.md +64 -0
- package/.codex/skills/cloudflare/references/miniflare/api.md +144 -0
- package/.codex/skills/cloudflare/references/miniflare/configuration.md +203 -0
- package/.codex/skills/cloudflare/references/miniflare/gotchas.md +187 -0
- package/.codex/skills/cloudflare/references/miniflare/patterns.md +211 -0
- package/.codex/skills/cloudflare/references/network-interconnect/README.md +60 -0
- package/.codex/skills/cloudflare/references/network-interconnect/api.md +240 -0
- package/.codex/skills/cloudflare/references/network-interconnect/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/network-interconnect/gotchas.md +171 -0
- package/.codex/skills/cloudflare/references/network-interconnect/patterns.md +171 -0
- package/.codex/skills/cloudflare/references/observability/README.md +18 -0
- package/.codex/skills/cloudflare/references/observability/api.md +51 -0
- package/.codex/skills/cloudflare/references/observability/configuration.md +60 -0
- package/.codex/skills/cloudflare/references/observability/gotchas.md +36 -0
- package/.codex/skills/cloudflare/references/observability/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/pages/README.md +76 -0
- package/.codex/skills/cloudflare/references/pages/api.md +200 -0
- package/.codex/skills/cloudflare/references/pages/configuration.md +228 -0
- package/.codex/skills/cloudflare/references/pages/gotchas.md +161 -0
- package/.codex/skills/cloudflare/references/pages/patterns.md +145 -0
- package/.codex/skills/cloudflare/references/pages-functions/README.md +57 -0
- package/.codex/skills/cloudflare/references/pages-functions/api.md +201 -0
- package/.codex/skills/cloudflare/references/pages-functions/configuration.md +159 -0
- package/.codex/skills/cloudflare/references/pages-functions/gotchas.md +151 -0
- package/.codex/skills/cloudflare/references/pages-functions/patterns.md +190 -0
- package/.codex/skills/cloudflare/references/pipelines/README.md +664 -0
- package/.codex/skills/cloudflare/references/pulumi/README.md +107 -0
- package/.codex/skills/cloudflare/references/pulumi/api.md +194 -0
- package/.codex/skills/cloudflare/references/pulumi/configuration.md +216 -0
- package/.codex/skills/cloudflare/references/pulumi/gotchas.md +223 -0
- package/.codex/skills/cloudflare/references/pulumi/patterns.md +139 -0
- package/.codex/skills/cloudflare/references/queues/README.md +69 -0
- package/.codex/skills/cloudflare/references/queues/api.md +138 -0
- package/.codex/skills/cloudflare/references/queues/configuration.md +125 -0
- package/.codex/skills/cloudflare/references/queues/gotchas.md +112 -0
- package/.codex/skills/cloudflare/references/queues/patterns.md +155 -0
- package/.codex/skills/cloudflare/references/r2/README.md +61 -0
- package/.codex/skills/cloudflare/references/r2/api.md +127 -0
- package/.codex/skills/cloudflare/references/r2/configuration.md +76 -0
- package/.codex/skills/cloudflare/references/r2/gotchas.md +94 -0
- package/.codex/skills/cloudflare/references/r2/patterns.md +127 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/README.md +18 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/api.md +29 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/configuration.md +39 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/gotchas.md +20 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/patterns.md +46 -0
- package/.codex/skills/cloudflare/references/r2-sql/README.md +512 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/README.md +21 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/api.md +135 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/configuration.md +63 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/gotchas.md +75 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/patterns.md +102 -0
- package/.codex/skills/cloudflare/references/realtimekit/README.md +81 -0
- package/.codex/skills/cloudflare/references/realtimekit/api.md +164 -0
- package/.codex/skills/cloudflare/references/realtimekit/configuration.md +147 -0
- package/.codex/skills/cloudflare/references/realtimekit/gotchas.md +172 -0
- package/.codex/skills/cloudflare/references/realtimekit/patterns.md +155 -0
- package/.codex/skills/cloudflare/references/sandbox/README.md +90 -0
- package/.codex/skills/cloudflare/references/sandbox/api.md +178 -0
- package/.codex/skills/cloudflare/references/sandbox/configuration.md +131 -0
- package/.codex/skills/cloudflare/references/sandbox/gotchas.md +156 -0
- package/.codex/skills/cloudflare/references/sandbox/patterns.md +203 -0
- package/.codex/skills/cloudflare/references/secrets-store/README.md +58 -0
- package/.codex/skills/cloudflare/references/secrets-store/api.md +182 -0
- package/.codex/skills/cloudflare/references/secrets-store/configuration.md +140 -0
- package/.codex/skills/cloudflare/references/secrets-store/gotchas.md +129 -0
- package/.codex/skills/cloudflare/references/secrets-store/patterns.md +218 -0
- package/.codex/skills/cloudflare/references/smart-placement/README.md +91 -0
- package/.codex/skills/cloudflare/references/smart-placement/api.md +139 -0
- package/.codex/skills/cloudflare/references/smart-placement/configuration.md +129 -0
- package/.codex/skills/cloudflare/references/smart-placement/gotchas.md +87 -0
- package/.codex/skills/cloudflare/references/smart-placement/patterns.md +135 -0
- package/.codex/skills/cloudflare/references/snippets/README.md +15 -0
- package/.codex/skills/cloudflare/references/snippets/api.md +47 -0
- package/.codex/skills/cloudflare/references/snippets/configuration.md +33 -0
- package/.codex/skills/cloudflare/references/snippets/gotchas.md +21 -0
- package/.codex/skills/cloudflare/references/snippets/patterns.md +34 -0
- package/.codex/skills/cloudflare/references/spectrum/README.md +16 -0
- package/.codex/skills/cloudflare/references/spectrum/api.md +24 -0
- package/.codex/skills/cloudflare/references/spectrum/configuration.md +43 -0
- package/.codex/skills/cloudflare/references/spectrum/gotchas.md +42 -0
- package/.codex/skills/cloudflare/references/spectrum/patterns.md +40 -0
- package/.codex/skills/cloudflare/references/static-assets/README.md +14 -0
- package/.codex/skills/cloudflare/references/static-assets/api.md +3 -0
- package/.codex/skills/cloudflare/references/static-assets/configuration.md +47 -0
- package/.codex/skills/cloudflare/references/static-assets/gotchas.md +44 -0
- package/.codex/skills/cloudflare/references/static-assets/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/stream/README.md +103 -0
- package/.codex/skills/cloudflare/references/stream/api.md +204 -0
- package/.codex/skills/cloudflare/references/stream/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/stream/gotchas.md +131 -0
- package/.codex/skills/cloudflare/references/stream/patterns.md +152 -0
- package/.codex/skills/cloudflare/references/tail-workers/README.md +640 -0
- package/.codex/skills/cloudflare/references/terraform/README.md +76 -0
- package/.codex/skills/cloudflare/references/terraform/api.md +159 -0
- package/.codex/skills/cloudflare/references/terraform/configuration.md +156 -0
- package/.codex/skills/cloudflare/references/terraform/gotchas.md +207 -0
- package/.codex/skills/cloudflare/references/terraform/patterns.md +135 -0
- package/.codex/skills/cloudflare/references/tunnel/README.md +82 -0
- package/.codex/skills/cloudflare/references/tunnel/api.md +105 -0
- package/.codex/skills/cloudflare/references/tunnel/configuration.md +113 -0
- package/.codex/skills/cloudflare/references/tunnel/gotchas.md +115 -0
- package/.codex/skills/cloudflare/references/tunnel/patterns.md +157 -0
- package/.codex/skills/cloudflare/references/turn/README.md +699 -0
- package/.codex/skills/cloudflare/references/turnstile/README.md +14 -0
- package/.codex/skills/cloudflare/references/turnstile/api.md +3 -0
- package/.codex/skills/cloudflare/references/turnstile/configuration.md +19 -0
- package/.codex/skills/cloudflare/references/turnstile/gotchas.md +27 -0
- package/.codex/skills/cloudflare/references/turnstile/patterns.md +41 -0
- package/.codex/skills/cloudflare/references/vectorize/README.md +682 -0
- package/.codex/skills/cloudflare/references/waf/README.md +14 -0
- package/.codex/skills/cloudflare/references/waf/api.md +3 -0
- package/.codex/skills/cloudflare/references/waf/configuration.md +44 -0
- package/.codex/skills/cloudflare/references/waf/gotchas.md +24 -0
- package/.codex/skills/cloudflare/references/waf/patterns.md +29 -0
- package/.codex/skills/cloudflare/references/web-analytics/README.md +19 -0
- package/.codex/skills/cloudflare/references/web-analytics/api.md +52 -0
- package/.codex/skills/cloudflare/references/web-analytics/configuration.md +31 -0
- package/.codex/skills/cloudflare/references/web-analytics/gotchas.md +28 -0
- package/.codex/skills/cloudflare/references/web-analytics/patterns.md +52 -0
- package/.codex/skills/cloudflare/references/workerd/README.md +47 -0
- package/.codex/skills/cloudflare/references/workerd/api.md +199 -0
- package/.codex/skills/cloudflare/references/workerd/configuration.md +185 -0
- package/.codex/skills/cloudflare/references/workerd/gotchas.md +203 -0
- package/.codex/skills/cloudflare/references/workerd/patterns.md +216 -0
- package/.codex/skills/cloudflare/references/workers/README.md +96 -0
- package/.codex/skills/cloudflare/references/workers/api.md +137 -0
- package/.codex/skills/cloudflare/references/workers/configuration.md +147 -0
- package/.codex/skills/cloudflare/references/workers/gotchas.md +99 -0
- package/.codex/skills/cloudflare/references/workers/patterns.md +149 -0
- package/.codex/skills/cloudflare/references/workers-ai/README.md +116 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/README.md +48 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/api.md +169 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/configuration.md +136 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/gotchas.md +130 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/patterns.md +170 -0
- package/.codex/skills/cloudflare/references/workers-playground/README.md +16 -0
- package/.codex/skills/cloudflare/references/workers-playground/api.md +20 -0
- package/.codex/skills/cloudflare/references/workers-playground/configuration.md +3 -0
- package/.codex/skills/cloudflare/references/workers-playground/gotchas.md +35 -0
- package/.codex/skills/cloudflare/references/workers-playground/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/workers-vpc/README.md +579 -0
- package/.codex/skills/cloudflare/references/workflows/README.md +62 -0
- package/.codex/skills/cloudflare/references/workflows/api.md +125 -0
- package/.codex/skills/cloudflare/references/workflows/configuration.md +177 -0
- package/.codex/skills/cloudflare/references/workflows/gotchas.md +136 -0
- package/.codex/skills/cloudflare/references/workflows/patterns.md +132 -0
- package/.codex/skills/cloudflare/references/wrangler/README.md +90 -0
- package/.codex/skills/cloudflare/references/wrangler/api.md +140 -0
- package/.codex/skills/cloudflare/references/wrangler/configuration.md +128 -0
- package/.codex/skills/cloudflare/references/wrangler/gotchas.md +93 -0
- package/.codex/skills/cloudflare/references/wrangler/patterns.md +150 -0
- package/.codex/skills/cloudflare/references/zaraz/README.md +360 -0
- package/.codex/skills/code-navigation/SKILL.md +130 -0
- package/.codex/skills/code-review/SKILL.md +208 -0
- package/.codex/skills/compaction/SKILL.md +317 -0
- package/.codex/skills/condition-based-waiting/SKILL.md +123 -0
- package/.codex/skills/condition-based-waiting/example.ts +158 -0
- package/.codex/skills/context-engineering/SKILL.md +176 -0
- package/.codex/skills/context-initialization/SKILL.md +70 -0
- package/.codex/skills/context-management/SKILL.md +163 -0
- package/.codex/skills/core-data-expert/SKILL.md +93 -0
- package/.codex/skills/core-data-expert/references/batch-operations.md +543 -0
- package/.codex/skills/core-data-expert/references/cloudkit-integration.md +259 -0
- package/.codex/skills/core-data-expert/references/concurrency.md +522 -0
- package/.codex/skills/core-data-expert/references/fetch-requests.md +643 -0
- package/.codex/skills/core-data-expert/references/glossary.md +233 -0
- package/.codex/skills/core-data-expert/references/migration.md +393 -0
- package/.codex/skills/core-data-expert/references/model-configuration.md +597 -0
- package/.codex/skills/core-data-expert/references/performance.md +300 -0
- package/.codex/skills/core-data-expert/references/persistent-history.md +553 -0
- package/.codex/skills/core-data-expert/references/project-audit.md +60 -0
- package/.codex/skills/core-data-expert/references/saving.md +574 -0
- package/.codex/skills/core-data-expert/references/stack-setup.md +625 -0
- package/.codex/skills/core-data-expert/references/testing.md +300 -0
- package/.codex/skills/core-data-expert/references/threading.md +589 -0
- package/.codex/skills/debugging/SKILL.md +203 -0
- package/.codex/skills/deep-research/SKILL.md +384 -0
- package/.codex/skills/defense-in-depth/SKILL.md +166 -0
- package/.codex/skills/dependency-upgrades/SKILL.md +198 -0
- package/.codex/skills/design-system-audit/SKILL.md +153 -0
- package/.codex/skills/development-lifecycle/SKILL.md +356 -0
- package/.codex/skills/dispatching-parallel-agents/SKILL.md +191 -0
- package/.codex/skills/docs-handoff/SKILL.md +175 -0
- package/.codex/skills/executing-plans/SKILL.md +247 -0
- package/.codex/skills/figma/SKILL.md +224 -0
- package/.codex/skills/figma/mcp.json +6 -0
- package/.codex/skills/finishing-a-development-branch/SKILL.md +357 -0
- package/.codex/skills/frontend-design/SKILL.md +176 -0
- package/.codex/skills/gemini-large-context/SKILL.md +216 -0
- package/.codex/skills/git-pr-prep/SKILL.md +179 -0
- package/.codex/skills/index-knowledge/SKILL.md +413 -0
- package/.codex/skills/jira/SKILL.md +283 -0
- package/.codex/skills/jira/mcp.json +6 -0
- package/.codex/skills/memory-system/SKILL.md +93 -0
- package/.codex/skills/mockup-to-code/SKILL.md +184 -0
- package/.codex/skills/mqdh/SKILL.md +171 -0
- package/.codex/skills/obsidian/SKILL.md +187 -0
- package/.codex/skills/obsidian/mcp.json +22 -0
- package/.codex/skills/opensrc/SKILL.md +127 -0
- package/.codex/skills/opensrc/references/architecture.md +176 -0
- package/.codex/skills/opensrc/references/cli-usage.md +176 -0
- package/.codex/skills/opensrc/references/registry-support.md +137 -0
- package/.codex/skills/pdf-extract/SKILL.md +438 -0
- package/.codex/skills/playwright/SKILL.md +320 -0
- package/.codex/skills/playwright/mcp.json +16 -0
- package/.codex/skills/playwriter/SKILL.md +158 -0
- package/.codex/skills/polar/SKILL.md +102 -0
- package/.codex/skills/prd/SKILL.md +146 -0
- package/.codex/skills/prd-task/SKILL.md +182 -0
- package/.codex/skills/prd-task/references/prd-schema.json +124 -0
- package/.codex/skills/prompt-leverage/SKILL.md +69 -0
- package/.codex/skills/prompt-leverage/agents/openai.yaml +4 -0
- package/.codex/skills/prompt-leverage/references/framework.md +91 -0
- package/.codex/skills/prompt-leverage/scripts/augment_prompt.py +114 -0
- package/.codex/skills/ralph/SKILL.md +296 -0
- package/.codex/skills/react-best-practices/AGENTS.md +2410 -0
- package/.codex/skills/react-best-practices/README.md +123 -0
- package/.codex/skills/react-best-practices/SKILL.md +133 -0
- package/.codex/skills/react-best-practices/metadata.json +15 -0
- package/.codex/skills/react-best-practices/rules/_sections.md +46 -0
- package/.codex/skills/react-best-practices/rules/_template.md +28 -0
- package/.codex/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.codex/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/.codex/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/.codex/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/.codex/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/.codex/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/.codex/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.codex/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/.codex/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/.codex/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.codex/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.codex/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/.codex/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/.codex/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/.codex/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/.codex/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.codex/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/.codex/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.codex/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.codex/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/.codex/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.codex/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/.codex/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.codex/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/.codex/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/.codex/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.codex/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.codex/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.codex/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/.codex/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.codex/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.codex/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.codex/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.codex/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.codex/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.codex/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.codex/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.codex/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.codex/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.codex/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.codex/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/.codex/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/.codex/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.codex/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/.codex/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/.codex/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/.codex/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/.codex/skills/receiving-code-review/SKILL.md +252 -0
- package/.codex/skills/refactoring/SKILL.md +217 -0
- package/.codex/skills/repo-orientation/SKILL.md +156 -0
- package/.codex/skills/requesting-code-review/SKILL.md +397 -0
- package/.codex/skills/resend/SKILL.md +177 -0
- package/.codex/skills/resend/references/react-email.md +287 -0
- package/.codex/skills/resend/references/receive-email.md +248 -0
- package/.codex/skills/resend/references/send-email.md +318 -0
- package/.codex/skills/root-cause-tracing/SKILL.md +192 -0
- package/.codex/skills/root-cause-tracing/find-polluter.sh +63 -0
- package/.codex/skills/safe-implementation/SKILL.md +205 -0
- package/.codex/skills/session-management/SKILL.md +10 -0
- package/.codex/skills/sharing-skills/SKILL.md +214 -0
- package/.codex/skills/skill-creator/SKILL.md +156 -0
- package/.codex/skills/source-code-research/SKILL.md +293 -0
- package/.codex/skills/source-code-research/references/analysis-tips.md +43 -0
- package/.codex/skills/source-code-research/references/anti-patterns.md +36 -0
- package/.codex/skills/source-code-research/references/common-patterns.md +57 -0
- package/.codex/skills/source-code-research/references/example-workflow.md +60 -0
- package/.codex/skills/source-code-research/references/further-reading.md +5 -0
- package/.codex/skills/source-code-research/references/source-structure.md +45 -0
- package/.codex/skills/stitch/SKILL.md +147 -0
- package/.codex/skills/stitch/mcp.json +9 -0
- package/.codex/skills/structured-edit/SKILL.md +181 -0
- package/.codex/skills/subagent-driven-development/SKILL.md +237 -0
- package/.codex/skills/supabase/SKILL.md +130 -0
- package/.codex/skills/supabase/mcp.json +27 -0
- package/.codex/skills/supabase-postgres-best-practices/AGENTS.md +1490 -0
- package/.codex/skills/supabase-postgres-best-practices/SKILL.md +65 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/advanced-full-text-search.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/advanced-jsonb-indexing.md +49 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-idle-timeout.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-limits.md +44 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-pooling.md +41 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-prepared-statements.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-batch-inserts.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-n-plus-one.md +53 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-pagination.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-upsert.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-advisory.md +56 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-deadlock-prevention.md +68 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-short-transactions.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-skip-locked.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-explain-analyze.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-pg-stat-statements.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-vacuum-analyze.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-composite-indexes.md +44 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-covering-indexes.md +40 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-index-types.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-missing-indexes.md +43 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-partial-indexes.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-data-types.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-foreign-key-indexes.md +59 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-lowercase-identifiers.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-partitioning.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-primary-keys.md +61 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-privileges.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-rls-basics.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-rls-performance.md +57 -0
- package/.codex/skills/swarm-coordination/SKILL.md +179 -0
- package/.codex/skills/swarm-coordination/references/architecture.md +39 -0
- package/.codex/skills/swarm-coordination/references/delegation-worker-protocol.md +145 -0
- package/.codex/skills/swarm-coordination/references/dependency-graph.md +50 -0
- package/.codex/skills/swarm-coordination/references/drift-check.md +90 -0
- package/.codex/skills/swarm-coordination/references/integration-beads.md +20 -0
- package/.codex/skills/swarm-coordination/references/launch-flow.md +186 -0
- package/.codex/skills/swarm-coordination/references/reconciler.md +172 -0
- package/.codex/skills/swarm-coordination/references/tier-enforcement.md +78 -0
- package/.codex/skills/swarm-coordination/references/tmux-integration.md +134 -0
- package/.codex/skills/swift-concurrency/SKILL.md +266 -0
- package/.codex/skills/swift-concurrency/references/actors.md +640 -0
- package/.codex/skills/swift-concurrency/references/async-algorithms.md +822 -0
- package/.codex/skills/swift-concurrency/references/async-await-basics.md +249 -0
- package/.codex/skills/swift-concurrency/references/async-sequences.md +670 -0
- package/.codex/skills/swift-concurrency/references/core-data.md +533 -0
- package/.codex/skills/swift-concurrency/references/glossary.md +128 -0
- package/.codex/skills/swift-concurrency/references/linting.md +142 -0
- package/.codex/skills/swift-concurrency/references/memory-management.md +542 -0
- package/.codex/skills/swift-concurrency/references/migration.md +1076 -0
- package/.codex/skills/swift-concurrency/references/performance.md +574 -0
- package/.codex/skills/swift-concurrency/references/sendable.md +578 -0
- package/.codex/skills/swift-concurrency/references/tasks.md +604 -0
- package/.codex/skills/swift-concurrency/references/testing.md +565 -0
- package/.codex/skills/swift-concurrency/references/threading.md +452 -0
- package/.codex/skills/swiftui-expert-skill/SKILL.md +329 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-advanced.md +351 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/.codex/skills/swiftui-expert-skill/references/image-optimization.md +286 -0
- package/.codex/skills/swiftui-expert-skill/references/layout-best-practices.md +312 -0
- package/.codex/skills/swiftui-expert-skill/references/liquid-glass.md +377 -0
- package/.codex/skills/swiftui-expert-skill/references/list-patterns.md +153 -0
- package/.codex/skills/swiftui-expert-skill/references/modern-apis.md +400 -0
- package/.codex/skills/swiftui-expert-skill/references/performance-patterns.md +377 -0
- package/.codex/skills/swiftui-expert-skill/references/scroll-patterns.md +305 -0
- package/.codex/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +292 -0
- package/.codex/skills/swiftui-expert-skill/references/state-management.md +447 -0
- package/.codex/skills/swiftui-expert-skill/references/text-formatting.md +285 -0
- package/.codex/skills/swiftui-expert-skill/references/view-structure.md +276 -0
- package/.codex/skills/systematic-debugging/SKILL.md +402 -0
- package/.codex/skills/task-planning/SKILL.md +205 -0
- package/.codex/skills/test-driven-development/SKILL.md +388 -0
- package/.codex/skills/test-strategy/SKILL.md +186 -0
- package/.codex/skills/testing-anti-patterns/SKILL.md +320 -0
- package/.codex/skills/testing-skills-with-subagents/SKILL.md +405 -0
- package/.codex/skills/tilth-cli/SKILL.md +180 -0
- package/.codex/skills/tool-priority/SKILL.md +299 -0
- package/.codex/skills/ui-inspiration-scout/SKILL.md +203 -0
- package/.codex/skills/ui-ux-research/SKILL.md +35 -0
- package/.codex/skills/using-git-worktrees/SKILL.md +259 -0
- package/.codex/skills/using-skills/SKILL.md +117 -0
- package/.codex/skills/v0/SKILL.md +158 -0
- package/.codex/skills/v0/mcp.json +6 -0
- package/.codex/skills/v1-run/SKILL.md +175 -0
- package/.codex/skills/v1-run/mcp.json +6 -0
- package/.codex/skills/vercel-deploy-claimable/SKILL.md +124 -0
- package/.codex/skills/vercel-deploy-claimable/scripts/deploy.sh +249 -0
- package/.codex/skills/verification/SKILL.md +191 -0
- package/.codex/skills/verification-before-completion/SKILL.md +236 -0
- package/.codex/skills/visual-analysis/SKILL.md +154 -0
- package/.codex/skills/web-design-guidelines/SKILL.md +46 -0
- package/.codex/skills/writing-plans/SKILL.md +320 -0
- package/.codex/skills/writing-skills/SKILL.md +287 -0
- package/.codex/skills/writing-skills/anthropic-best-practices.md +1173 -0
- package/.codex/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/.codex/skills/writing-skills/persuasion-principles.md +220 -0
- package/.codex/skills/writing-skills/references/anti-patterns.md +25 -0
- package/.codex/skills/writing-skills/references/claude-search-optimization.md +140 -0
- package/.codex/skills/writing-skills/references/discovery-workflow.md +11 -0
- package/.codex/skills/writing-skills/references/file-organization.md +32 -0
- package/.codex/skills/writing-skills/references/flowcharts-and-examples.md +57 -0
- package/.codex/skills/writing-skills/references/rationalization-hardening.md +75 -0
- package/.codex/skills/writing-skills/references/testing-skill-types.md +52 -0
- package/.template-manifest.json +631 -0
- package/AGENTS.md +719 -0
- package/AGENTS.override.md.example +7 -0
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +641 -0
- package/bin/codexkit +148 -0
- package/install/bead-close.sh +20 -0
- package/install/bead-search.sh +18 -0
- package/install/bead-start.sh +20 -0
- package/install/bead-sync.sh +19 -0
- package/install/bead-verify.sh +20 -0
- package/install/generate-manifest.sh +55 -0
- package/install/install-global.sh +150 -0
- package/install/install-project.sh +704 -0
- package/install/install-remote.sh +152 -0
- package/install/patch.sh +478 -0
- package/install/plugin.sh +565 -0
- package/install/run-codex.sh +68 -0
- package/install/template.sh +620 -0
- package/install/validate.sh +653 -0
- package/package.json +39 -0
- package/templates/global/.codex-config-template.toml +87 -0
- package/templates/global/AGENTS.override.md +18 -0
- package/templates/global/README.md +29 -0
- package/templates/project/.codex-config-template.toml +26 -0
- package/templates/project/AGENTS.md.template +27 -0
- package/templates/project/README.md +24 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
# Model Configuration
|
|
2
|
+
|
|
3
|
+
Core Data's data model offers powerful configuration options beyond basic attributes and relationships. This guide covers constraints, derived attributes, transformables, validation, and lifecycle events.
|
|
4
|
+
|
|
5
|
+
## Constraints
|
|
6
|
+
|
|
7
|
+
Constraints ensure uniqueness of attribute values. When combined with the correct merge policy, Core Data automatically handles duplicates.
|
|
8
|
+
|
|
9
|
+
### Setting Up Constraints
|
|
10
|
+
|
|
11
|
+
In Xcode's Data Model Editor:
|
|
12
|
+
1. Select your entity
|
|
13
|
+
2. In the Data Model Inspector, find "Constraints"
|
|
14
|
+
3. Click "+" and add attribute names
|
|
15
|
+
|
|
16
|
+
**Example:** Make `name` unique in the `Category` entity.
|
|
17
|
+
|
|
18
|
+
### Required Merge Policy
|
|
19
|
+
|
|
20
|
+
```swift
|
|
21
|
+
viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Without this merge policy, constraint violations will crash your app.**
|
|
25
|
+
|
|
26
|
+
### How Constraints Work
|
|
27
|
+
|
|
28
|
+
```swift
|
|
29
|
+
// First save
|
|
30
|
+
let category1 = Category(context: context)
|
|
31
|
+
category1.name = "Swift"
|
|
32
|
+
try context.save() // Saves successfully
|
|
33
|
+
|
|
34
|
+
// Duplicate attempt
|
|
35
|
+
let category2 = Category(context: context)
|
|
36
|
+
category2.name = "Swift" // Same name
|
|
37
|
+
try context.save() // With correct merge policy: keeps first, discards second
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Multiple Constraints
|
|
41
|
+
|
|
42
|
+
```swift
|
|
43
|
+
// Constraints on multiple attributes
|
|
44
|
+
// In model: constraints = ["email", "username"]
|
|
45
|
+
|
|
46
|
+
// Both must be unique
|
|
47
|
+
user1.email = "test@example.com"
|
|
48
|
+
user1.username = "testuser"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Compound Constraints
|
|
52
|
+
|
|
53
|
+
```swift
|
|
54
|
+
// Unique combination of attributes
|
|
55
|
+
// In model: constraints = ["firstName,lastName"]
|
|
56
|
+
|
|
57
|
+
// These are different (unique combinations)
|
|
58
|
+
person1.firstName = "John"
|
|
59
|
+
person1.lastName = "Doe"
|
|
60
|
+
|
|
61
|
+
person2.firstName = "John"
|
|
62
|
+
person2.lastName = "Smith" // Different combination, allowed
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Derived Attributes
|
|
66
|
+
|
|
67
|
+
Derived attributes are computed from other attributes or relationships and stored in the database. They're calculated on save or refresh.
|
|
68
|
+
|
|
69
|
+
### Benefits
|
|
70
|
+
|
|
71
|
+
- No need to manually update computed values
|
|
72
|
+
- Better performance than accessing relationships
|
|
73
|
+
- Optimized for queries
|
|
74
|
+
|
|
75
|
+
### Common Derivations
|
|
76
|
+
|
|
77
|
+
#### 1. Count of Relationships
|
|
78
|
+
|
|
79
|
+
```swift
|
|
80
|
+
// In Data Model Editor:
|
|
81
|
+
// Derived attribute: articlesCount
|
|
82
|
+
// Derivation: articles.@count
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Why this is better than `articles.count`:**
|
|
86
|
+
- Doesn't fire faults
|
|
87
|
+
- Faster queries
|
|
88
|
+
- Always up-to-date after save
|
|
89
|
+
|
|
90
|
+
#### 2. Related Object Property
|
|
91
|
+
|
|
92
|
+
```swift
|
|
93
|
+
// Derived attribute: categoryName
|
|
94
|
+
// Derivation: category.name
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Use case:** Avoid firing faults when displaying list views.
|
|
98
|
+
|
|
99
|
+
#### 3. Current Timestamp
|
|
100
|
+
|
|
101
|
+
```swift
|
|
102
|
+
// Derived attribute: lastModified
|
|
103
|
+
// Derivation: now()
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Automatically updates on every save.**
|
|
107
|
+
|
|
108
|
+
#### 4. Canonical String (Search Optimization)
|
|
109
|
+
|
|
110
|
+
```swift
|
|
111
|
+
// Derived attribute: searchName
|
|
112
|
+
// Derivation: canonical:(name)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**What it does:**
|
|
116
|
+
- Converts to lowercase
|
|
117
|
+
- Removes diacritics
|
|
118
|
+
- Perfect for case-insensitive, diacritic-insensitive searches
|
|
119
|
+
|
|
120
|
+
**Example:**
|
|
121
|
+
```swift
|
|
122
|
+
// name = "Café"
|
|
123
|
+
// searchName = "cafe"
|
|
124
|
+
|
|
125
|
+
// Search query
|
|
126
|
+
fetchRequest.predicate = NSPredicate(format: "searchName CONTAINS %@", "cafe")
|
|
127
|
+
// Matches "Café", "CAFE", "café", etc.
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### 5. Sum of Related Values
|
|
131
|
+
|
|
132
|
+
```swift
|
|
133
|
+
// Derived attribute: totalViews
|
|
134
|
+
// Derivation: @sum.articles.views
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Important Notes
|
|
138
|
+
|
|
139
|
+
- Derived attributes are calculated **on save** or **refresh**
|
|
140
|
+
- In-memory changes don't update derived attributes until saved
|
|
141
|
+
- Can't be set manually (they're computed)
|
|
142
|
+
|
|
143
|
+
### Example Usage
|
|
144
|
+
|
|
145
|
+
```swift
|
|
146
|
+
class Article: NSManagedObject {
|
|
147
|
+
@NSManaged var name: String
|
|
148
|
+
@NSManaged var category: Category?
|
|
149
|
+
|
|
150
|
+
// Derived from category.name
|
|
151
|
+
@NSManaged var categoryName: String?
|
|
152
|
+
|
|
153
|
+
// Derived from canonical:(name)
|
|
154
|
+
@NSManaged var searchName: String?
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Usage
|
|
158
|
+
article.name = "Core Data Best Practices"
|
|
159
|
+
try context.save()
|
|
160
|
+
|
|
161
|
+
// After save, derived attributes are updated
|
|
162
|
+
print(article.searchName) // "core data best practices"
|
|
163
|
+
print(article.categoryName) // "Swift"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Transformables
|
|
167
|
+
|
|
168
|
+
Transformables allow storing custom types that aren't natively supported by Core Data.
|
|
169
|
+
|
|
170
|
+
### Creating a Value Transformer
|
|
171
|
+
|
|
172
|
+
```swift
|
|
173
|
+
import UIKit
|
|
174
|
+
|
|
175
|
+
@objc(ColorTransformer)
|
|
176
|
+
class ColorTransformer: ValueTransformer {
|
|
177
|
+
override class func transformedValueClass() -> AnyClass {
|
|
178
|
+
return NSData.self
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
override class func allowsReverseTransformation() -> Bool {
|
|
182
|
+
return true
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
override func transformedValue(_ value: Any?) -> Any? {
|
|
186
|
+
guard let color = value as? UIColor else { return nil }
|
|
187
|
+
|
|
188
|
+
do {
|
|
189
|
+
let data = try NSKeyedArchiver.archivedData(
|
|
190
|
+
withRootObject: color,
|
|
191
|
+
requiringSecureCoding: true
|
|
192
|
+
)
|
|
193
|
+
return data
|
|
194
|
+
} catch {
|
|
195
|
+
print("Failed to transform color: \(error)")
|
|
196
|
+
return nil
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
override func reverseTransformedValue(_ value: Any?) -> Any? {
|
|
201
|
+
guard let data = value as? Data else { return nil }
|
|
202
|
+
|
|
203
|
+
do {
|
|
204
|
+
let color = try NSKeyedUnarchiver.unarchivedObject(
|
|
205
|
+
ofClass: UIColor.self,
|
|
206
|
+
from: data
|
|
207
|
+
)
|
|
208
|
+
return color
|
|
209
|
+
} catch {
|
|
210
|
+
print("Failed to reverse transform color: \(error)")
|
|
211
|
+
return nil
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Registering the Transformer
|
|
218
|
+
|
|
219
|
+
```swift
|
|
220
|
+
// In your stack setup, before loading stores
|
|
221
|
+
ValueTransformer.setValueTransformer(
|
|
222
|
+
ColorTransformer(),
|
|
223
|
+
forName: NSValueTransformerName("ColorTransformer")
|
|
224
|
+
)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Configuring in Data Model
|
|
228
|
+
|
|
229
|
+
1. Select the attribute
|
|
230
|
+
2. Set Type to "Transformable"
|
|
231
|
+
3. Set "Custom Class" to your type (e.g., `UIColor`)
|
|
232
|
+
4. Set "Transformer" to your transformer name (e.g., `ColorTransformer`)
|
|
233
|
+
|
|
234
|
+
### Using Transformable Attributes
|
|
235
|
+
|
|
236
|
+
```swift
|
|
237
|
+
class Article: NSManagedObject {
|
|
238
|
+
@NSManaged var color: UIColor?
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Usage
|
|
242
|
+
article.color = .systemBlue
|
|
243
|
+
try context.save()
|
|
244
|
+
|
|
245
|
+
// Retrieval
|
|
246
|
+
let color = article.color // UIColor
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### NSSecureCoding Requirement
|
|
250
|
+
|
|
251
|
+
Modern Core Data requires secure coding:
|
|
252
|
+
|
|
253
|
+
```swift
|
|
254
|
+
// Make your custom type conform to NSSecureCoding
|
|
255
|
+
extension CustomType: NSSecureCoding {
|
|
256
|
+
static var supportsSecureCoding: Bool { return true }
|
|
257
|
+
|
|
258
|
+
func encode(with coder: NSCoder) {
|
|
259
|
+
// Encode properties
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
required init?(coder: NSCoder) {
|
|
263
|
+
// Decode properties
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Validation
|
|
269
|
+
|
|
270
|
+
Core Data provides built-in validation that runs before saving.
|
|
271
|
+
|
|
272
|
+
### Model-Level Validation
|
|
273
|
+
|
|
274
|
+
Set in Data Model Editor:
|
|
275
|
+
|
|
276
|
+
**String Validation:**
|
|
277
|
+
- Minimum Length
|
|
278
|
+
- Maximum Length
|
|
279
|
+
- Regular Expression
|
|
280
|
+
|
|
281
|
+
**Numeric Validation:**
|
|
282
|
+
- Minimum Value
|
|
283
|
+
- Maximum Value
|
|
284
|
+
|
|
285
|
+
**Example:**
|
|
286
|
+
```
|
|
287
|
+
Attribute: name
|
|
288
|
+
Type: String
|
|
289
|
+
Min Length: 3
|
|
290
|
+
Max Length: 100
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Code-Level Validation
|
|
294
|
+
|
|
295
|
+
Override validation methods in your `NSManagedObject` subclass:
|
|
296
|
+
|
|
297
|
+
```swift
|
|
298
|
+
class Article: NSManagedObject {
|
|
299
|
+
@NSManaged var name: String?
|
|
300
|
+
|
|
301
|
+
// Validate before insert
|
|
302
|
+
override func validateForInsert() throws {
|
|
303
|
+
try super.validateForInsert()
|
|
304
|
+
try validateName()
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Validate before update
|
|
308
|
+
override func validateForUpdate() throws {
|
|
309
|
+
try super.validateForUpdate()
|
|
310
|
+
try validateName()
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Validate before delete
|
|
314
|
+
override func validateForDelete() throws {
|
|
315
|
+
try super.validateForDelete()
|
|
316
|
+
|
|
317
|
+
// Example: Can't delete if has related objects
|
|
318
|
+
if let attachments = attachments, !attachments.isEmpty {
|
|
319
|
+
throw NSError(
|
|
320
|
+
domain: "ArticleValidation",
|
|
321
|
+
code: 1001,
|
|
322
|
+
userInfo: [NSLocalizedDescriptionKey: "Cannot delete article with attachments"]
|
|
323
|
+
)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Custom validation
|
|
328
|
+
private func validateName() throws {
|
|
329
|
+
guard let name = name, !name.isEmpty else {
|
|
330
|
+
throw NSError(
|
|
331
|
+
domain: "ArticleValidation",
|
|
332
|
+
code: 1000,
|
|
333
|
+
userInfo: [NSLocalizedDescriptionKey: "Name cannot be empty"]
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Check for protected names
|
|
338
|
+
let protectedNames = ["Admin", "System", "Root"]
|
|
339
|
+
if protectedNames.contains(name) {
|
|
340
|
+
throw NSError(
|
|
341
|
+
domain: "ArticleValidation",
|
|
342
|
+
code: 1002,
|
|
343
|
+
userInfo: [NSLocalizedDescriptionKey: "'\(name)' is a protected name"]
|
|
344
|
+
)
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Property-Level Validation
|
|
351
|
+
|
|
352
|
+
```swift
|
|
353
|
+
class Article: NSManagedObject {
|
|
354
|
+
@NSManaged var name: String?
|
|
355
|
+
|
|
356
|
+
override func validateName(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>) throws {
|
|
357
|
+
guard let name = value.pointee as? String, !name.isEmpty else {
|
|
358
|
+
throw NSError(
|
|
359
|
+
domain: "ArticleValidation",
|
|
360
|
+
code: 1000,
|
|
361
|
+
userInfo: [NSLocalizedDescriptionKey: "Name cannot be empty"]
|
|
362
|
+
)
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Handling Validation Errors
|
|
369
|
+
|
|
370
|
+
```swift
|
|
371
|
+
do {
|
|
372
|
+
try context.save()
|
|
373
|
+
} catch let error as NSError {
|
|
374
|
+
if error.domain == NSCocoaErrorDomain {
|
|
375
|
+
switch error.code {
|
|
376
|
+
case NSValidationStringTooShortError:
|
|
377
|
+
print("String too short")
|
|
378
|
+
case NSValidationStringTooLongError:
|
|
379
|
+
print("String too long")
|
|
380
|
+
case NSManagedObjectValidationError:
|
|
381
|
+
print("Validation failed")
|
|
382
|
+
default:
|
|
383
|
+
print("Other error: \(error.localizedDescription)")
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Lifecycle Events
|
|
390
|
+
|
|
391
|
+
Override lifecycle methods to perform actions at specific points in an object's life.
|
|
392
|
+
|
|
393
|
+
### awakeFromInsert()
|
|
394
|
+
|
|
395
|
+
Called once when object is first inserted into context.
|
|
396
|
+
|
|
397
|
+
```swift
|
|
398
|
+
override func awakeFromInsert() {
|
|
399
|
+
super.awakeFromInsert()
|
|
400
|
+
|
|
401
|
+
// Set default values
|
|
402
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.creationDate))
|
|
403
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.lastModified))
|
|
404
|
+
setPrimitiveValue(0, forKey: #keyPath(Article.views))
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**Use `setPrimitiveValue` to avoid:**
|
|
409
|
+
- KVO notifications
|
|
410
|
+
- Marking object as changed
|
|
411
|
+
- Infinite loops
|
|
412
|
+
|
|
413
|
+
### willSave()
|
|
414
|
+
|
|
415
|
+
Called before every save. Use for updating modification dates or cleaning up.
|
|
416
|
+
|
|
417
|
+
```swift
|
|
418
|
+
override func willSave() {
|
|
419
|
+
super.willSave()
|
|
420
|
+
|
|
421
|
+
// Update modification date
|
|
422
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.lastModified))
|
|
423
|
+
|
|
424
|
+
// Delete local files if object is deleted
|
|
425
|
+
if isDeleted, let localResource = localResourceURL {
|
|
426
|
+
try? FileManager.default.removeItem(at: localResource)
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Caution:** Don't call `save()` inside `willSave()` - infinite loop!
|
|
432
|
+
|
|
433
|
+
### didSave()
|
|
434
|
+
|
|
435
|
+
Called after save completes.
|
|
436
|
+
|
|
437
|
+
```swift
|
|
438
|
+
override func didSave() {
|
|
439
|
+
super.didSave()
|
|
440
|
+
|
|
441
|
+
// Post notification, update cache, etc.
|
|
442
|
+
NotificationCenter.default.post(
|
|
443
|
+
name: .articleDidSave,
|
|
444
|
+
object: self
|
|
445
|
+
)
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### prepareForDeletion()
|
|
450
|
+
|
|
451
|
+
Called when object is marked for deletion (before save).
|
|
452
|
+
|
|
453
|
+
```swift
|
|
454
|
+
override func prepareForDeletion() {
|
|
455
|
+
super.prepareForDeletion()
|
|
456
|
+
|
|
457
|
+
// Cancel ongoing operations
|
|
458
|
+
downloadTask?.cancel()
|
|
459
|
+
|
|
460
|
+
// Don't delete files here! Use willSave() instead
|
|
461
|
+
// (prepareForDeletion is called even if save is rolled back)
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Important:** Don't delete files in `prepareForDeletion()`. The deletion might be rolled back, leaving your data inconsistent.
|
|
466
|
+
|
|
467
|
+
### awakeFromFetch()
|
|
468
|
+
|
|
469
|
+
Called when object is fetched from store.
|
|
470
|
+
|
|
471
|
+
```swift
|
|
472
|
+
override func awakeFromFetch() {
|
|
473
|
+
super.awakeFromFetch()
|
|
474
|
+
|
|
475
|
+
// Initialize transient properties
|
|
476
|
+
setupObservers()
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Complete Lifecycle Example
|
|
481
|
+
|
|
482
|
+
```swift
|
|
483
|
+
class Article: NSManagedObject {
|
|
484
|
+
@NSManaged var name: String?
|
|
485
|
+
@NSManaged var creationDate: Date?
|
|
486
|
+
@NSManaged var lastModified: Date?
|
|
487
|
+
@NSManaged var localResourceURL: URL?
|
|
488
|
+
|
|
489
|
+
override func awakeFromInsert() {
|
|
490
|
+
super.awakeFromInsert()
|
|
491
|
+
|
|
492
|
+
// Set creation date once
|
|
493
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.creationDate))
|
|
494
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.lastModified))
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
override func willSave() {
|
|
498
|
+
super.willSave()
|
|
499
|
+
|
|
500
|
+
// Update modification date on every save
|
|
501
|
+
if !isDeleted && changedValues().keys.contains("name") {
|
|
502
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.lastModified))
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Clean up files when deleted
|
|
506
|
+
if isDeleted, let url = localResourceURL {
|
|
507
|
+
try? FileManager.default.removeItem(at: url)
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
override func prepareForDeletion() {
|
|
512
|
+
super.prepareForDeletion()
|
|
513
|
+
|
|
514
|
+
// Cancel ongoing operations
|
|
515
|
+
// Don't delete files here!
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
## Common Pitfalls
|
|
521
|
+
|
|
522
|
+
### ❌ Not Setting Merge Policy with Constraints
|
|
523
|
+
|
|
524
|
+
```swift
|
|
525
|
+
// Constraint violation will crash
|
|
526
|
+
let category = Category(context: context)
|
|
527
|
+
category.name = "Duplicate"
|
|
528
|
+
try context.save() // CRASH!
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### ❌ Manually Setting Derived Attributes
|
|
532
|
+
|
|
533
|
+
```swift
|
|
534
|
+
// Derived attributes are read-only
|
|
535
|
+
article.categoryName = "Swift" // Ignored!
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### ❌ Using KVO Methods in Lifecycle Events
|
|
539
|
+
|
|
540
|
+
```swift
|
|
541
|
+
override func awakeFromInsert() {
|
|
542
|
+
super.awakeFromInsert()
|
|
543
|
+
|
|
544
|
+
// ❌ Triggers KVO, marks as changed
|
|
545
|
+
self.creationDate = Date()
|
|
546
|
+
|
|
547
|
+
// ✅ Use primitive values
|
|
548
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.creationDate))
|
|
549
|
+
}
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### ❌ Deleting Files in prepareForDeletion
|
|
553
|
+
|
|
554
|
+
```swift
|
|
555
|
+
override func prepareForDeletion() {
|
|
556
|
+
super.prepareForDeletion()
|
|
557
|
+
|
|
558
|
+
// ❌ Bad: Deletion might be rolled back
|
|
559
|
+
try? FileManager.default.removeItem(at: fileURL)
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### ✅ Correct Approaches
|
|
564
|
+
|
|
565
|
+
```swift
|
|
566
|
+
// Set merge policy
|
|
567
|
+
viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
|
|
568
|
+
|
|
569
|
+
// Let derived attributes compute themselves
|
|
570
|
+
article.name = "New Name"
|
|
571
|
+
try context.save()
|
|
572
|
+
print(article.searchName) // Automatically updated
|
|
573
|
+
|
|
574
|
+
// Use primitive values in lifecycle events
|
|
575
|
+
setPrimitiveValue(Date(), forKey: #keyPath(Article.creationDate))
|
|
576
|
+
|
|
577
|
+
// Delete files in willSave when isDeleted
|
|
578
|
+
override func willSave() {
|
|
579
|
+
super.willSave()
|
|
580
|
+
if isDeleted {
|
|
581
|
+
try? FileManager.default.removeItem(at: fileURL)
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
## Summary
|
|
587
|
+
|
|
588
|
+
1. **Use constraints for uniqueness** - Requires NSMergeByPropertyStoreTrumpMergePolicy
|
|
589
|
+
2. **Use derived attributes** - Better performance than accessing relationships
|
|
590
|
+
3. **Use canonical: for search** - Case and diacritic insensitive
|
|
591
|
+
4. **Use transformables for custom types** - With NSSecureCoding
|
|
592
|
+
5. **Validate in code** - For complex business rules
|
|
593
|
+
6. **Use awakeFromInsert for defaults** - Called once on creation
|
|
594
|
+
7. **Use willSave for updates** - Called before every save
|
|
595
|
+
8. **Use setPrimitiveValue** - Avoid KVO in lifecycle events
|
|
596
|
+
9. **Delete files in willSave** - When isDeleted is true
|
|
597
|
+
10. **Don't save in willSave** - Causes infinite loop
|